Wednesday, February 22, 2023

System.Text.Json: Configure Polymorphism using the Contract Model

In this post let's see how we can configure Polymorphism using the Contract Model in System.Text.Json. You can also configure Polymorphism using attributes (How to configure Polymorphism using attributes), but there can be scenarios it isn't possible to use attributes. 

In that case, you can achieve Polymorphism using the Contract Model and this is only available with .NET 7 onwards.

Consider the following classes.
public class Person
{
    public string Name { getset; }
}

public class Student : Person
{
    public int StudentId { getset; }
}

public class Employee : Person
{
    public int EmployeeId { getset; }
}
Now instead of using attributes, I can update the JsonSerializerOptions, by calling the DefaultJsonTypeInfoResolver() constructor to obtain the JsonSerializerOptions.TypeInfoResolver and adding custom actions to its Modifiers property to configure Polymorphism.
var jsonSerializerOptions = new JsonSerializerOptions
{
    WriteIndented = true,
    PropertyNameCaseInsensitive = true,
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers =
        {
            static jsonTypeInfo =>
            {
                if (jsonTypeInfo.Type != typeof(Person))
                {
                    return;
                }

                jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions
                {
                    TypeDiscriminatorPropertyName = "type",
                    IgnoreUnrecognizedTypeDiscriminators = true,
                    UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FailSerialization,
                    DerivedTypes =
                    {
                        new JsonDerivedType(typeof(Student), "Student"),
                        new JsonDerivedType(typeof(Employee), "Employee"),
                    }
                };
            }
        }
    }
};
And now I can above JsonSerializerOptions to Serialize/Deserialize as follows.
Person student = new Student
{
    Name = "John Doe",
    StudentId = 1
};

// Serializing
string jsonString = JsonSerializer.Serialize(student, jsonSerializerOptions);
Console.WriteLine(jsonString);
//{
//  "type": "Student",
//  "studentId": 1,
//  "name": "John Doe"
//}

// Deserializing
Person parsedPerson = JsonSerializer.Deserialize<Person>(jsonString, jsonSerializerOptions);
Console.WriteLine(parsedPerson is Student);  //true
Hope this helps.

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment