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

.NET控制器统一异常处理问询:捕获特定异常返回BadRequest

.NET 全局捕获指定异常返回BadRequest的可行方案

下面是几种无需在每个端点重复编写try/catch的通用异常处理方案:

1. 基于基类控制器的OnException重写

创建一个基类控制器,所有需要统一处理异常的业务控制器继承它,在基类中重写OnException方法捕获指定异常:

public class BaseApiController : ControllerBase
{
    protected override void OnException(ExceptionContext context)
    {
        if (context.Exception is BadHttpRequestException badRequestEx)
        {
            // 返回自定义BadRequest响应
            context.Result = new BadRequestObjectResult(new 
            { 
                Message = "请求参数格式错误", 
                Detail = badRequestEx.Message 
            });
            context.ExceptionHandled = true; // 标记异常已处理,避免触发默认处理逻辑
        }
        else
        {
            // 其他异常交给框架默认处理
            base.OnException(context);
        }
    }
}

业务控制器直接继承该基类即可:

[ApiController]
[Route("api/[controller]")]
public class SampleController : BaseApiController
{
    [HttpGet("{id}")]
    public async Task<ActionResult<int>> GetById(int id)
    {
        id = FormatId(id);
        return await lookupId(id);
    }
}

2. 全局异常过滤器

实现IExceptionFilter接口创建全局过滤器,注册后对所有控制器端点生效:

定义过滤器

public class BadRequestExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        if (context.Exception is BadHttpRequestException badRequestEx)
        {
            context.Result = new BadRequestObjectResult(new 
            { 
                ErrorCode = "INVALID_ID_FORMAT", 
                Message = badRequestEx.Message 
            });
            context.ExceptionHandled = true;
        }
    }
}

注册过滤器

在Program.cs中添加过滤器到MVC配置:

builder.Services.AddControllers(options =>
{
    options.Filters.Add<BadRequestExceptionFilter>();
});

3. 全局异常处理中间件

中间件可以捕获整个请求管道中的异常,覆盖范围更广(包括非MVC类型的请求):

定义中间件

public class BadRequestExceptionMiddleware
{
    private readonly RequestDelegate _next;

    public BadRequestExceptionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (BadHttpRequestException ex)
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
            context.Response.ContentType = "application/json";
            
            var errorResponse = new 
            { 
                StatusCode = 400, 
                Message = "请求参数无效", 
                Detail = ex.Message 
            };
            
            await context.Response.WriteAsJsonAsync(errorResponse);
        }
    }
}

注册中间件

在Program.cs中添加中间件(注意顺序,需放在UseRouting之后、UseEndpoints之前):

app.UseMiddleware<BadRequestExceptionMiddleware>();

方案选择建议

  • 若仅需部分控制器统一处理异常,选基类控制器方案;
  • 若要对所有MVC端点生效,选全局异常过滤器;
  • 若需要覆盖整个请求管道的异常处理(如静态文件、自定义中间件中的异常),选中间件方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:22:41