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

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);
    }
}

代码说明

  1. 拆分JSON数组:先将原始JSON反序列化为JsonElement[],把数组拆分为独立的对象节点,避免单个错误导致整个数组解析失败;
  2. 逐个反序列化:遍历每个节点,用try-catch包裹单个对象的反序列化逻辑,成功则加入有效列表,失败则记录错误;
  3. 错误追踪:通过element.GetRawText()获取错误对象的原始JSON,结合异常信息记录,方便后续排查问题。

运行后会输出4个有效对象,同时记录第三个对象的解析错误,完全满足需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:07:26