.Net Core MVC如何重写OnException实现异常过滤器统一错误处理
自定义异常过滤器实现方案
你可以按照以下逻辑重写OnException方法,完全替代Action内重复的try-catch错误处理逻辑:
核心实现逻辑
- 优先判断异常是否已被其他逻辑处理,避免重复执行错误响应
- 区分运行环境,开发环境返回完整异常信息方便排查,生产环境隐藏敏感错误详情
- 实例化你预先定义的错误模型,填充请求ID、请求路径、异常信息等字段
- 替换请求返回结果为错误视图,传入填充完成的错误模型
- 标记异常为已处理状态,设置对应HTTP状态码
具体代码实现
首先定义自定义异常过滤器,如果你需要把过滤器作为特性标记到单独的Controller/Action上,就继承ExceptionFilterAttribute,如果只做全局过滤器,实现IExceptionFilter接口即可:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.ModelBinding; public class GlobalExceptionFilter : ExceptionFilterAttribute { private readonly IWebHostEnvironment _webHostEnv; // 注入运行环境,用于区分开发/生产环境 public GlobalExceptionFilter(IWebHostEnvironment webHostEnv) { _webHostEnv = webHostEnv; } public override void OnException(ExceptionContext context) { // 异常已被处理则直接跳过 if (context.ExceptionHandled) { return; } // 填充你定义好的错误模型,这里假设你的错误模型类名为ErrorViewModel var errorInfo = new ErrorViewModel { RequestId = context.HttpContext.TraceIdentifier, RequestPath = context.HttpContext.Request.Path, // 开发环境返回真实异常信息,生产环境返回通用提示 ErrorMsg = _webHostEnv.IsDevelopment() ? context.Exception.Message : "服务繁忙,请稍后再试", // 开发环境返回堆栈信息方便排查,生产环境置空避免泄露敏感信息 StackTrace = _webHostEnv.IsDevelopment() ? context.Exception.StackTrace : string.Empty }; // 构造视图返回结果,替换原有异常响应 context.Result = new ViewResult { // 替换为你实际开发的错误视图路径 ViewName = "~/Views/Shared/Error.cshtml", ViewData = new ViewDataDictionary<ErrorViewModel>(new EmptyModelMetadataProvider(), context.ModelState) { Model = errorInfo } }; // 设置响应状态码为500服务端错误 context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError; // 标记异常已处理,阻止后续异常处理逻辑触发 context.ExceptionHandled = true; } }
过滤器注册
如果需要全局生效(覆盖所有Action请求,完全替代你原来每个Action写的try-catch),在Program.cs中注册为全局过滤器即可:
builder.Services.AddControllersWithViews(opt => { opt.Filters.Add<GlobalExceptionFilter>(); });
如果只需要给特定Controller或Action生效,直接在对应类/方法上标记[GlobalExceptionFilter]特性即可。
注意事项
- 生产环境务必屏蔽完整异常信息、堆栈内容,避免泄露代码结构、数据库连接串等敏感信息
- 如果项目同时包含MVC视图接口和WebApi接口,可以在方法内增加请求类型判断:Ajax/Api请求返回JSON格式错误结果,视图请求返回错误页,避免前端收到HTML内容解析异常
- 可以在异常处理逻辑中增加日志埋点,将异常信息写入日志系统方便后续排查问题
内容的提问来源于stack exchange,提问作者ogiyavuz
相关产品推荐
相关产品推荐

