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

Minimal API生产环境下无效JSON请求无法自定义异常处理的问题

原因分析

ASP.NET Core在生产环境下,默认通过ApiBehaviorOptions自动拦截模型绑定/JSON解析类错误(比如你遇到的无效JSON),直接返回标准化的400响应,不会将这类异常传递到你注册的UseExceptionHandler全局异常处理器中。而开发环境为了便于调试,会跳过这个自动拦截,让异常能被全局处理器捕获,所以你能看到自定义的响应内容。

解决方法

以下几种方式可以让你在生产环境中控制无效JSON输入的响应:

1. 禁用默认的模型状态无效过滤器

通过配置ApiBehaviorOptions关闭自动拦截,让模型绑定错误流入全局异常处理器:

var builder = WebApplication.CreateBuilder(args);

// 添加配置禁用默认过滤器
builder.Services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressModelStateInvalidFilter = true;
});

var app = builder.Build();

// 你的全局异常处理器代码保持不变
app.UseExceptionHandler((exceptionApp) =>
{
    exceptionApp.Run(async context =>
    {
        context.Response.ContentType = MediaTypeNames.Text.Plain;

        var feature = context.Features.Get<IExceptionHandlerPathFeature>();
        if (feature?.Error is BadHttpRequestException ex)
        {
            context.Response.StatusCode = 400;
            var message = (ex.InnerException is JsonException) 
                ? "The request body is an invalid JSON" 
                : "Bad Request";
            await context.Response.WriteAsync(message);
        }
        else
        {
            context.Response.StatusCode = 500;
            await context.Response.WriteAsync("There is a problem occured");
        }
    });
});

app.MapPost("/models", (Model model) => Results.Created(string.Empty, model));

app.Run();

2. 自定义模型状态错误响应

如果不想完全禁用默认拦截,可以直接定制模型状态错误的返回内容,更精准地处理JSON解析错误:

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<ApiBehaviorOptions>(options =>
{
    options.InvalidModelStateResponseFactory = context =>
    {
        // 检查是否存在JSON解析异常
        var jsonException = context.ModelState.Values
            .SelectMany(v => v.Errors)
            .Select(e => e.Exception)
            .OfType<JsonException>()
            .FirstOrDefault();

        if (jsonException != null)
        {
            return Results.Text(
                "The request body is an invalid JSON",
                statusCode: 400,
                contentType: MediaTypeNames.Text.Plain);
        }

        // 其他模型绑定错误返回默认的BadRequest响应
        return Results.BadRequest(context.ModelState);
    };
});

var app = builder.Build();

// 全局异常处理器仍可处理其他非模型绑定类异常
app.UseExceptionHandler(...);

app.MapPost("/models", (Model model) => Results.Created(string.Empty, model));

app.Run();

3. 提前捕获JSON解析异常

注册一个前置中间件,直接捕获JSON解析阶段抛出的BadHttpRequestException,确保在生产环境下能拦截到:

var app = builder.Build();

// 这个中间件要放在路由映射和异常处理器之前
app.Use(async (context, next) =>
{
    try
    {
        await next();
    }
    catch (BadHttpRequestException ex)
    {
        context.Response.ContentType = MediaTypeNames.Text.Plain;
        context.Response.StatusCode = 400;
        var message = (ex.InnerException is JsonException) 
            ? "The request body is an invalid JSON" 
            : "Bad Request";
        await context.Response.WriteAsync(message);
    }
});

app.UseExceptionHandler(...); // 保留处理其他异常

app.MapPost("/models", (Model model) => Results.Created(string.Empty, model));

app.Run();

内容的提问来源于stack exchange,提问作者Farzan Hajian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 08:42:26