直接用 JsonSerializer.Deserialize<List<T>>() 或 JsonConvert.DeserializeObject<List<T>>() 解析 JSON 数组时,类型不匹配、空值、嵌套结构不一致会抛运行时异常;System.Text.Json 默认区分大小写,需设 PropertyNameCaseInsensitive = true;下划线命名需配合 JsonNamingPolicy;日期需 DateTimeConverter;Newtonsoft 中 null 值对非可空类型报错,应改可空类型或配 NullValueHandling.Ignore;不规则数组宜用 JArray/JObject 手动解析;嵌套数组须声明正确泛型类型;动态 key 用 Dictionary<string, T>;解析前应校验 JSON 合法性。

直接用 JsonSerializer.Deserialize<List<T>>() 或 JsonConvert.DeserializeObject<List<T>>() 就能解析 JSON 数组,但类型不匹配、空值、嵌套结构不一致时会直接抛异常——不是语法错,是运行时崩。
用 System.Text.Json 解析 JSON 数组必须注意字段名大小写
System.Text.Json 默认严格区分大小写,而多数 API 返回的 JSON 字段是小驼峰(firstName),C# 模型常用 PascalCase(FirstName)。不配选项就会反序列化失败,字段全为默认值。
- 必须显式传入
new JsonSerializerOptions { PropertyNameCaseInsensitive = true } - 如果 JSON 里有
"user_name"这种下划线命名,还得配合JsonNamingPolicy.CamelCase或自定义 converter - 日期字段如
"created_at": "2025-03-12T14:22:00",模型用DateTime但没配DateTimeConverter,可能抛JsonException
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
Converters = { new JsonStringEnumConverter() }
};
var list = JsonSerializer.Deserialize<List<User>>(json, options);Newtonsoft.Json 解析数组时 null 值容易导致 NullReferenceException
Newtonsoft 默认把缺失字段或 null 值映射为 null,如果模型属性是 int、DateTime 等非 nullable 值类型,反序列化会直接报错:Cannot convert null value to Int32。
- 要么把字段改成可空类型:
public int? Age { get; set; } - 要么加
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]特性 - 要么全局配置
JsonConvert.DefaultSettings = () => new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
遇到不规则数组(混合类型或部分字段缺失)别硬套强类型
比如 JSON 是 [{"id":1,"name":"a"},{"id":2}],第二个对象缺 name,用 List<Person> 解析会失败;又比如 [{"type":"user","data":{...}},{"type":"error","msg":"xxx"}],结构完全不统一。
- 优先用
JArray.Parse(json)+ 手动遍历每个JToken,再按需取字段 - 或用
JsonConvert.DeserializeObject<List<JObject>>(json),后续用obj.TryGetValue("name", out var name)安全读取 - 强类型只适用于结构稳定、契约明确的场景;临时调试或对接野 API,
JObject/JArray更容错
数组元素里嵌套对象数组时,别漏掉深层泛型声明
像这种结构:[{"id":1,"orders":[{"no":"A001"},{"no":"A002"}]}],对应模型里 Orders 属性必须声明为 List<Order>,不能只写 Order[] 或 IEnumerable<Order>(System.Text.Json 对接口支持有限,Newtonsoft 虽能处理但建议统一用 List)。
- 嵌套层级越深,模型类越要和 JSON 键名、类型、可空性一一对应
- 如果某层是动态 key(如
"items": {"2025Q1": {...}, "2025Q2": {...}}),就得用Dictionary<string, Item>,不能用数组 - 别依赖“自动推断”——JSON 库不会猜你想要什么类型,它只按声明的泛型去匹配
最常被忽略的其实是 JSON 字符串本身是否合法:开头结尾有没有多余空格、换行、BOM 头,或者用了单引号。解析前用 json.Trim().StartsWith("[") 快速校验一下,比看异常堆栈快得多。


















