如何在JSON属性为null时为C#对象属性设置默认值?
解决System.Text.Json反序列化时Null转非可空值类型的异常问题
针对你遇到的JSON中null对应DTO非可空值类型导致的反序列化异常,以下是几种无需逐个属性添加特性的全局解决方案:
方案一:.NET 6+ 直接使用JsonNumberHandling配置
从.NET 6开始,System.Text.Json提供了JsonNumberHandling.AllowNull选项,可直接将JSON中的null数值反序列化为对应值类型的默认值(比如int默认0),无需自定义转换器:
var serializerOptions = new JsonSerializerOptions { // 必须开启,匹配JSON小写属性名与DTO的PascalCase属性名 PropertyNameCaseInsensitive = true, // 允许null反序列化为数值类型的默认值 NumberHandling = JsonNumberHandling.AllowNull }; // 调用时传入配置 var result = await httpClient.GetFromJsonAsync<ComplexClass>("your-api-endpoint", serializerOptions);
注意:该配置仅针对数值类型(int、long、double等),如果需要处理bool、DateTime等值类型的null,需使用方案二。
方案二:自定义通用值类型转换器
编写一个通用转换器,覆盖所有值类型,遇到JSONnull时返回对应类型的默认值,全局生效:
public class NullToDefaultValueConverter<T> : JsonConverter<T> where T : struct { public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.TokenType == JsonTokenType.Null ? default : JsonSerializer.Deserialize<T>(ref reader, options); } public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, options); } }
然后在配置中注册需要处理的值类型转换器:
var serializerOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, Converters = { new NullToDefaultValueConverter<int>(), new NullToDefaultValueConverter<long>(), new NullToDefaultValueConverter<bool>(), new NullToDefaultValueConverter<DateTime>() // 添加其他需要处理的值类型 } }; var result = await httpClient.GetFromJsonAsync<ComplexClass>("your-api-endpoint", serializerOptions);
方案三:从DTO生成阶段解决
既然你使用JsonToC#网站生成DTO,可以在生成时勾选**"Make properties nullable"**(类似选项),让可能为null的属性直接生成可空值类型(比如int? Quantity),从源头避免类型不匹配问题。
内容的提问来源于stack exchange,提问作者Navid_pdp11
相关产品推荐
相关产品推荐

