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

.NET 4.8 WebAPI迁移至.NET 6:枚举JSON转换兼容问题求助

.NET 4.8 迁移至 .NET 6 枚举JSON兼容问题

问题场景

原.NET 4.8 Web API代码如下:

public enum SampleEnum
{
    Bar,
    Baz,
}
public class Jerry
{
    public SampleEnum MyEnum { get; set; }
}
public class ValuesController : ApiController
{
    // POST api/values
    public void Post([FromBody] Jerry value)
    {
        var a = value;
    }
}

当客户端传入包含无效枚举值的请求体时:

{  
   "MyEnum":  "MonthEnd"       
}

.NET 4.8会自动将MyEnum赋值为枚举的默认值Bar;但迁移到.NET 6后,无论使用System.Text.Json还是Newtonsoft.Json,都会抛出“无法识别枚举值”的异常。需要模拟旧版的兼容行为,避免客户端报错。

解决方案

方案1:适配System.Text.Json

自定义一个枚举转换器,遇到无法识别的枚举值时返回默认值:

public class TolerantEnumConverter<TEnum> : JsonConverter<TEnum> where TEnum : struct, Enum
{
    public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            var enumStr = reader.GetString();
            if (Enum.TryParse(enumStr, ignoreCase: true, out TEnum result))
            {
                return result;
            }
            // 无法识别时返回枚举默认值
            return default;
        }

        if (reader.TokenType == JsonTokenType.Number)
        {
            var numValue = reader.GetInt32();
            if (Enum.IsDefined(typeToConvert, numValue))
            {
                return (TEnum)Enum.ToObject(typeToConvert, numValue);
            }
            return default;
        }

        return default;
    }

    public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString());
    }
}

然后在Program.cs中全局注册转换器:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 针对单个枚举注册
        options.JsonSerializerOptions.Converters.Add(new TolerantEnumConverter<SampleEnum>());

        // 如果需要全局适配所有枚举(需.NET 7+或自行实现反射逻辑)
        // var enumTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsEnum);
        // foreach (var enumType in enumTypes)
        // {
        //     var converter = Activator.CreateInstance(typeof(TolerantEnumConverter<>).MakeGenericType(enumType));
        //     options.JsonSerializerOptions.Converters.Add((JsonConverter)converter);
        // }
    });

方案2:适配Newtonsoft.Json

Newtonsoft.Json提供了现成的配置项,只需开启UnknownEnumValueHandling.Default即可:

builder.Services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.Converters.Add(new StringEnumConverter
        {
            AllowIntegerValues = true,
            // 遇到未知枚举值时返回默认值
            UnknownEnumValueHandling = UnknownEnumValueHandling.Default
        });
        // 忽略未定义的字段,避免其他字段报错
        options.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
    });

注意:UnknownEnumValueHandling是Newtonsoft.Json 12.0.1及以上版本的属性,确保你的NuGet包版本符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:25:44