.NET Core 6+中使用System.Text.Json反序列化时忽略JSON空值以保留模型默认值的方案咨询
嗨,我来帮你理清这个问题:
首先你说得完全没错——DefaultIgnoreCondition.WhenWritingNull这个选项确实只在序列化(把对象转成JSON)的时候生效,名字里的"WhenWriting"已经明确了它的作用场景,反序列化(把JSON转成对象)时它不会起任何作用,所以你用它的时候,JSON里的B: null还是会把模型里的默认值覆盖成null。
至于.NET 6+里替代过时的IgnoreNullValues的方案,其实官方已经提供了更精准的控制选项:
方案1:全局设置反序列化时忽略null值
在.NET 6及以后的版本中,JsonIgnoreCondition枚举新增了WhenReadingNull这个值,专门用来控制反序列化行为——当JSON中的属性值为null时,直接忽略这个属性,不会覆盖模型的默认值。你只需要把它配置到JsonSerializerOptions里就行:
var obj1 = System.Text.Json.JsonSerializer.Deserialize<Demo>(strJson, new JsonSerializerOptions() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenReadingNull }); // 此时obj1.B会保留默认值"Default value"
方案2:针对单个属性做精细控制
如果你不想全局生效,只想让特定属性忽略JSON中的null值,可以在属性上标记[JsonIgnore]特性,并指定Condition = JsonIgnoreCondition.WhenReadingNull:
public class Demo { public int A { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenReadingNull)] public string B { get; set; } = "Default value"; }
这样即使全局配置没改,这个B属性在反序列化时遇到JSON里的null也会保持默认值,其他属性不受影响。
关于官方的设计思路
你猜的很对,.NET团队的设计逻辑是:如果JSON中显式写出了某个属性为null,默认情况下应该尊重这个明确的赋值,把模型属性设为null;只有当JSON中完全没有这个属性时,才会保留模型的默认值。旧的IgnoreNullValues同时影响序列化和反序列化,灵活性不足,所以.NET 6拆分出了更细粒度的WhenWritingNull、WhenReadingNull等选项,让开发者可以分别控制读写JSON时的行为。
备注:内容来源于stack exchange,提问作者Shire

