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

标签 c# json inheritance 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; }
    }

组件模型:
public class Component
    {
        public string component { get; set; }
        public int id { get; set; }
    }

一个组件:
public class Title : Component
    {
        public string component { get; set; }
        public int id { get; set; {
        public string titletext { get; set; }
    }

这是 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"
         }
      ]
   }

最佳答案

如果您不想将所有属性添加到 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; }
}

您将需要编写自定义 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; }
}

和用法示例:
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();

也不要将此转换器用作 JsonConverterAttribute 的参数因为它将以 stackoverflow 结束。

关于c# - 反序列化具有混合值 System.Text.JSON 的 JSON 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62121242/

相关文章:

php - Json 与 PHP mysql 和 Jquery

c++ - 用当前类专门化继承的模板函数

c++ - 具有相同名称的继承函数如何被视为重载函数?

c# - 具有基类和子类的扩展方法

C# 方法求和 hh :mm data ? ??

c# - 单元测试 : Assert range of a list with greater or lesser than

java - 将 HashMap 数据保存到 SQLite

json - 如何在 N1QL 中查看 couchbase 服务器中的文档树?

c# - Membership.GetUser(userName, isOnline) 总是更新 LastActivityDate

c# - Github api 使用 octokit.net 获取按标签过滤的问题