如何自定义JSON反序列化异常导致模型绑定失败的错误返回信息?
解决JSON反序列化错误的自定义响应问题
你遇到的问题是因为JSON反序列化失败属于模型绑定阶段的验证错误,而非未处理的异常,所以IExceptionFilter和普通中间件无法捕获——ASP.NET Core框架会自动将这类错误收集到ModelState中,并返回默认的400响应。要替换成自定义错误,需要从ModelState的处理入手,以下是两种简单可行的方案:
方案一:配置InvalidModelStateResponseFactory(推荐)
直接在控制器配置中替换默认的ModelState响应生成逻辑,代码改动最小:
services.AddControllers(options => { options.Filters.Add(new ApiErrorFilter()); // 替换默认的ModelState错误响应 options.InvalidModelStateResponseFactory = context => { // 构建自定义错误结构 var customError = new { StatusCode = StatusCodes.Status400BadRequest, Message = "请求格式错误,请检查输入的JSON数据类型与格式", Errors = context.ModelState.Values .SelectMany(v => v.Errors) .Select(e => { // 过滤敏感的内部类型信息,替换为通用提示 if (e.ErrorMessage.Contains("could not be converted to")) { return "字段数据类型不匹配,请检查输入值"; } return string.IsNullOrEmpty(e.ErrorMessage) ? "输入格式错误" : e.ErrorMessage; }) .ToList() }; return new JsonResult(customError) { StatusCode = StatusCodes.Status400BadRequest }; }; }) .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); options.JsonSerializerOptions.Converters.Add(new Core.Infrastructure.DateTimeConverter()); });
方案二:自定义Action过滤器
实现IAsyncActionFilter来拦截ModelState验证失败的请求,灵活性更高:
public class CustomModelValidationFilter : IAsyncActionFilter { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!context.ModelState.IsValid) { var errorList = context.ModelState.Values .SelectMany(v => v.Errors) .Select(e => { if (e.ErrorMessage.Contains("could not be converted to")) { return "JSON数据类型不符合要求,请检查字段类型"; } return string.IsNullOrEmpty(e.ErrorMessage) ? "请求参数验证失败" : e.ErrorMessage; }) .ToList(); var customResponse = new { Status = 400, Message = "请求参数无效", ErrorDetails = errorList }; context.Result = new JsonResult(customResponse) { StatusCode = StatusCodes.Status400BadRequest }; return; } // 验证通过,继续执行后续管道 await next(); } }
然后在控制器配置中添加这个过滤器:
services.AddControllers(options => { options.Filters.Add(new ApiErrorFilter()); options.Filters.Add<CustomModelValidationFilter>(); // 添加自定义过滤器 }) // ... 保留原有JsonOptions配置
关键说明
- JSON反序列化错误不会抛出未处理异常,而是被框架转化为
ModelState的验证错误,因此无法通过异常过滤器或普通中间件捕获。 - 两种方案都可以过滤掉响应中的内部类型信息(如
TestingService.Business.Features.V1.Test.Models.Answer[]),避免泄露业务代码结构,解决安全问题。
内容的提问来源于stack exchange,提问作者JamesBondCaesar
相关产品推荐
相关产品推荐

