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

如何自定义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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 20:38:21