C#中解析JsonArray时如何跳过解析失败的元素?
解析JSON数组时跳过错误对象并保留有效数据(C#)
问题背景
现有如下C#代码,用于解析JSON数组:
实体类定义
public class Person { public int Id { get; set; } public required string Name { get; set; } }
原解析代码
var jsonString = @" [ { ""Id"": 1, ""Name"": ""name1"" }, { ""Id"": 2, ""Name"": ""name2"" }, { ""Id"": 3, ""NameX"": ""name3"" }, { ""Id"": 4, ""Name"": ""name4"" }, { ""Id"": 5, ""Name"": ""name5"" } ] "; List<Person> people = JsonSerializer.Deserialize<List<Person>>(jsonString) ?? []; Console.WriteLine(people.Count);
由于JSON字符串中第三个对象的字段为NameX(应为Name),且Person类的Name属性带有required修饰符(无法移除),直接反序列化整个列表会抛出运行时错误;若用try-catch包裹,最终会得到空列表。需要修改代码实现:解析所有格式正确的对象,跳过并记录错误对象,最终保留Id为1、2、4、5的4个有效Person对象。
解决方案
核心思路是拆分JSON数组为单个对象节点,逐个尝试反序列化,隔离错误对象的影响,同时记录错误信息。具体实现如下:
完整修改后的代码
public class Person { public int Id { get; set; } public required string Name { get; set; } } // 主程序逻辑 var jsonString = @" [ { ""Id"": 1, ""Name"": ""name1"" }, { ""Id"": 2, ""Name"": ""name2"" }, { ""Id"": 3, ""NameX"": ""name3"" }, { ""Id"": 4, ""Name"": ""name4"" }, { ""Id"": 5, ""Name"": ""name5"" } ] "; List<Person> validPeople = new(); List<string> errorLogs = new(); // 先将JSON数组解析为单个JsonElement节点 if (JsonSerializer.Deserialize<JsonElement[]>(jsonString) is { } elements) { foreach (var element in elements) { try { // 尝试反序列化单个对象 if (JsonSerializer.Deserialize<Person>(element) is { } person) { validPeople.Add(person); } } catch (JsonException ex) { // 记录错误对象的原始JSON及异常信息 string errorMsg = $"解析失败的对象: {element.GetRawText()}\n错误详情: {ex.Message}\n"; errorLogs.Add(errorMsg); } } } // 输出结果 Console.WriteLine($"有效对象总数: {validPeople.Count}"); Console.WriteLine("有效对象Id: " + string.Join(", ", validPeople.Select(p => p.Id))); // 输出错误日志(按需使用) if (errorLogs.Any()) { Console.WriteLine("\n=== 错误日志 ==="); foreach (var log in errorLogs) { Console.WriteLine(log); } }
代码说明
- 拆分JSON数组:先将原始JSON反序列化为
JsonElement[],把数组拆分为独立的对象节点,避免单个错误导致整个数组解析失败; - 逐个反序列化:遍历每个节点,用try-catch包裹单个对象的反序列化逻辑,成功则加入有效列表,失败则记录错误;
- 错误追踪:通过
element.GetRawText()获取错误对象的原始JSON,结合异常信息记录,方便后续排查问题。
运行后会输出4个有效对象,同时记录第三个对象的解析错误,完全满足需求。
内容的提问来源于stack exchange,提问作者user25975796
相关产品推荐
相关产品推荐

