直接用jsonserializer.deserialize解析顶层json数组;嵌套数组字段应声明为list而非array或ienumerable;空字段需显式判空或初始化;动态场景优先用jsondocument。

用 JsonSerializer.Deserialize<list>>()</list> 直接解析顶层 JSON 数组
如果接口返回的是纯数组(如 [{"id":1,"name":"a"},{"id":2,"name":"b"}]),别套一层 Root 包装类,直接反序列化到 List<t></t> 或 T[]。System.Text.Json 默认支持,一行搞定:var items = JsonSerializer.Deserialize<list>>(jsonString);</list>
常见错误是硬写成 JsonSerializer.Deserialize<root>(jsonString)</root>,而 Root 里只定义了一个 public List<product> Data { get; set; }</product> —— 这会导致解析失败或返回 null,因为 JSON 根节点不是对象,而是方括号开头的数组。
嵌套数组字段(如 "orders": [...] )声明为 List<t></t>,别用 Array 或 IEnumerable<t></t>
在模型类中遇到 JSON 里的数组字段,比如:"items": [{"sku":"P001","qty":2}]
对应属性必须声明为 public List<orderitem> Items { get; set; }</orderitem>。
以下写法会出问题:
-
public OrderItem[] Items:System.Text.Json 默认不支持数组反序列化(除非显式配置JsonSerializerOptions的DefaultBufferSize和类型映射) -
public IEnumerable<orderitem> Items</orderitem>:接口不可实例化,反序列化直接抛NotSupportedException -
public IList<orderitem> Items</orderitem>:虽能工作,但不如List<t></t>明确、兼容性好
"items": [] 能正常绑定,前提是字段不是 readonly 或没加 init 限制。
遍历嵌套数组时,NullReferenceException 多半是因为父级对象没初始化
典型场景:JSON 中 "customer" 对象存在,但它的 "addresses" 字段缺失或为 null,而你的模型写成:public List<address> Addresses { get; set; } = new();</address>
看起来安全?错。如果 JSON 里压根没这个字段,Addresses 仍会被设为 null(System.Text.Json 默认不调用构造函数或赋默认值)。正确做法:
- 用可空引用类型 + 显式判空:
public List<address>? Addresses { get; set; }</address>,访问前检查if (obj.Addresses?.Count > 0) - 或启用
JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull并配合[JsonPropertyName("addresses")]确保字段名对齐 - 更稳妥:在反序列化后统一做空值填充(如
item.Addresses ??= new();)
需要动态遍历任意层嵌套数组?优先用 JsonDocument,不是 JObject
当你不确定结构、又不想建一堆类(比如日志聚合、配置探查、调试工具),JsonDocument.Parse() 比 JObject.Parse() 更轻量、内存友好,且是 .NET 原生 API:
using var doc = JsonDocument.Parse(jsonString);<br>foreach (var item in doc.RootElement.GetProperty("data").EnumerateArray()) {<br> string name = item.GetProperty("user").GetProperty("name").GetString();<br>}
注意:
-
JsonDocument是只读的,不能修改;要改用JsonNode(.NET 6+)或退回JObject - 每次调用
GetProperty()前必须确认字段存在,否则抛KeyNotFoundException;用TryGetProperty("xxx", out var elem)更安全 - 别在循环里反复
Parse()同一段 JSON——开销大,应复用JsonDocument实例
JObject 才值得引入,但得承担额外 NuGet 依赖和维护成本。
复杂嵌套数组最常卡在“以为字段一定存在”和“忽略大小写/命名风格差异”这两点上,实际跑通的关键往往不在怎么写循环,而在模型字段是否真和 JSON 对得上——建议先用 JsonDocument 快速 dump 出根结构,再动手建类。











