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

.NET 8中为何无法反序列化带List<T>属性的对象?

System.Text.Json反序列化含List属性对象失败的原因与修复方案

问题根源

你的代码中,Parent类的Children属性只有get访问器,没有set访问器:

public List<Child> Children { get; } = new List<Child>();

System.Text.Json默认规则是:反序列化时需要属性具备可写能力(即存在setter),才能将JSON中的数据赋值到属性上。

直接反序列化List<Child>能成功,是因为序列化器会直接创建List<T>实例并填充数据;但反序列化Parent对象时,虽然属性初始化了一个空列表,序列化器却无法向这个只读属性对应的列表中添加数据——它既不能创建新列表赋值(没有setter),也默认不会修改已存在的集合实例。

另外,Child类的带参构造函数不影响这个问题(.NET 5+的System.Text.Json默认支持构造函数绑定,所以直接反序列化List<Child>可行)。


修复方案

方案1:给属性添加私有setter

保留外部只读的语义,同时让序列化器能通过反射访问私有setter来赋值:

public class Parent
{
    public List<Child> Children { get; private set; } = new List<Child>();
}

这种方式最简单,不需要修改序列化配置。

方案2:使用序列化配置允许修改只读集合

如果想完全保留属性的只读特性(不添加任何setter),可以配置JsonSerializerOptions让序列化器直接修改已初始化的集合实例:

// 配置序列化选项
var options = new JsonSerializerOptions
{
    AllowReadOnlyProperties = true,
    PropertyNameCaseInsensitive = true // 可选,增强兼容性
};

// 反序列化时传入配置
var deserializedParent = JsonSerializer.Deserialize<Parent>(parentJson, options);

Parent类保持原有代码不变即可,序列化器会自动把JSON中的Children数组元素添加到已初始化的空列表中。


验证效果

修改后重新运行测试,反序列化后的Parent对象Children属性会正确包含Child A和Child B,断言parentJson == parentJson2将成功通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:33:23