Search code examples
c#jsonserializationasp.net-core-webapiabstract-class

How to serialize multiple different classes in a list that all inherit from the same abstract class


In an ASP.NET Core 8 Web API, I have the following structure:

public abstract class BaseClass
{
}

public class A : BaseClass 
{
    [JsonPropertyName("PropA")]
    public int PropA { get; set; }
}

public class B : BaseClass 
{
    [JsonPropertyName("PropB")]
    public int PropB { get; set; }
}

public class Row 
{
    [JsonPropertyName("cells")]
    public List<BaseClass> Cells { get; set; }
}

public class Table 
{    
    [JsonPropertyName("rows")]
    public List<Row> Rows { get; set; }
    [JsonPropertyName("pageNumber")]
    public int PageNumber { get; set; }
    [JsonPropertyName("pageSize")]
    public int PageSize { get; set; }
    [JsonPropertyName("totalAmountRecords")]
    public int TotalAmountRecords { get; set; }
    [JsonPropertyName("totalAmountPages")]
    public int TotalAmountPages { get; set; }
    [JsonPropertyName("recordOffset")]
    public int RecordOffset { get; set; }
}

This data structure needs to be able to store multiple classes (with different properties) in the same list and be serialized to a JSON to be returned to the client.

I return Ok{tableInstance} and I get this:

{"rows":{],"pageNumber":0,"pageSize":20,"totalAmountRecords":100,"totalAmountPages":5,"recordOffset":0}

But for some reason rows is empty while it is filled up, since pageSize=rows.Count.

I to implement a custom serializer, but couldn't get it syntax wise working. I wasn't able to find any similar problem either.


Solution

  • You need to tell System.Text.Json serializer about derived types:

    [JsonDerivedType (typeof (A))]
    [JsonDerivedType (typeof (B))]
    public abstract class BaseClass {
    
    }
    

    If your derived types are located in other assemblies so that you cannot use JsonDerivedType attributes, you will have to set up a custom contract resolver.