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

C#使用JsonConvert反序列化多层嵌套JSON得到空集合问题排查

C# Json.NET 嵌套JSON反序列化空集合问题解决方案

不需要手动遍历逐个解析赋值,修正类定义规则后可直接通过反序列化得到完整的嵌套对象集合

现有代码核心错误点

  • 所有标记[JsonProperty]的属性均无set访问器,Json.NET默认无法向只读属性写入反序列化得到的值,你定义的只读属性直接返回未赋值的私有字段,最终只能拿到空集合。
  • 所有业务类(Info、IntOptions、BubbleList、SubBubbleList)仅定义了带参数的构造函数,无无参构造函数,Json.NET默认优先调用无参构造初始化对象,找不到匹配构造时无法正确实例化嵌套对象。
  • 类内部的私有后备字段(如_param、_intOptions、_bubbleList、_subBubbleList)未加序列化标记,反序列化过程不会为这些私有字段赋值,后续通过属性访问时拿到的始终是初始化时的空列表。

可直接运行的修正方案

调整类定义适配Json.NET的反序列化规则即可,反序列化调用逻辑无需修改。

修正后类定义

public class ParamList
{
    [JsonProperty("Parameters")]
    public List<Param> Parameters { get; private set; } = new();
}

public class Param
{
    [JsonProperty("Info")]
    public Info? Info { get; private set; }

    [JsonProperty("IntOptions")]
    public List<IntOptions> IntOptions { get; private set; } = new();

    [JsonProperty("BubbleList")]
    public List<BubbleList> BubbleList { get; private set; } = new();
}

public class Info
{
    // 无参构造供反序列化初始化使用
    public Info() {}
    public Info(int id, string number)
    {
        Id = id;
        Number = number;
    }

    [JsonProperty("Id")]
    public int Id { get; private set; }

    [JsonProperty("No")]
    public string Number { get; private set; } = string.Empty;
}

public class IntOptions
{
    public IntOptions() {}
    public IntOptions(int value, string valInfo)
    {
        Value = value;
        ValInfo = valInfo;
    }

    [JsonProperty("Value")]
    public int Value { get; private set; }

    [JsonProperty("ValInfo")]
    public string ValInfo { get; private set; } = string.Empty;
}

public class BubbleList
{
    public BubbleList() {}
    public BubbleList(int position)
    {
        Position = position;
    }

    [JsonProperty("Position")]
    public int Position { get; private set; }

    [JsonProperty("SubBubbleList")]
    public List<SubBubbleList> SubBubbleList { get; private set; } = new();
}

public class SubBubbleList
{
    public SubBubbleList() {}
    public SubBubbleList(int value, string message)
    {
        Value = value;
        Message = message;
    }

    [JsonProperty("Value")]
    public int Value { get; private set; }

    [JsonProperty("Message")]
    public string Message { get; private set; } = string.Empty;
}

保留只读集合封装的可选写法

如果你需要对外暴露IReadOnlyCollection避免外部修改集合,可以直接将[JsonProperty]标记加在私有后备字段上,反序列化会直接填充私有字段,对外依然保持只读逻辑,示例写法:

public class Param
{
    [JsonProperty("Info")]
    public Info? Info { get; private set; }

    [JsonProperty("IntOptions")]
    private List<IntOptions> _intOptions = new();
    public IReadOnlyCollection<IntOptions> IntOptionsVar => _intOptions.AsReadOnly();

    [JsonProperty("BubbleList")]
    private List<BubbleList> _bubbleList = new();
    public IReadOnlyCollection<BubbleList> BubbleListVar => _bubbleList.AsReadOnly();
}

修正后直接执行原有反序列化代码,即可拿到包含Info对象、IntOptions列表、BubbleList(内含SubBubbleList子列表)的完整Param集合,无需手动遍历赋值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:42:17