DotNet Core 2.1中私有setter属性无法被DataContractJsonSerializer序列化的问题
为什么DataContractJsonSerializer会忽略非公开Setter的属性?
你碰到的这个问题,核心是对SerializeReadOnlyTypes这个配置项的作用理解有偏差——它可不是用来处理属性Setter访问权限的哦!
先搞清楚SerializeReadOnlyTypes到底管什么
这个配置项的作用是允许序列化整个类型是“只读”的不可变对象,比如那些没有公共构造函数、所有属性都是只有Getter(没有Setter)的类型。但它完全不影响单个属性的Setter访问权限判断。
DataContractJsonSerializer的默认序列化规则
默认情况下,这个序列化器的逻辑很严格:
- 只有同时拥有公共Getter和公共Setter的属性,才会被自动纳入序列化范围;
- 当你把Setter改成private/internal时,序列化器会认为这个属性无法被反序列化(因为外部无法通过公共Setter赋值),所以干脆在序列化时也忽略它。
解决办法
如果想保留非公开Setter,同时让属性被正常序列化,最直接的方式是用[DataContract]和[DataMember]特性明确标记:
[DataContract] public class TestSubObject { [DataMember] public string Property { get; private set; } = "Bar"; }
只要属性被标记为[DataMember],不管Setter的访问权限是private还是internal,序列化器都会处理它(反序列化时如果需要private setter,只要类型有合适的构造函数或者允许反射访问,也能正常工作)。
如果你不想用DataContract特性,也可以自定义DataContractResolver来扩展序列化器的行为,但这种方式相对复杂,适合需要全局统一配置的场景。
额外对比:为什么JSON.NET能处理?
JSON.NET的默认规则更宽松,它默认只要属性的Getter是公共的就会序列化,而System.Runtime.Serialization.Json的设计更偏向于严格遵循“数据契约”的双向序列化要求(既要能序列化,也要能反序列化),所以才会默认排除非公开Setter的属性。
内容的提问来源于stack exchange,提问作者kipy
相关产品推荐
相关产品推荐

