反序列化具有混合值 System.Text.JSON 的 JSON 数组

use*_*999 5 c# inheritance json system.text.json

我正在尝试创建一个在 .net core 3.1 中呈现的页面,该页面基于 JSON 呈现页面。

如何反序列化本文末尾的 JSON?

我尝试反序列化它,但它不起作用,因为我丢失了每个组件的数据,因为 Page 类有一个List<Component>- 但我需要它是不同组件的列表。

页面模型:

public class Page
    {
        public int id { get; set; }
        public string pagename { get; set; }
        public string metatitle { get; set; }
        public string metadescription { get; set; }
        public string created_at { get; set; }
        public string updated_at { get; set; }
        public List<Component> components { get; set; }
    }

    public class Pages
    {
        public List<Page> pages { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

组件型号:

public class Component
    {
        public string component { get; set; }
        public int id { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

一个组件:

public class Title : Component
    {
        public string component { get; set; }
        public int id { get; set; {
        public string titletext { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

这是 JSON:

{
      "id":1,
      "pagename":"home",
      "metatitle":"no title",
      "metadescription":"no meta",
      "created_at":"2020-05-31T16:35:52.084Z",
      "updated_at":"2020-05-31T16:35:52.084Z",
      "components":[
         {
            "component":"components.titletext",
            "id":1,
            "titletext":"hello"
         },
         {
            "component":"components.section",
            "id":2,
            "titletext":"hello",
            "descriptiontext":"its a beatiful day in lost santos",
            "buttonlink":"/go"
         },
         {
            "component":"components.cta",
            "id":3,
            "sectiontitle":"hello",
            "buttonlink":"/go",
            "buttontext":"click me"
         }
      ]
   }
Run Code Online (Sandbox Code Playgroud)

Gur*_*ron 4

如果您不想将所有属性添加到类中,Component如下所示:

public class Component
{
    public string component { get; set; }
    public int id { get; set; }
    public string titletext { get; set; }
    public string sectiontitle { get; set; }
    public string buttonlink { get; set; }
    public string descriptiontext { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

例如,您需要编写自定义JsonConverter(不是非常高性能的实现,但可以与您的 json 一起使用,并且您不需要手动解析每个字段):

public class ComponentConverter : JsonConverter<Component>
{
    public override Component Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using (var doc = JsonDocument.ParseValue(ref reader))
        {
            var type = doc.RootElement.GetProperty(@"component").GetString();
            switch(type)
            {
                case "components.titletext": 
                    return JsonSerializer.Deserialize<Title>(doc.RootElement.GetRawText());
                // other types handling
                default: return JsonSerializer.Deserialize<Component>(doc.RootElement.GetRawText());
            }
        }
    }

    public override void Write(Utf8JsonWriter writer, Component value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

public class Component
{
    public string component { get; set; }
    public int id { get; set; }
}

public class Title : Component
{
    public string titletext { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

以及用法示例:

var json = @"[
     {
        ""component"":""components.titletext"",
        ""id"":1,
        ""titletext"":""hello""
     },
     {
""component"":""components.section"",
        ""id"":2,
        ""titletext"":""hello"",
        ""descriptiontext"":""its a beatiful day in lost santos"",
        ""buttonlink"":""/go""
     },
     {
""component"":""components.cta"",
        ""id"":3,
        ""sectiontitle"":""hello"",
        ""buttonlink"":""/go"",
        ""buttontext"":""click me""
     }
  ]";
var deserializeOptions = new JsonSerializerOptions();
deserializeOptions.Converters.Add(new ComponentConverter());
JsonSerializer.Deserialize<List<Component>>(json, deserializeOptions).Dump();
Run Code Online (Sandbox Code Playgroud)

也不要使用此转换器作为参数,因为JsonConverterAttribute它会在 stackoverflow 中结束。