如何覆盖.NET Core默认JsonSerializer或捕获序列化异常
解决方案
问题原因
你遇到的这类类型转换错误属于JSON反序列化阶段抛出的异常,发生在常规模型验证流程之前,所以你实现的IValidationMetadataProvider无法捕获到这类错误。
方案1:自定义JsonConverter捕获类型转换异常
如果你使用.NET Core 3.0+默认的System.Text.Json序列化器,可以针对特定类型编写自定义转换器,在转换失败时抛出自定义提示:
// 示例:针对string类型的自定义转换器 public class CustomStringConverter : JsonConverter<string> { public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { try { return reader.GetString(); } catch (JsonException) { throw new JsonException($"值不正确,要求类型为{typeToConvert.Name}"); } } public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { writer.WriteStringValue(value); } }
在Program.cs(或Startup.cs)中注册转换器即可生效:
builder.Services.AddControllers() .AddJsonOptions(options => { // 可添加多个不同类型的自定义转换器 options.JsonSerializerOptions.Converters.Add(new CustomStringConverter()); });
方案2:全局重写验证错误返回逻辑
如果不想逐个编写类型转换器,可以直接修改ApiBehaviorOptions的响应工厂,统一替换所有类型转换错误的提示:
builder.Services.Configure<ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = context => { var errorList = new List<object>(); foreach (var (field, state) in context.ModelState) { var errorMsgs = state.Errors.Select(e => { // 匹配系统默认的类型转换错误提示 if (e.ErrorMessage.StartsWith("The JSON value could not be converted to")) { // 提取要求的目标类型 var typeName = e.ErrorMessage.Split("to System.")[1].Split('.')[0]; return $"值不正确,要求类型为{typeName}"; } return e.ErrorMessage; }).ToList(); errorList.Add(new { filedName = field, validateErrors = errorMsgs }); } return new BadRequestObjectResult(new { status = 400, message = "Validation error", data = errorList }); }; });
该方案无需修改序列化逻辑,适配所有类型的转换错误场景,改造成本最低。
内容的提问来源于stack exchange,提问作者Nexicolt
相关产品推荐
相关产品推荐

