ASP.NET Core自定义JsonConverter输入非法时抛什么异常返回400而非500
核心原理说明
ASP.NET Core默认会将JSON反序列化阶段抛出的普通Exception识别为服务端未处理异常,所以返回500状态码;只有特定的序列化相关异常会被判定为客户端输入错误,归类为模型验证失败,自动返回400状态码。
方案1:替换抛出的异常类型(最简实现)
你只需要把代码中抛出的普通Exception替换为对应序列化组件的专属异常即可:
适配System.Text.Json(ASP.NET Core默认序列化组件)
修改后的转换器代码如下:
int[] parts = value.Split(':', StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x, CultureInfo.InvariantCulture)).ToArray(); if (parts.Length != 3) throw new System.Text.Json.JsonException($"值{value}不是TimeSpan的合法值"); return new TimeSpan(parts[0] / 24, parts[0] % 24, parts[1], parts[2]);
适配Newtonsoft.Json
如果项目用Newtonsoft.Json作为序列化组件,替换抛出Newtonsoft.Json.JsonSerializationException即可。
默认配置下,标注了[ApiController]特性的控制器会自动捕获这类序列化异常,作为模型验证错误返回400状态码,响应内容会自动携带你设置的错误提示。
方案2:自定义400响应格式(可选)
如果你需要统一控制所有模型验证失败的返回格式,可以在Program.cs中配置ApiBehaviorOptions:
builder.Services.AddControllers() .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { var errorList = context.ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); return new BadRequestObjectResult(new { Code = 400, Message = "请求参数不合法", ErrorDetails = errorList }); }; });
配置后所有模型验证失败场景(包括自定义转换器抛出的序列化异常)都会按照你定义的格式返回400响应。
注意事项
- 确保控制器类标注了
[ApiController]特性,该特性默认启用了自动模型验证和错误响应处理。 - 如果你自定义了全局异常过滤器,需要确认没有把JSON序列化相关的异常拦截后统一返回500,若有可以加判断逻辑将这类异常按400处理。
内容的提问来源于stack exchange,提问作者Homayoun Behzadian
相关产品推荐
相关产品推荐

