.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
相关产品推荐
相关产品推荐

