You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将空字符串传递给可空整数(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

火山引擎 最新活动