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
相关产品推荐
相关产品推荐

