.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
相关产品推荐
相关产品推荐

