Post

Serializing derived classes using System.Text.Json.JsonSerializer

Overview

By default, ASP.NET Core uses a new JSON serializer: System.Text.Json.JsonSerializer. This has slightly different behaviour to Newtonsoft’s Json.NET when serializing derived types.

Example Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Program
{
    public class BaseClass
    {
        public string BaseClassProperty { get; set; }
    }

    public class DerivedClass : BaseClass
    {
        public string DerivedClassProperty { get; set; }
    }

    public static void Main(string[] args)
    {
        BaseClass toSerialize = new DerivedClass()
            {
                BaseClassProperty = "One",
                DerivedClassProperty = "Two"
            };
        var serialized = JsonSerializer.Serialize(toSerialize);
        
        Console.WriteLine(serialized);
    }
}

This will output { "baseClassProperty": "One" }; note the absence of the derivedClassProperty field. Using Newtonsoft’s Json.NET library to serialize the same object will include both properties.

Workaround

To work around it, you can make a polymorphic JsonConverter. Sample code for this is in a reply to the GitHub issue, located here.

I added an extra check to handle serializing null values, turning the class into:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class PolymorphicJsonConverter<T> : JsonConverter<T>
{
    public override T
        Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
    
    public override void
        Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        JsonSerializer.Serialize(writer, value, value?.GetType() ?? typeof(T), options);
    }
}
This post is licensed under CC BY 4.0 by the author.