With .NET 8, working with polymorphic JSON serialization and deserialization is easier and more effective. Earlier versions of System.Text.Json had issues handling polymorphism, but .NET 8 now offers built-in support that eliminates the need for workarounds or additional libraries.

Polymorphic Serialization

Polymorphic serialization involves converting an object to JSON using its base class or interface, while also retaining information (such as its actual type) to ensure the correct derived class is restored during deserialization.

Polymorphic Deserialization

Polymorphic deserialization involves converting JSON back into the correct derived class, rather than just the base class.

.NET 8 builds on the capabilities introduced in .NET 7 by further enhancing support for polymorphic serialization through the JsonDerivedType attribute, JsonPolymorphismOptions, and JsonPolymorphic.

The source code can be downloaded from this GitRepo.

In our example, the MessageRequest JSON includes a nested Message object, which can represent either an Email or an Sms, each with its own specific fields. The MessageType property is used to identify the type of message.

This explanation covers a simple approach known as declarative polymorphism, which leverages attributes.

namespace PolymorphicDeserialization.Models
{
    [JsonPolymorphic(TypeDiscriminatorPropertyName = "MessageType")]
    [JsonDerivedType(typeof(Email), "Email")]
    [JsonDerivedType(typeof(Sms), "Sms")]
    public abstract class Message
    {
        public string MessageBody { get; set; }
    }
    public class Email : Message
    {
        public string EmailAddress { get; set; }
    }

    public class Sms : Message
    {
        public string PhoneNumber { get; set; }
    }
    public class MessageRequest
    {
        public string RequestId { get; set; }
        public Message Message { get; set; }
    }
}

To properly handle serialization and deserialization.

Note. You don’t need to explicitly define the MessageType field in the Email and Sms classes. It is automatically included during serialization and leveraged during deserialization to determine the appropriate class.

Common Mistakes to Avoid

I just ran the code and captured screenshots for both deserialization and serialization.

Deserialization

Deserialization

Serialization

Serialization

Conclusion

Polymorphic deserialization in .NET 8 is now a built-in, first-class feature. It makes handling different object types easier in scenarios like message processing, APIs, or document-based storage.

Happy Coding!