Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Text.Json serialize derived class property

I'm migrating a project from Newtonsoft.Json to System.Text.Json in .NET 5.

I have class:

abstract class Car
{
    public string Name { get; set; } = "Default Car Name";
}

class Tesla : Car
{
    public string TeslaEngineName { get; set; } = "My Tesla Engine";
}

I tried:

var cars = new List<Car> 
{ 
    new Tesla(),
    new Tesla(),
    new Tesla()
};

var json = JsonSerializer.Serialize(cars);

Console.WriteLine(json);

The output is:

[
  {"Name":"Default Car Name"},
  {"Name":"Default Car Name"},
  {"Name":"Default Car Name"}
]

Which lost my property: TeslaEngineName.

So how can I serialize derived an object with all properties?

like image 534
Anduin Avatar asked Mar 07 '26 18:03

Anduin


2 Answers

This is a design feature of System.Text.Json, see here for more details. Your options are:

  1. Keep using JSON.Net

  2. Use one of the workarounds, in this case use a List<object> or cast your list when serialising. For example:

    var json = JsonSerializer.Serialize(cars.Cast<object>());
                                             ^^^^^^^^^^^^^^
    

    The downside of this option is that it will still not serialise any nested properties of derived classes.

like image 171
DavidG Avatar answered Mar 10 '26 09:03

DavidG


Starting in .NET 7, you can use the JsonDerivedType attribute to decorate the base class with the derived classes.

[JsonDerivedType(typeof(WeatherForecastWithCity))]
public class WeatherForecastBase
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

public class WeatherForecastWithCity : WeatherForecastBase
{
    public string? City { get; set; }
}

Serializing an object of type WeatherForecastWithCity will properly include the City property:

{
  "City": "Milwaukee",
  "Date": "2022-09-26T00:00:00-05:00",
  "TemperatureCelsius": 15,
  "Summary": "Cool"
}

Further reading: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism?pivots=dotnet-8-0

like image 37
Noel Avatar answered Mar 10 '26 07:03

Noel