如何配置Newtonsoft JsonSerializer,使非可空字符串为null时反序列化失败?
解决Newtonsoft.Json非可空字段遇Null静默赋值的问题
要实现全局配置序列化器,让所有非可空字段遇到null值时反序列化直接失败,无需给单个字段添加装饰器,可以通过自定义ContractResolver来实现:
1. 自定义契约解析器
创建一个继承自DefaultContractResolver的类,重写CreateProperty方法,对所有非可空属性强制设置Required.DisallowNull,这样当JSON中对应字段为null时会触发序列化异常:
public class NonNullableRequiredContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); Type propertyType = property.PropertyType; // 判断属性是否为非可空类型 bool isNonNullable = !IsNullableType(propertyType); if (isNonNullable) { // 禁止字段值为null property.Required = Required.DisallowNull; } return property; } private bool IsNullableType(Type type) { // 处理可空值类型(Nullable<T>) if (Nullable.GetUnderlyingType(type) != null) { return true; } // 处理.NET 6+的可空引用类型 var nullableAttr = type.CustomAttributes.FirstOrDefault(a => a.AttributeType == typeof(NullableAttribute)); if (nullableAttr != null) { var argValue = nullableAttr.ConstructorArguments.FirstOrDefault().Value as byte?; return argValue == 0; } // 未标记可空的引用类型视为非可空 return false; } }
2. 配置序列化器并使用
在反序列化时,将自定义的契约解析器赋值给序列化器的ContractResolver属性,同时保留你原有的MissingMemberHandling.Error配置:
using JsonTextReader reader = new JsonTextReader(file); var serializer = new Newtonsoft.Json.JsonSerializer(); serializer.MissingMemberHandling = MissingMemberHandling.Error; // 应用自定义契约解析器 serializer.ContractResolver = new NonNullableRequiredContractResolver(); try { return serializer.Deserialize<Collection<ContainerClass>>(reader); } catch (JsonSerializationException ex) { // 按需处理反序列化失败的异常 throw new InvalidOperationException("非可空字段不能为null", ex); }
效果说明
配置完成后,当JSON中出现非可空字段为null的情况时,序列化器会直接抛出JsonSerializationException,不再静默将null赋值给非可空字段,完全符合预期。
内容的提问来源于stack exchange,提问作者jeancallisti
相关产品推荐
相关产品推荐

