UseExceptionHandler捕获中间件管道未处理异常,IExceptionFilter仅处理MVC层Action内异常;两者可共存,前者兜底后者细粒度定制。

ASP.NET Core 里 UseExceptionHandler 和 IExceptionFilter 到底该用哪个
控制器报错捕获,不是“加个过滤器就行”,得看错误发生在哪一层。UseExceptionHandler 捕的是中间件管道里未处理的异常(包括控制器抛出但没被 catch 的),而 IExceptionFilter 只管 MVC 层——也就是 Controller 执行过程中、进入 Action 之后、返回结果之前这段。如果异常发生在模型绑定、授权过滤器或自定义中间件里,IExceptionFilter 根本收不到。
-
UseExceptionHandler是兜底方案,适合统一返回错误页或 JSON 错误响应,但拿不到ActionContext,没法做细粒度响应定制(比如按不同 Controller 返回不同结构) -
IExceptionFilter能访问ExceptionContext和当前 action 信息,适合记录日志、补充上下文、局部响应覆盖,但对400 Bad Request(如模型验证失败)这类非异常流程无效 - 两者可以共存:先由
IExceptionFilter处理可预判的业务异常,再靠UseExceptionHandler拦住漏网的运行时崩溃
OnException 里为什么 context.Result 设了却没生效
常见现象:在 OnException 方法里写了 context.Result = new JsonResult(...),但浏览器还是看到默认黄页或空响应。根本原因是没调 context.ExceptionHandled = true —— ASP.NET Core 默认认为你只是“看了眼异常”,还要继续往上抛。
- 必须显式设
context.ExceptionHandled = true,否则后续中间件(包括UseExceptionHandler)仍会介入 - 不要在
OnException里 throw 新异常,这会导致二次崩溃,且可能绕过你刚设的Result - 如果用了
[ApiController]特性,部分异常(如ModelStateInvalid)根本不会触发IExceptionFilter,它走的是内置的InvalidModelStateResponseFactory
全局过滤器注册时 AddControllers 和 AddMvc 的区别
项目模板不同,API 和 MVC 混用时容易配错入口。.NET 6+ 推荐用 AddControllers,它只注册控制器相关服务;而 AddMvc 还带视图引擎、Razor Pages 等一堆你可能不需要的东西,体积大、启动慢,且在纯 API 项目里反而可能引入意外行为(比如试图解析 .cshtml)。
- 纯 Web API 项目:用
services.AddControllers().AddControllersAsServices(),再链式调AddExceptionFilter<myglobalfilter>()</myglobalfilter> - 需要 Razor Pages 或视图:才用
AddMvc,但记得通过ConfigureServices显式关闭不需要的组件(如options.EnableEndpointRouting = false已废弃,别抄旧教程) - 过滤器作用域要对:全局过滤器必须注册在
ConfigureServices里,写在Configure的UseMiddleware之后是无效的
UseExceptionHandler 配置路径时 404 不走自定义页面
设了 app.UseExceptionHandler("/error"),但访问一个不存在的路由(比如 /api/xxx)返回 404,却没跳到你的 /error 页面。这是因为 UseExceptionHandler 只捕获“已进入管道但中途崩掉”的请求,而 404 是 Endpoint Routing 在匹配失败后直接生成的响应,根本没抛异常。
- 想统一处理 404,得单独配
UseStatusCodePagesWithReExecute("/error?statusCode={0}"),并在 Controller 里判断HttpContext.Response.StatusCode -
/error路由对应的 Controller Action 必须允许匿名访问(加[AllowAnonymous]),否则 401/403 也会卡在这里 - 不要在
/errorAction 里再抛异常,否则陷入死循环——ASP.NET Core 不会二次进UseExceptionHandler


















