CodexBloom - Programming Q&A Platform

C# 10 - Serialization implementing Polymorphic Objects Using System.Text.Json

πŸ‘€ Views: 334 πŸ’¬ Answers: 1 πŸ“… Created: 2025-07-27
c# json serialization polymorphism dotnet6 C#

I'm wondering if anyone has experience with I'm converting an old project and I'm upgrading from an older version and I'm working with a question when trying to serialize and deserialize a polymorphic object hierarchy using `System.Text.Json` in .NET 6... I have a base class `Animal` and two derived classes `Dog` and `Cat`. The serialization seems to work, but when I try to deserialize the JSON back into the respective objects, it always creates an instance of `Animal` instead of the specific derived class. Here’s a simple version of my classes: ```csharp public abstract class Animal { public string Name { get; set; } } public class Dog : Animal { public string BarkSound { get; set; } } public class Cat : Animal { public string MeowSound { get; set; } } ``` When I serialize a `Dog` object like this: ```csharp var dog = new Dog { Name = "Rex", BarkSound = "Woof!" }; var json = JsonSerializer.Serialize(dog); ``` It produces the JSON: ```json {"Name":"Rex","BarkSound":"Woof!"} ``` However, during deserialization, I use: ```csharp var animal = JsonSerializer.Deserialize<Animal>(json); ``` Expectedly, I would like `animal` to be of type `Dog`, but it stays as `Animal` with only the `Name` property populated. I even tried using a custom converter, but I’m running into various issues with type discrimination. Here's the converter I attempted: ```csharp public class AnimalConverter : JsonConverter<Animal> { public override Animal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { using (JsonDocument doc = JsonDocument.ParseValue(ref reader)) { var root = doc.RootElement; if (root.TryGetProperty("BarkSound", out _)) { return JsonSerializer.Deserialize<Dog>(root.GetRawText(), options); } else if (root.TryGetProperty("MeowSound", out _)) { return JsonSerializer.Deserialize<Cat>(root.GetRawText(), options); } return null; } } public override void Write(Utf8JsonWriter writer, Animal value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, value.GetType(), options); } } ``` I've registered the converter in the `JsonSerializerOptions`: ```csharp var options = new JsonSerializerOptions { Converters = { new AnimalConverter() } }; var animal = JsonSerializer.Deserialize<Animal>(json, options); ``` But I still end up with the base class only. The behavior I’m seeing in logs is `Unable to convert JSON to object of type 'Animal'`. Can anyone suggest what I might be missing or how I can properly implement polymorphic serialization and deserialization with `System.Text.Json`? I'm working on a REST API that needs to handle this. Am I approaching this the right way? I'd love to hear your thoughts on this. This is part of a larger web app I'm building. Thanks for taking the time to read this!