当web.config中的
<customErrors mode="Off"/>设置为关闭的时候,只能依赖Global.asax.cs中的Application_Error方法处理。
当web.config中的
<customErrors mode="On"/>设置为开启的时候,可以实现的方法比较多。
在Global.asax.cs中 ,可以编写处理异常的代码的点有2个,一个是默认生成的
- public static void RegisterGlobalFilters(GlobalFilterCollection filters)
- {
- filters.Add(new HandleErrorAttribute());
- }
另一处是
- protected void Application_Error(object sender, EventArgs e)
- {
- }
这两处有些不同。
使用HandleErrorAttribute特性的方法是,在GlobalFilterCollection中加了一个HandleErrorAttribute属性。这个设置即把所有的程序中出现的错误都通过HandleErrorAttribute定义的方式来处理。默认情况下,new HandleErrorAttribute()的一些属性的默认值如下:
ExceptionType: {Name = "Exception" FullName = "System.Exception"}
View: "Error"
Order: -1
也就是说,这样的设置,只要出现了System.Exception这种类型的异常,都会调用Error页面处理,这里View就是Page View,不支持全路径,通常放在Views/Shared目录下.Order表示拦截异常的顺序。
你也可以这样自定义HandleErrorAttribute
- filters.Add(new HandleErrorAttribute()
- {
- ExceptionType = typeof(MyException),
- View = " MyException ",
- Order = 0
- });
从上可以看出,这种方式只能处理500错误。
HandleErrorAttribute这种在Global中添加注册的方式保证了全局的异常都是如是处理,其实它也可以单独的附加在某个Action方法上,比如下面的用法:
- [HandleError(View = "CustomErrorView", ExceptionType = typeof(NotImplementedException))]
- public ActionResult ThrowNotImplemented()
- {
- throw new NotImplementedException();
- }
错误页面如果要捕获异常的值,写法可如下:
- <h2>CustomErrorView</h2>
- Controller: <%=((HandleErrorInfo)ViewData.Model).ControllerName %>
- Action: <%=((HandleErrorInfo)ViewData.Model).ActionName %>
- Message: <%=((HandleErrorInfo)ViewData.Model).Exception.Message %>
- Stack Trace: <%=((HandleErrorInfo)ViewData.Model).Exception.StackTrace %>
更多细节,参考微软官方文档:
http://msdn.microsoft.com/zh-cn/library/system.web.mvc.handleerrorattribute(v=VS.98).aspx
需要注意的2点,
1.启用 HandleErrorAttribute属性,需要web.config中设置 customErrors Mode为On
<customErrors mode="On" defaultRedirect="500Error.htm">
2.一旦由HandleErrorAttribute属性接管了异常处理,那么就不再触发Application_Error事件,也不会跳转到配置的错误页面
对于不注册HandleErrorAttribute属性,或者HandleErrorAttribute未能捕获到异常的情况下,只能依赖Application_Error方法,在customErrors Mode为On的情况下,如果不做特殊的代码处理,会由设置自动跳到配置的页面去。
- <customErrors mode="On" defaultRedirect="500Error.htm">
- <error statusCode="403" redirect="403Error.htm" />
- <error statusCode="404" redirect="404Error.htm" />
- <error statusCode="500" redirect="500Error.htm" />
- </customErrors>
对于同样是500错误,HandleErrorAttribute模式和自动跳转到配置页面的模式有一点不同点。
自动跳转到配置的页面时,请求是先得到一个302响应,临时重定向到要跳转的页面,然后得到200响应,整个过程中并没有500响应:
而由HandleErrorAttribute控制的异常处理,直接返回的是500响应。某些场合下,IE浏览器的设置了显示友好页面,对于500错误,一律用IE自己的友好界面显示,导致服务器端的真正页面无法输出给IE用户看到。
总结:
2种处理异常的方式都很方便简单,HandleErrorAttribute方式,通过匹配不同的异常类型跳转到不同的页面,稍显灵活。
要注意,一旦由HandleErrorAttribute进行异常处理,那么就不再触发Application_Error事件 ,也不会跳转到配置的错误页面。如果不希望使用HandleErrorAttribute方式,就把filters.Add(new HandleErrorAttribute());这句话注释掉即可。
通过Application_Error方法,配合良好的代码机制,也可以很好的实现异常控制。通常2种方式依据个人口味使用。