You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7中如何正确处理JSON反序列化中空字符串与对象混合的问题?

解决ASP.NET Core Web API中空字符串转null/默认值的JSON解析问题

问题背景

升级ASP.NET Core Web API时,遇到调用方将空对象/值以""(空字符串)形式发送的情况,且对方不修改格式。例如:

{
    "user": "",
    "subscription": {
        "id": 123456789,
        "origin": "",
        "verlenging": true
    },
    "voucher": {
        "name": "",
        "id": 0
    },
    "webLinkId": ""
}

当user字段是正常对象、webLinkId是数值时也需要正常解析,目前报错:

The JSON value could not be converted to ...

以下是可行的解决办法:


1. 自定义JSON转换器处理引用类型(如User对象)

针对引用类型,将空字符串转换为null,正常对象则正常反序列化:

public class EmptyStringToNullConverter<T> : JsonConverter<T> where T : class
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String && string.IsNullOrEmpty(reader.GetString()))
        {
            return null;
        }
        return JsonSerializer.Deserialize<T>(ref reader, options);
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        JsonSerializer.Serialize(writer, value, options);
    }
}

2. 自定义转换器处理值类型(如int、DateTime)

非可空int(空字符串转0)

public class EmptyStringToDefaultIntConverter : JsonConverter<int>
{
    public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            var str = reader.GetString();
            if (string.IsNullOrEmpty(str)) return 0;
            return int.TryParse(str, out var result) ? result : throw new JsonException("无法转换为int类型");
        }
        else if (reader.TokenType == JsonTokenType.Number)
        {
            return reader.GetInt32();
        }
        throw new JsonException("无法将JSON值转换为int类型");
    }

    public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
    {
        writer.WriteNumberValue(value);
    }
}

可空DateTime(空字符串转null)

public class EmptyStringToNullableDateTimeConverter : JsonConverter<DateTime?>
{
    public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            var str = reader.GetString();
            if (string.IsNullOrEmpty(str)) return null;
            return DateTime.TryParse(str, out var result) ? result : null;
        }
        else if (reader.TokenType == JsonTokenType.String)
        {
            return reader.GetDateTime();
        }
        return null;
    }

    public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
    {
        if (value.HasValue)
            writer.WriteStringValue(value.Value);
        else
            writer.WriteNullValue();
    }
}

3. 应用转换器

方式一:单个模型属性标记

在请求模型的目标属性上添加转换器特性:

public class RequestModel
{
    [JsonConverter(typeof(EmptyStringToNullConverter<User>))]
    public User User { get; set; }

    public Subscription Subscription { get; set; }

    public Voucher Voucher { get; set; }

    [JsonConverter(typeof(EmptyStringToDefaultIntConverter))]
    public int WebLinkId { get; set; }
}

public class User
{
    public bool IsDomi { get; set; }
    public bool IsStudent { get; set; }
    // 其他属性...
    [JsonConverter(typeof(EmptyStringToNullableDateTimeConverter))]
    public DateTime? Birthday { get; set; }
}

方式二:全局注册(所有模型生效)

在Program.cs中配置全局JSON序列化选项:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new EmptyStringToNullConverter<User>());
        options.JsonSerializerOptions.Converters.Add(new EmptyStringToDefaultIntConverter());
        options.JsonSerializerOptions.Converters.Add(new EmptyStringToNullableDateTimeConverter());
    });

注意事项

  • 根据实际需求扩展转换器,比如枚举、decimal等类型的处理;
  • 测试边界场景:空字符串、正常数值、正常对象、null值等;
  • 若使用Newtonsoft.Json而非System.Text.Json,只需调整转换器继承的基类为Newtonsoft的对应类型。

内容的提问来源于stack exchange,提问作者ItsProbablySomethingStupid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 09:25:35