mvc源码解读(14)-mvc四大过滤器之ExceptionFilter
这一章我们主要来讲异常过滤器ExceptionFilter,废话不多说,mvc3中默认的异常过滤器特性类是HandleErrorAttribute,该类的主要主要成员有:
public Type ExceptionType{get;set} public string View public virtual void OnException(ExceptionContext filterContext) |
其中ExceptionType表示异常的类型,默认是所有异常的基类Exception,表示会处理所有的标准异常。View属性表示抛出异常时该显示什么样的视图给用户,如果每没有自定义的View,系统默认输出的是字符串“Error”,OnException方法用于系统出现异常时调用的方法,我们看红色代码这两句:
filterContext.ExceptionHandled = true; new HttpException(null, innerException).GetHttpCode() == 500 |
ExceptionHandled属性是布尔值,表示该抛出的异常是否被处理了,true表示已经被处理,false表示没有被处理,如果被处理过的异常,一定要将ExceptionHandled设置为true,防止父类或者更高级别的异常处理重复的处理改异常。而HttpCode=500表示会优先调用MVC框架自己的处理异常,然后将ExceptionHandled设置为true。我们先来看一段demo:
我们自定义一个异常类过滤器MyExceptionFilter,继承自HandleErrorAttribute并重写了OnException方法,实现方法如下:
public class MyExceptionFilter : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { if (!filterContext.ExceptionHandled && filterContext.Exception is DivideByZeroException) { filterContext.Result = new RedirectResult("/MyException/ErrorView"); filterContext.ExceptionHandled = true; } base.OnException(filterContext); } } |
我们创建一个MVC3的项目,创建一个MyException控制器,具体代码如下:
[MyExceptionFilter] public ActionResult Index() { int firstNumber = 10; int secondNumber = 0; int c = firstNumber / secondNumber; return View(); } public ActionResult ErrorView() { return View(); } |
ErrorView具体代码如下:
@{ Layout = null; } <!DOCTYPE html> <html> <head><title>ErrorView</title> </head> <body><div> <p>这是一个异常页面哦~~~~~</p> </div> </body> </html> |
运行结果如下:
我们可以看到,在Index中出现异常的时候,执行了OnException方法,并将用户的请求转到了我们自定义的错误页面,同时标记改异常已经处理过了,如果上文我们说到过,若是每个Controller都要贴上这个异常标签,会很麻烦,因此我们可以在全局文件文件注册一个全局的异常过滤器,具体如下:
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); //filters.Add(new MyTestResultFiter() { FilterMessage="标志全局过滤器"}); filters.Add(new MyExceptionFilter());//全局的异常过滤器 } |
,同时在配置文件中设置i如下:
<system.web> </system.web> |
这是一种情况,我们来看另外一种情况,我们自己在try-catch中处理该异常,会有什么结果呢,我们将Index里面的方法稍作修改如下:
[MyExceptionFilter] public ActionResult Index() { try { int firstNumber = 10; int secondNumber = 0; int c = firstNumber / secondNumber; } catch (DivideByZeroException ex) { HttpContext.Response.Write(ex.Message.ToString()); } return View(); } |
对应的inde的View如下:
@{ Layout = null; } <!DOCTYPE html> <html><head><title>Index</title> </head> <body><div> <p>这个是我自己try-Catch到的异常哦~~~</p></div></body></html> |
运行结果如下:
我们可以看到,这一次他并没有执行OnException方法,异常直接被Catch住了。try-Catch和mvc内置的异常处理器到底有什么样的关系?望可以得到解释~~