Сериализация объектов, реализующих интерфейс с System.Text.Json - PullRequest
0 голосов
/ 14 октября 2019

У меня есть мастер-класс, который содержит общую коллекцию. Элементы в коллекции имеют разные типы, и каждый реализует интерфейс.

Мастер-класс:

public class MasterClass
{
    public ICollection<IElement> ElementCollection { get; set; }
}

Контракт для элементов:

public interface IElement
{
    string Key { get; set; }
}

Два образца дляэлементы:

public class ElementA : IElement
{
    public string Key { get; set; }

    public string AValue { get; set; }
}

public class ElementB : IElement
{
    public string Key { get; set; }

    public string BValue { get; set; }
}

Мне нужно сериализовать экземпляр объекта MasterClass, используя новую библиотеку System.Text.Json в Json. Используя следующий код,

public string Serialize(MasterClass masterClass)
{
    var options = new JsonSerializerOptions
    {
        WriteIndented = true,
    };
    return JsonSerializer.Serialize(masterClass, options);
}

я получаю следующий JSON:

{
    "ElementCollection":
    [
        {
            "Key": "myElementAKey1"
        },
        {
            "Key": "myElementAKey2"
        },
        {
            "Key": "myElementBKey1"
        }
    ]
}

вместо:

{
    "ElementCollection":
    [
        {
            "Key": "myElementAKey1",
            "AValue": "MyValueA-1"
        },
        {
            "Key": "myElementAKey2",
            "AValue": "MyValueA-2"
        },
        {
            "Key": "myElementBKey1",
            "AValue": "MyValueB-1"
        }
    ]
}

Какой класс (конвертер, писатель, .. .) я должен реализовать для получения полного JSON?

Заранее спасибо за вашу помощь.

1 Ответ

0 голосов
/ 21 октября 2019

Решение состоит в том, чтобы реализовать универсальный конвертер (System.Text.Json.Serialization.JsonConverter):

public class ElementConverter : JsonConverter<IElement>
{
    public override IElement Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, IElement value, JsonSerializerOptions options)
    {
        if (value is ElementA)
            JsonSerializer.Serialize(writer, value as ElementA, typeof(ElementA), options);
        else if (value is ElementB)
            JsonSerializer.Serialize(writer, value as ElementB, typeof(ElementB), options);
        else
            throw new ArgumentOutOfRangeException(nameof(value), $"Unknown implementation of the interface {nameof(IElement)} for the parameter {nameof(value)}. Unknown implementation: {value?.GetType().Name}");
    }
}

Просто нужно сложить больше работы для метода Read.

...