.netserializationorleans

Orleans Private Property Deserialization


I have an orleans project with a stateful grain.

Orleans seems to not deserialize private properties when hydrating the state for the grain.

In the image below UserId gets deserialized but not State.

Is there a way to get around this?

enter image description here


Solution

  • You can override the default GrainStorageSerializer to use System.Text.Json which allows properties with private setters to be deserialized when you apply the JsonInclude attribute to the property as shown below.

    public class Order
    {
        [JsonInclude]
        public OrderStates State{ get; private set; }
    }
    

    You can then do the follow setup when configuring your environment. Implement a version of IGrainStorageSerializer that uses System.Text.Json. In this case below I created SystemTextJsonSerializer which implements the interface.

    public class SystemTextJsonSerializer : IGrainStorageSerializer
    {
        public BinaryData Serialize<T>(T input)
        {
            return new BinaryData(JsonSerializer.SerializeToUtf8Bytes(input));
        }
    
        public T Deserialize<T>(BinaryData input)
        {
            return input.ToObjectFromJson<T>();
        }
    }
    

    You can then configure your GrainStorageSerializer as below.

    siloBuilder.Services.AddSerializer(serializerBuilder =>
        {
            serializerBuilder.AddJsonSerializer(isSupported: type => type.Namespace.StartsWith("Example.Domain"));
        });
            
    .AddAzureTableGrainStorage(
        name: "OrleansProvider",
        configureOptions: options =>
        {
            options.GrainStorageSerializer = new SystemTextJsonSerializer();
            options.ConfigureTableServiceClient("...");
        });