System.Text.Json не сериализует классы наследники в списке

Есть следующая структура классов:

    public class foo
    {
        public string name { get; set; }
    }

    public class derived : foo
    {
        public string lastName { get; set; }
    }

    public class container
    {
        public List<foo> foos { get; set; }
    }

Мне надо составить список и отправить его на сервер предварительно засереализировав его.

var c = new container
{
    foos = new List<foo>
    {
        new derived{name = "first", lastName = "first"},
        new derived{name = "second", lastName = "second"},
        new derived{name = "third", lastName = "third"}
    }
};

Console.WriteLine(JsonSerializer.Serialize(c));

Для сериализации использую System.Text.Json, стандартную либу в нет коре. Получаю след вывод

{"foos":[{"name":"first"},{"name":"second"},{"name":"third"}]}

Почему нет полей которые дополнил класс наследника?

Например в Newtonsoft все поля сериализируются.

Проблему можно частично решить если сделать список обьектов

public List<object> foos { get; set; }

В таком случае все поля сериализируются. Но такой вариант немного корявый и мне не подходит.


Ответы (1 шт):

Автор решения: aepot

Вообще да, странный получится json, если массив будет содержать разные типы данных. Как это десереализовать потом? Без костылей никак. Придется иметь кастомные контвертеры либо специальную модель данных для сериализации.

Я бы лучше организовал контейнер так:

public class Foo
{
    public string name { get; set; }
}

public class Derived : Foo
{
    public string lastName { get; set; }
}

public class Container<T> where T : Foo
{
    public List<T> foos { get;  set; }
}

Тогда код, который вы привели, будет выглядеть так:

var c = new Container<Derived>
{
    foos = new List<Derived>
    {
        new Derived{name = "first", lastName = "first"},
        new Derived{name = "second", lastName = "second"},
        new Derived{name = "third", lastName = "third"}
    }
};

Console.WriteLine(JsonSerializer.Serialize(c));

И работать так как нужно

{"foos":[{"lastName":"first","name":"first"},{"lastName":"second","name":"second"},{"lastName":"third","name":"third"}]}
→ Ссылка