System.TypeAccessException: Named type "CustomGrainState" is invalid: Type string "CustomGrainState" cannot be resolved.

Sometimes Orleans throws the following exception when it fails to serialize a custom object:

System.TypeAccessException: Named type "Simple.GrainImplementation.CustomGrainState" is invalid: Type string "Simple.GrainImplementation.CustomGrainState" cannot be resolved. at Orleans.Serialization.BinaryTokenStreamReader.ReadSpecifiedTypeHeader() at Orleans.Serialization.SerializationManager.DeserializeInner(Type expected, BinaryTokenStreamReader stream) at Orleans.Serialization.BuiltInTypes.DeserializeOrleansResponse(Type expected, BinaryTokenStreamReader stream) at Orleans.Serialization.SerializationManager.DeserializeInner(Type expected, BinaryTokenStreamReader stream) at Orleans.Serialization.SerializationManager.Deserialize(Type t, BinaryTokenStreamReader stream) at Orleans.Serialization.SerializationManager.Deserialize(BinaryTokenStreamReader stream) at Orleans.Runtime.Message.DeserializeBody(List`1 bytes) at Orleans.Runtime.Message.get_BodyObject() at Orleans.Runtime.GrainReference.ResponseCallback(Message message, TaskCompletionSource`1 context) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at Orleans.Runtime.GrainReference.d__42`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at Simple.Web.Hubs.NotificationHub.d__4.MoveNext() in C:\Projects\Simple\Simple.Web\Hubs\NotificationHub.cs:line 40

The reason behind this error is: the Orleans client cannot locate the typed object that is being used inside the code. In my case, I had a project structure similar to below:


Here, I am using a custom grain state (CustomGrainState) for the DataProcessingGrain. Note that:
  • DataProcessingGrain inherits from IDataProcessingGrain.
  • CustomGrainState inherits from ICustomGrainState and contains few more methods on top of the properties of the base interface.
  • IDataProcessingGrain has a method named 'GetCurrentState()' that returns the current grain state (ICustomGrainState).
 Now, I've another web project that uses Orleans client to get the current state of DataProcessingGrain. This client project includes the following references:
  • Simple.GrainInterface - as it invokes the GetCurrentState() method from IDataProcessingGrain.
  • OrleansCodeGenerator - this is needed for Orleans client to generate the grain logic.

At this stage, the client project threw the above exception at runtime as it cannot locate CustomGrainState type.

Even if the grain implementation project doesn't require to be added as a reference to this (client) project for the actual grain logic, but for the serializable custom state we must add Simple.GrainImplementation project reference to the Simple.Web project.

So adding reference to the dll containing the custom state eliminated the exception in this case.

Comments

Popular posts from this blog

Adding security headers to prevent XSS and MiTM attacks in .Net Core

Creating transformations for custom config files

Microsoft.IdentityModel.Protocols.OpenIdConnectProtocolInvalidNonceException