You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JSON.NET将指定JSON反序列化为List<Person>集合

解决方案

1. 定义实体类

先根据JSON结构定义对应的数据类:

// 科目类,根据实际JSON的subjects字段调整属性
public class Subject
{
    public string Name { get; set; }
    public int? Score { get; set; } // 支持学生带分数、老师仅科目名的场景
}

// 最终的人员类,Id存储原JSON的键(如student 1)
public class Person
{
    public string Id { get; set; }
    public string Name { get; set; }
    public Subject[] Subjects { get; set; }
}

// 包含人员集合的自定义类
public class MyClass
{
    public List<Person> People { get; set; }
}

2. 反序列化实现方案

方法一:字典中转映射(简单直观)

由于原JSON是键值对结构(键为student 1这类标识,值为人员数据),可以先反序列化为字典,再手动映射为List<Person>:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

// 示例JSON字符串
string json = @"
{
  ""student 1"": {
    ""name"": ""Alice"",
    ""subjects"": {
      ""Math"": 95,
      ""English"": 88
    }
  },
  ""student 2"": {
    ""name"": ""Bob"",
    ""subjects"": {
      ""Physics"": 90,
      ""Chemistry"": 85
    }
  },
  ""teacher 1"": {
    ""name"": ""Mr. Smith"",
    ""subjects"": [""Math"", ""Physics""]
  }
}";

// 1. 反序列化为字典,键是原JSON的标识,值为JObject
var personDict = JsonConvert.DeserializeObject<Dictionary<string, JObject>>(json);

// 2. 映射为List<Person>
var people = new List<Person>();
foreach (var kvp in personDict)
{
    var person = new Person
    {
        Id = kvp.Key,
        Name = kvp.Value["name"].ToString()
    };

    // 处理subjects:兼容对象(科目:分数)和数组(纯科目名)两种格式
    var subjectsToken = kvp.Value["subjects"];
    if (subjectsToken.Type == JTokenType.Object)
    {
        person.Subjects = subjectsToken
            .Children<JProperty>()
            .Select(p => new Subject
            {
                Name = p.Name,
                Score = int.Parse(p.Value.ToString())
            })
            .ToArray();
    }
    else if (subjectsToken.Type == JTokenType.Array)
    {
        person.Subjects = subjectsToken
            .Select(s => new Subject { Name = s.ToString() })
            .ToArray();
    }

    people.Add(person);
}

// 赋值给MyClass
var myClass = new MyClass { People = people };

方法二:自定义JsonConverter(一步到位)

如果想直接反序列化为MyClass,可以编写自定义转换器:

public class MyClassConverter : JsonConverter<MyClass>
{
    public override MyClass ReadJson(JsonReader reader, Type objectType, MyClass existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var personDict = serializer.Deserialize<Dictionary<string, JObject>>(reader);
        var people = new List<Person>();

        foreach (var kvp in personDict)
        {
            var person = new Person
            {
                Id = kvp.Key,
                Name = kvp.Value["name"].ToString()
            };

            // 同方法一处理subjects
            var subjectsToken = kvp.Value["subjects"];
            if (subjectsToken.Type == JTokenType.Object)
            {
                person.Subjects = subjectsToken
                    .Children<JProperty>()
                    .Select(p => new Subject
                    {
                        Name = p.Name,
                        Score = int.Parse(p.Value.ToString())
                    })
                    .ToArray();
            }
            else if (subjectsToken.Type == JTokenType.Array)
            {
                person.Subjects = subjectsToken
                    .Select(s => new Subject { Name = s.ToString() })
                    .ToArray();
            }

            people.Add(person);
        }

        return new MyClass { People = people };
    }

    public override void WriteJson(JsonWriter writer, MyClass value, JsonSerializer serializer)
    {
        // 如需序列化回JSON,可自行实现,此处省略
        throw new NotImplementedException();
    }
}

使用转换器:

var myClass = JsonConvert.DeserializeObject<MyClass>(json, new MyClassConverter());

关键说明

  • 核心逻辑是用字典接收原JSON的键值对,将字典的Key作为Person的Id字段
  • subjects的处理逻辑需匹配实际JSON结构,若你的subjects本身就是标准数组(如[{"name":"Math", "score":95}]),可直接用serializer.Deserialize<Subject[]>(subjectsToken)转换

内容的提问来源于stack exchange,提问作者Paul Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 00:20:05