如何使用 JSON 序列化继承自 List<T> 并具有附加属性的类型

问题描述 投票:0回答:1

任何人都知道我如何使用 System.Text.Json 序列化此类

  public class MachineTray : List<MachineCoil>
  {

      public String TrayName { get; set; }

      public MachineTray() : base() { }

  }

这也无济于事,因为这只是一个更大物体的一部分

public class Machine 
{
    public List<MachineTray> Trays;
}

我正在序列化对象列表。

JsonSerializerOptions JSO = new JsonSerializerOptions();
               
JSO.WriteIndented = true;

String JSON = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(Machines, Machines.GetType(), JSO ));

我一直在使用https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism?pivots=dotnet-8-0

尝试各种组合

但是,无论我尝试什么,我总是只是得到一个序列化的列表,并且缺少 TrayName 属性。

c# system.text.json
1个回答
0
投票

您的情况非常棘手,不确定是否有解决方案,但让我们尝试找出答案:

您继承一个列表并向其添加您想要以 JSON 形式保留的新属性。我们首先想一下 JSON 是什么样子的。对于列表来说很简单:

[ { ...object } , {... another item}, ...]

所以,这里的根是数组本身,我们没有根“准备好包含”更多道具 - 我们该怎么做?

为了在列表中包含更多信息,我们提供了两个选项:

  • 向根添加信息 - 在我们的例子中,向数组添加信息,因此这意味着为每个新属性添加一个额外的项目 - 这非常令人困惑,并且会与原始数组项目混淆 - 所以这不是我们想要的
  • 另一个选项 - 创建根目录,将数组与您想要的任何属性一起保存,因此 JSON 可能如下所示:
{ "TrayName": "Name 051"; "Items": [ { ...object } , {... another item}, ...] }

我认为只有后一种选择才有意义。

现在,C# 端的模型将如下所示:

private class MachineTrayDto
{
    public string TrayName { get; set; }
    public List<MachineCoil> MachineCoils { get; set; }
}

现在应该很明显了,为什么在你的情况下继承

List
是个坏主意。您可以使用上面的模型。

但是生活很奇怪,也许这就是你想要的。因此,要处理概述的场景,您可以使用这样的

JsonConverter
:

public class MachineTrayJsonConverter : JsonConverter<MachineTray>
{
    public override MachineTray? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var dto = JsonSerializer.Deserialize<MachineTrayDto>(ref reader);
        var tray = new MachineTray
        {
            TrayName = dto.TrayName,
        };
        tray.AddRange(dto.MachineCoils);
        return tray;
    }

    public override void Write(Utf8JsonWriter writer, MachineTray value, JsonSerializerOptions options)
    {
        var dto = new MachineTrayDto { TrayName = value.TrayName, };
        dto.MachineCoils = value;
        JsonSerializer.Serialize(writer, dto);
    }

    private class MachineTrayDto
    {
        public string TrayName { get; set; }
        public List<MachineCoil> MachineCoils { get; set; }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.