Home > Back-end >  How can I emulate deserialization "callbacks" in System.Text.Json?
How can I emulate deserialization "callbacks" in System.Text.Json?

Time:01-31

I am attempting to have my object execute some logic immediately after deserialization. I am using the example shown on the following Microsoft documentation

The issue that I'm running into is that calling JsonSerializer.Deserialize() results in an infinite recursion loop because Deserialize() is called in the Read override. I know that I can get around this by implementing my own deserialize method - but that defeats the purpose of using this override, so I'm assuming that there's gotta be some way to keep the Deserialize() call in the Read override.

My deserialization test

    public void TestSerializationConverterCallbacks()
    {
        Animal a = JsonSerializer.Deserialize<Animal>(SerializedData.SerializedAnimal);
    }

My serialized object

    [JsonConverter(typeof(AnimalCallbacksConverter))]
    public class Animal
    {
        public string Name { get; set; } = "dog";
        
        public string Id { get; set; } = "123";
    }

My custom Serializer

    public class AnimalCallbacksConverter : JsonConverter<Animal>
    {
        public override Animal Read(
            ref Utf8JsonReader reader,
            Type type,
            JsonSerializerOptions options)
        {
            // Place "before" code here (OnDeserializing),
            // but note that there is no access here to the POCO instance.
            Console.WriteLine("OnDeserializing");

            // Don't pass in options when recursively calling Deserialize.
            Animal animal = JsonSerializer.Deserialize<Animal>(ref reader);

            // Place "after" code here (OnDeserialized)
            Console.WriteLine("OnDeserialized");

            return animal;
        }

        public override void Write(
            Utf8JsonWriter writer,
            Animal animal, JsonSerializerOptions options)
        {
            // Place "before" code here (OnSerializing)
            Console.WriteLine("OnSerializing");

            // Don't pass in options when recursively calling Serialize.
            JsonSerializer.Serialize(writer, animal);

            // Place "after" code here (OnSerialized)
            Console.WriteLine("OnSerialized");
        }
    }

CodePudding user response:

You can use actual deserialization callbacks...

public class MyObject : IJsonOnDeserialized
{
    public MyProperty1 { get; set; }
    public MyProperty2 { get; set; }

    void IJsonOnDeserialized.OnDeserialized()
    {
        //Code runs after deserialization is complete
    }
}

System.Text.Json has an example of this about 2/3rds the way down the page. Newtonsoft.Json doesn't have the limitations that System.Text.Json has, and can use [OnDeserializing] and [OnDeserialized] attributes that take a streaming context.

  • Related