如何将空字符串传递给可空整数(nullable int)属性
解决JSON空字符串无法转换为Nullable的问题
这个坑我之前踩过好几次!你遇到的问题本质是:JSON里的空字符串""和null是完全不同的类型,而.NET默认的JSON序列化器(不管是System.Text.Json还是Json.NET)都不会自动把空字符串映射到int?的null值,所以才会抛出「JSON值无法转换为System.Nullable`1[System.Int32]」的错误。
下面给你几个实用的解决方案,按需选择:
方案1:修改前端传值(最简单直接)
直接让前端把空字符串改成null,也就是把请求里的codigoBanco: ""改成codigoBanco: null。这样序列化器能直接识别成int?的null,不需要后端做任何修改。
方案2:后端自定义JSON转换器(适合无法修改前端的场景)
如果前端没法改,那就在后端写个自定义转换器,让序列化器知道怎么把空字符串转成int?的null。
针对System.Text.Json(.NET Core 3.0+默认)
先写转换器类:
public class NullableIntConverter : JsonConverter<int?> { public override int? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 处理空字符串的情况 if (reader.TokenType == JsonTokenType.String) { string? value = reader.GetString(); if (string.IsNullOrWhiteSpace(value)) return null; // 尝试把非空字符串转成int if (int.TryParse(value, out int result)) return result; } // 处理正常数字的情况 else if (reader.TokenType == JsonTokenType.Number) { return reader.GetInt32(); } // 其他情况返回null return null; } public override void Write(Utf8JsonWriter writer, int? value, JsonSerializerOptions options) { // 序列化时,有值就写数字,没值就写null if (value.HasValue) writer.WriteNumberValue(value.Value); else writer.WriteNullValue(); } }
然后有两种方式使用这个转换器:
- 局部使用:在属性上加特性
[JsonConverter(typeof(NullableIntConverter))] public int? CodigoBanco { get; set; } - 全局使用:在Program.cs/Startup.cs里注册,对所有
int?生效builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new NullableIntConverter()); });
针对Newtonsoft.Json(Json.NET)
如果你的项目用的是Json.NET,转换器写法类似:
public class NullableIntConverter : JsonConverter<int?> { public override int? ReadJson(JsonReader reader, Type objectType, int? existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.Value is string str) { if (string.IsNullOrWhiteSpace(str)) return null; if (int.TryParse(str, out int result)) return result; } else if (reader.Value is int num) { return num; } return null; } public override void WriteJson(JsonWriter writer, int? value, JsonSerializer serializer) { if (value.HasValue) writer.WriteValue(value.Value); else writer.WriteNull(); } }
使用方式同样分局部和全局:
- 局部:
[JsonConverter(typeof(NullableIntConverter))] public int? CodigoBanco { get; set; } - 全局:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.Converters.Add(new NullableIntConverter()); });
补充说明
为啥默认会报错?因为.NET的JSON序列化器遵循严格的类型匹配:JSON的""是字符串类型,而int?要么是null要么是整数,类型不匹配自然就会抛出转换错误。自定义转换器就是帮序列化器补上这个“空字符串转null”的逻辑。
内容的提问来源于stack exchange,提问作者Heitor Giacomini




