当前位置:首页 > 技术 > 正文内容

ASP.NET MVC 全局异常处理与自定义错误页实现

访客 技术 2026年9月22日 12

在 ASP.NET MVC 应用中,统一捕获并展示用户友好的错误页面是提升健壮性和用户体验的关键环节。以下是一种基于全局事件与控制器路由的轻量级实现方案。

1. 利用 Application_Error 实现异常拦截

在 Global.asax.cs 的 Application_Error 方法中,可对未处理异常进行分类响应:

protected void Application_Error(object sender, EventArgs e)
{
    var lastEx = Server.GetLastError();
    if (lastEx == null) return;

    var httpEx = lastEx as HttpException;
    int statusCode = httpEx?.GetHttpCode() ?? 500;

    // 区分客户端错误与服务器内部错误
    switch (statusCode)
    {
        case 400:
        case 404:
            Response.Clear();
            Server.ClearError();
            Response.StatusCode = 404;
            Response.RedirectToRoute("ErrorRoute", new { code = "NotFound" });
            break;
        default:
            // 记录原始请求体(仅限调试,生产环境建议异步日志)
            string rawBody = string.Empty;
            try
            {
                Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
                using var reader = new System.IO.StreamReader(Request.InputStream, Request.ContentEncoding);
                rawBody = reader.ReadToEnd();
            }
            catch { /* 忽略流读取异常 */ }

            // 写入诊断日志(如 NLog、Serilog 或自定义日志器)
            // Logger.Error(lastEx, "Uncaught server error. Raw body: {RawBody}", rawBody.Substring(0, Math.Min(512, rawBody.Length)));

            Response.Clear();
            Server.ClearError();
            Response.StatusCode = 500;
            Response.RedirectToRoute("ErrorRoute", new { code = "ServerError" });
            break;
    }
}

2. 创建专用错误处理控制器

新建 ErrorController,支持按错误类型动态渲染视图:

public class ErrorController : Controller
{
    public ActionResult Display(string code)
    {
        ViewBag.ErrorType = code;
        ViewBag.Timestamp = DateTime.UtcNow.ToString("o");
        
        // 可选:根据 code 返回不同视图(如 NotFound.cshtml / ServerError.cshtml)
        return View("Display", (object)code);
    }
}

3. 配置专用路由规则

在 RouteConfig.cs 中注册显式错误路由,确保优先匹配,避免被默认路由覆盖:

routes.MapRoute(
    name: "ErrorRoute",
    url: "error/{code}",
    defaults: new { controller = "Error", action = "Display", code = UrlParameter.Optional },
    constraints: new { code = @"^(NotFound|ServerError)$" }
);

// 确保该路由在 Default 路由之前注册
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

4. 关闭 IIS/ASP.NET 默认错误页干预

在根目录 Web.config 的 <system.web> 节点下,禁用 customErrors,防止其劫持状态码:

<system.web>
  <customErrors mode="Off" />
</system.web>

同时,在 <system.webServer> 中确保 httpErrors 也设为 disabled(IIS 7+):

<system.webServer>
  <httpErrors existingResponse="PassThrough" />
</system.webServer>

5. 移除内置异常过滤器

注释或删除 FilterConfig.RegisterGlobalFilters 中的 HandleErrorAttribute,避免与手动异常处理逻辑冲突:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    // filters.Add(new HandleErrorAttribute()); // ← 禁用此行
}
标签: asp.net-mvc

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。