在ASP.NET MVC中,经过应用程序生命周期中的Application_Error事件能够捕获到网站引起的全部未处理异常。本文做为学习笔记,记录了使用Global.asax文件的Application_Error事件处理和捕获全局异常的详细步骤。html
文章演示项目是使用vs2013编译器编写的,下载地址:GlobalExceptionHandle-By-Application_Error.zip。web
在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事件代码:mvc
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错误码、详细的错误信息等等。在事件中能够根据需求编写本身的业务代码,好比记录日志、跳转到自定义的错误页面等。app
一、必定要取消GlobalFilter全局过滤器中HandleErrorAttribute的注册,也要注意检查项目中是否有其余全局过滤器对异常进行处理的,防止HTTP 500类型的服务器错误不会触发Application_Error事件(其余类型错误依然可触发)。post
此外也能够关闭Web.config配置文件的自定义错误:<customErrors mode="Off"></customErrors>。由于通常状况下都是在Application_Error事件中处理要跳转的自定义错误页,这样有利于设置HTTP错误代码。学习
二、不管最终处理的流程如何,在流程结束或者响应输出的地方,必定要调用Server.ClearError()方法清空异常,不然异常错误依然处于未被处理的状态,若是customErrors mode="On",那么异常会被自定义错误模块处理,除非本意就是要使用这种方式跳转到错误页。网站
若是已经关闭了自定义错误但又没有调用ClearError方法,将会引起ASP.NET的详细错误页面(俗称黄页)。spa
三、若是要跳转到静态的自定义错误页面中,请使用Response.WriteFile(string filename)方法,最后设置下HTTP状态码,好比下面的代码:
//跳转到指定的静态404信息页面,根据需求本身更改URL Response.WriteFile("~/HttpError/404.html"); Server.ClearError();
四、若是想要使用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事件没法处理已经被处理的异常,好比在try-catch捕捉的异常。此外因为是应用程序级别的事件,因此没法处理操做方法或者控制器级别的异常,暂时我也只想到这些局限,通常来讲只要项目没有什么特殊要求均可以使用此事件处理自定义异常。
出处:http://shiyousan.com/post/635813858052755170
欢迎转载本文,本文版权归做者全部,转载请声明出处或保留此段声明。^_^请尊重他人劳动成果,共建美好的网络环境。