ASP.NET MVC中,通用的异常处理

时间:2022-12-31 20:33:09

当web.config中的

<customErrors mode="Off"/>设置为关闭的时候,只能依赖Global.asax.cs中的Application_Error方法处理。

当web.config中的

<customErrors mode="On"/>设置为开启的时候,可以实现的方法比较多。

在Global.asax.cs中 ,可以编写处理异常的代码的点有2个,一个是默认生成的

 

  
 
 
  1. public static void RegisterGlobalFilters(GlobalFilterCollection filters)  
  2.         {  
  3.             filters.Add(new HandleErrorAttribute());  
  4.         } 

 

另一处是

  
 
 
  1. protected void Application_Error(object sender, EventArgs e)  
  2. {  
  3. }   

这两处有些不同。

使用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  

  
 
 
  1. filters.Add(new HandleErrorAttribute()  
  2. {  
  3.     ExceptionType = typeof(MyException),  
  4.      View = " MyException ",  
  5.      Order = 0  
  6. });

 

从上可以看出,这种方式只能处理500错误。

HandleErrorAttribute这种在Global中添加注册的方式保证了全局的异常都是如是处理,其实它也可以单独的附加在某个Action方法上,比如下面的用法:   

  
 
 
  1. [HandleError(View = "CustomErrorView", ExceptionType = typeof(NotImplementedException))]  
  2.    public ActionResult ThrowNotImplemented()  
  3.    {  
  4.        throw new NotImplementedException();  
  5.    } 

错误页面如果要捕获异常的值,写法可如下:

 

  
 
 
  1. <h2>CustomErrorView</h2> 
  2.   Controller: <%=((HandleErrorInfo)ViewData.Model).ControllerName %> 
  3.   Action: <%=((HandleErrorInfo)ViewData.Model).ActionName %> 
  4.   Message: <%=((HandleErrorInfo)ViewData.Model).Exception.Message %> 
  5.   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的情况下,如果不做特殊的代码处理,会由设置自动跳到配置的页面去。  

  
 
 
  1. <customErrors mode="On" defaultRedirect="500Error.htm"> 
  2.       <error statusCode="403" redirect="403Error.htm" /> 
  3.       <error statusCode="404" redirect="404Error.htm" /> 
  4.       <error statusCode="500" redirect="500Error.htm" /> 
  5.     </customErrors>  

对于同样是500错误,HandleErrorAttribute模式和自动跳转到配置页面的模式有一点不同点。

自动跳转到配置的页面时,请求是先得到一个302响应,临时重定向到要跳转的页面,然后得到200响应,整个过程中并没有500响应:

ASP.NET MVC中,通用的异常处理

而由HandleErrorAttribute控制的异常处理,直接返回的是500响应。某些场合下,IE浏览器的设置了显示友好页面,对于500错误,一律用IE自己的友好界面显示,导致服务器端的真正页面无法输出给IE用户看到。

ASP.NET MVC中,通用的异常处理

总结:

2种处理异常的方式都很方便简单,HandleErrorAttribute方式,通过匹配不同的异常类型跳转到不同的页面,稍显灵活。

要注意,一旦由HandleErrorAttribute进行异常处理,那么就不再触发Application_Error事件 ,也不会跳转到配置的错误页面。如果不希望使用HandleErrorAttribute方式,就把filters.Add(new HandleErrorAttribute());这句话注释掉即可。

通过Application_Error方法,配合良好的代码机制,也可以很好的实现异常控制。通常2种方式依据个人口味使用。

本文出自 “一只博客” 博客,请务必保留此出处http://cnn237111.blog.51cto.com/2359144/1035439