CodexBloom - Programming Q&A Platform

Unexpected Behavior When Using Custom JsonConverter with Inherited Classes in System.Text.Json

πŸ‘€ Views: 43 πŸ’¬ Answers: 1 πŸ“… Created: 2025-06-12
json serialization system.text.json custom-converter C#

I've spent hours debugging this and Could someone explain I'm following best practices but I'm not sure how to approach I'm writing unit tests and I'm facing an issue with serialization when using a custom `JsonConverter` for a base class with derived classes in .NET 6... I created a base class `Animal` and two derived classes, `Dog` and `Cat`. My custom converter is supposed to serialize the specific type of animal based on a `Type` property in the JSON. However, I'm getting an unexpected `JsonException` when trying to deserialize the JSON back into objects. The error message states: `The JSON value could not be converted to MyNamespace.Animal because the type requires a JsonConverter`. Here’s the structure of my classes: ```csharp public abstract class Animal { public string Name { get; set; } public abstract string Type { get; } } public class Dog : Animal { public override string Type => "Dog"; public string Breed { get; set; } } public class Cat : Animal { public override string Type => "Cat"; public string Color { get; set; } } ``` My custom converter looks like this: ```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; string type = root.GetProperty("Type").GetString(); Animal animal = type switch { "Dog" => JsonSerializer.Deserialize<Dog>(root.GetRawText(), options), "Cat" => JsonSerializer.Deserialize<Cat>(root.GetRawText(), options), _ => throw new JsonException("Unknown animal type") }; return animal; } } public override void Write(Utf8JsonWriter writer, Animal value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, value.GetType(), options); } } ``` And I register the converter like this: ```csharp var options = new JsonSerializerOptions { Converters = { new AnimalConverter() } }; ``` When I try to deserialize a JSON string like this: ```json {"Name":"Buddy","Type":"Dog","Breed":"Golden Retriever"} ``` I get the aforementioned exception. I've double-checked that the `Type` property is present in the JSON, and I'm passing the correct `JsonSerializerOptions` with the converter included. I feel like I've followed the correct approach, but I'm clearly missing something. Any ideas on what could be causing this issue? For reference, this is a production desktop app. What would be the recommended way to handle this? My team is using C# for this service. This is my first time working with C# 3.9. What's the best practice here? I'm working with C# in a Docker container on Debian. What's the best practice here? Cheers for any assistance!