ASP.NET MVC中注册Global.asax的Application_Error事件处理全局异常

来源:互联网 发布:有鬼吗 知乎 编辑:程序博客网 时间:2024/05/04 02:16

在ASP.NET MVC中,通过应用程序生命周期中的Application_Error事件可以捕获到网站引发的所有未处理异常。本文作为学习笔记,记录了使用Global.asax文件的Application_Error事件处理和捕获全局异常的详细步骤。

文章演示项目是使用vs2013编译器编写的,下载地址:GlobalExceptionHandle-By-Application_Error.zip。

ASP.NET MVC全局异常范例项目结构

在VS2013中新建一个MVC项目,这里要先关闭自定义错误,将Web.config配置文件中customErrors节点的mode设置为Off,注意大小写:

  <system.web>        <customErrors mode="Off"></customErrors>    <compilation debug="true" targetFramework="4.5"/>    <httpRuntime targetFramework="4.5"/>  </system.web>

在GlobalFilter全局过滤器中取消HandleErrorAttribute的注册:

public class FilterConfig{    public static void RegisterGlobalFilters(GlobalFilterCollection filters)    {        //filters.Add(new HandleErrorAttribute());    }}

打开Global.asax文件并添加Application_Error事件代码:

protected void Application_Error(Object sender, EventArgs e){    Exception lastError = Server.GetLastError();    if (lastError != null)    {        //异常信息        string strExceptionMessage = string.Empty;        //对HTTP 404做额外处理,其他错误全部当成500服务器错误        HttpException httpError = lastError as HttpException;        if (httpError != null)        {            //获取错误代码            int httpCode = httpError.GetHttpCode();            strExceptionMessage = httpError.Message;            if (httpCode == 400 || httpCode == 404)            {                Response.StatusCode = 404;                //跳转到指定的静态404信息页面,根据需求自己更改URL                Response.WriteFile("~/HttpError/404.html");                Server.ClearError();                return;            }        }        strExceptionMessage = lastError.Message;        /*-----------------------------------------------------         * 此处代码可根据需求进行日志记录,或者处理其他业务流程         * ---------------------------------------------------*/        /*         * 跳转到指定的http 500错误信息页面         * 跳转到静态页面一定要用Response.WriteFile方法                          */        Response.StatusCode = 500;        Response.WriteFile("~/HttpError/500.html");        //一定要调用Server.ClearError()否则会触发错误详情页(就是黄页)        Server.ClearError();        Server.Transfer("~/HttpError/500.aspx");    }}

从上面的演示代码可以看出,在Application_Error事件中可以通过Server.GetLastError()获取Exception对象,并依据Exception对象获取相关异常信息,包括HTTP错误码、详细的错误信息等等。在事件中可以根据需求编写自己的业务代码,比如记录日志、跳转到自定义的错误页面等。

编写Application_Error事件的代码需要注意的地方

1、一定要取消GlobalFilter全局过滤器中HandleErrorAttribute的注册,也要注意检查项目中是否有其他全局过滤器对异常进行处理的,防止HTTP 500类型的服务器错误不会触发Application_Error事件(其他类型错误依然可触发)。

此外也可以关闭Web.config配置文件的自定义错误:<customErrors mode="Off"></customErrors>。因为一般情况下都是在Application_Error事件中处理要跳转的自定义错误页,这样有利于设置HTTP错误代码。


2、无论最终处理的流程如何,在流程结束或者响应输出的地方,一定要调用Server.ClearError()方法清空异常,否则异常错误依然处于未被处理的状态,如果customErrors mode="On",那么异常会被自定义错误模块处理,除非本意就是要使用这种方式跳转到错误页。

如果已经关闭了自定义错误但又没有调用ClearError方法,将会引发ASP.NET的详细错误页面(俗称黄页)。


3、如果要跳转到静态的自定义错误页面中,请使用Response.WriteFile(string filename)方法,最后设置下HTTP状态码,比如下面的代码:

//跳转到指定的静态404信息页面,根据需求自己更改URLResponse.WriteFile("~/HttpError/404.html");Server.ClearError();

4、如果想要使用Server.Transfer(string path)方法跳转到自定义的错误页面,这里有两点需要注意:

第一点、一定不能设置HTTP状态码(Response.StatusCode),否则会引发IIS错误,无论是跳转到静态还是动态页面中。例如下列代码:

//Response.StatusCode = 500;//Server.Transfer("~/HttpError/500.html");//Server.Transfer("~/HttpError/500.aspx");

第二点、Server.Transfer方法对路由地址不兼容,会引发错误,下面代码使用路由会引发另一个异常:

Server.Transfer("~/Home/Index");

使用应用程序全局错误的一些优势:

第一点就是兼容性好,Web Form和MVC中都可以通用,如果旧的Web Form项目中是使用Application_Error处理全局异常,那么在新的MVC项目就可以很容易移植过来!此外灵活性也比较高,相比ASP.NET自带的自定义错误以及MVC的HandleError特性,可以更加自由的编写灵活的业务代码。

另外可以根据需求设定HTTP错误码,这方面也是考虑到一个SEO的问题,毕竟ASP.NET的自定义错误机智是使用302重写跳转,并不有利于SEO。虽然customErrors节点的redirectMode属性可以设置为"ResponseRewrite"(重写),但是如果在跳转的页面上不设置HTTP错误码,则HTTP状态码为200。

Application_Error处理网站异常的局限性

Application_Error事件无法处理已经被处理的异常,比如在try-catch捕捉的异常。此外由于是应用程序级别的事件,所以无法处理操作方法或者控制器级别的异常,暂时我也只想到这些局限,一般来说只要项目没有什么特殊要求都可以使用此事件处理自定义异常。


作者:十有三

出处:http://shiyousan.com/post/635813858052755170

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 拉肚子半个月怎么办啊 肚子里有细菌怎么办 文珠兰叶子黄了怎么办 文殊兰叶子太长怎么办 桑叶牡丹有虫子怎么办? 米兰花叶子枯萎怎么办 一品红叶子不红怎么办 兰花叶有白点怎么办 旱莲花叶子黄怎么办 旱莲花叶子发黄怎么办 长寿冠叶子枯萎怎么办 长寿花枯萎了怎么办 竹节海棠植株发软怎么办 竹节海棠烂根怎么办 倒挂金钟晒伤了怎么办 长寿花已经徒长怎么办 夏天长寿花徒长怎么办 吊金钟叶子蔫了怎么办 四季海棠长虫子怎么办 小金鱼花不开花怎么办 杜鹃花浇肥大了怎么办 四季海棠烂叶子怎么办 竹节海棠叶子干枯怎么办 月月菊花花朵发黑怎么办 枯萎的四季海棠怎么办 夏天蟹爪兰叶子发软怎么办 夏天蟹爪兰掉叶子该怎么办 天竺葵木质化了怎么办 绿萝烂根且叶子发黄怎么办 海棠树叶子发黑怎么办 四季海棠花干叶怎么办 海棠花叶子蔫了怎么办 海棠花叶子发黑枯萎怎么办? 海棠花突然蔫了怎么办 海棠叶子蔫了怎么办? 海棠花叶子打卷怎么办? 海棠花树叶掉了怎么办 龙骨茎蔫了怎么办 长寿花叶尖干枯怎么办 彩叶草突然蔫了怎么办 五彩苏蔫了怎么办?