直接用JsonSerializer.Deserialize<List<T>>解析顶层JSON数组;嵌套数组字段应声明为List<T>而非Array或IEnumerable<T>;空字段需显式判空或初始化;动态场景优先用JsonDocument。

用 JsonSerializer.Deserialize<List<T>>() 直接解析顶层 JSON 数组
如果接口返回的是纯数组(如 [{"id":1,"name":"a"},{"id":2,"name":"b"}]),别套一层 Root 包装类,直接反序列化到 List<T> 或 T[]。System.Text.Json 默认支持,一行搞定:var items = JsonSerializer.Deserialize<List<Product>>(jsonString);
常见错误是硬写成 JsonSerializer.Deserialize<Root>(jsonString),而 Root 里只定义了一个 public List<Product> Data { get; set; } —— 这会导致解析失败或返回 null,因为 JSON 根节点不是对象,而是方括号开头的数组。
嵌套数组字段(如 "orders": [...] )声明为 List<T>,别用 Array 或 IEnumerable<T>
在模型类中遇到 JSON 里的数组字段,比如:"items": [{"sku":"P001","qty":2}]
对应属性必须声明为 public List<OrderItem> Items { get; set; }。
以下写法会出问题:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
-
public OrderItem[] Items:System.Text.Json 默认不支持数组反序列化(除非显式配置JsonSerializerOptions的DefaultBufferSize和类型映射) -
public IEnumerable<OrderItem> Items:接口不可实例化,反序列化直接抛NotSupportedException -
public IList<OrderItem> Items:虽能工作,但不如List<T>明确、兼容性好
"items": [] 能正常绑定,前提是字段不是 readonly 或没加 init 限制。
遍历嵌套数组时,NullReferenceException 多半是因为父级对象没初始化
典型场景:JSON 中 "customer" 对象存在,但它的 "addresses" 字段缺失或为 null,而你的模型写成:public List<Address> Addresses { get; set; } = new();
看起来安全?错。如果 JSON 里压根没这个字段,Addresses 仍会被设为 null(System.Text.Json 默认不调用构造函数或赋默认值)。正确做法:
- 用可空引用类型 + 显式判空:
public List<Address>? Addresses { get; set; },访问前检查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 出根结构,再动手建类。

















