MVC使用HandleErrorAttribute自定义异常

时间:2022-05-20 17:16:45

MVC中,有一个Filter可以捕捉错误,但是它的用法是利用Attribute来实现的,而且只能加在Controller和Action上,所以不能捕捉别出的错误

其实理论上所有的错误肯定产生于Controller中,但有2种情况下,就不会被捕捉了

1、页面不存在的时候,找不到对应的Controller,那没有任何Controller被执行,所以自然也不会捕捉到错误了

2、在 IAuthorizationFilter 下发生错误的时候,错误捕捉代码在IExceptionFilter中,而IAuthorizationFilter的优先权高于IExceptionFilter,所以也就捕捉不到了

一、HandleError的使用

1、设置HandleError属性

  可以通过设置下面这些属性来更改HandleErrorAttribute特性的默认处理:

  ExceptionType.指定过滤器处理那种或哪些类型的异常,如果没有指定该属性,过滤器将会处理所有的异常.

  View.指定发生异常时过滤器要显示的视图名称.

  Master.指定视图母版的名称,如果有的话.

  Order.指定过滤器应用的顺序,如果一个Action有多个HandleErrorAttribute过滤器.

2、指定Order属性

  如果某个Action设置了多个HandleErrorAttribute,Order属性可以用来确定使用哪个过滤器.其值可以设置为从-1(最高优先级)到任何正整数之间的整数来标识其优先级,值越大,优先级别越低.Order属性遵循以下规则:

  应用到Controller上的过滤器将会自动应用到该Controller的所有Action上.

  如果Controller和Action都应用了HandleErrorAttribute,那么只要Order属性值相同,将会先执行Controller上的过滤器,而后才会执行Action上的过滤器.

  对于相同Order属性的过滤器,其执行先后次序不定.

  如果没有指定Order属性,则默认为-1,这意味着该过滤器将比其他的过滤器优先执行,除非其他过滤器指定了Order为-1.

  如果有多个过滤器可适用,那么第一个可以处理该异常的过滤器会被首先调用,然后针对该异常的处理将会终结.

3、在View中获取异常信息

  ASP.NET MVC框架将异常信息存储在ViewDataDictionary中来传递给Error视图,该ViewDataDictionary的Model属性即是ExceptionContext类的一个实例,这个ViewData有下面几个键:

  ActionName:目标Action方法的名称

  ControllerName:目标Controller的名称

  Exception:异常对象.

二、使用HandleErrorAttribte类处理异常及步骤

1、可以通过下列两种方式选择一种处理异常

(1)、在类或者方法上直接使用HandleError属性来定义

 
MVC使用HandleErrorAttribute自定义异常MVC使用HandleErrorAttribute自定义异常
// 在这里声明

MVC使用HandleErrorAttribute自定义异常

[HandleError]

MVC使用HandleErrorAttribute自定义异常

public class HomeController : Controller

MVC使用HandleErrorAttribute自定义异常

{
MVC使用HandleErrorAttribute自定义异常 // 或者在这里声明
MVC使用HandleErrorAttribute自定义异常 // [HandleError]
MVC使用HandleErrorAttribute自定义异常 public ActionResult Index()
MVC使用HandleErrorAttribute自定义异常 {
MVC使用HandleErrorAttribute自定义异常 return View();
MVC使用HandleErrorAttribute自定义异常 }
MVC使用HandleErrorAttribute自定义异常}
MVC使用HandleErrorAttribute自定义异常

 (2)、使用MVC3的Global Filters功能来注册,默认新建MVC项目在Global.asax文件里就已经有了

代码如下:

 
MVC使用HandleErrorAttribute自定义异常MVC使用HandleErrorAttribute自定义异常
public static void RegisterGlobalFilters(GlobalFilterCollection filters)

MVC使用HandleErrorAttribute自定义异常

{
MVC使用HandleErrorAttribute自定义异常 filters.Add(new HandleErrorAttribute());
MVC使用HandleErrorAttribute自定义异常}
MVC使用HandleErrorAttribute自定义异常
MVC使用HandleErrorAttribute自定义异常public static void RegisterRoutes(RouteCollection routes)
MVC使用HandleErrorAttribute自定义异常{
MVC使用HandleErrorAttribute自定义异常 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
MVC使用HandleErrorAttribute自定义异常
MVC使用HandleErrorAttribute自定义异常 routes.MapRoute(
MVC使用HandleErrorAttribute自定义异常"Default", // Route name
MVC使用HandleErrorAttribute自定义异常"{controller}/{action}/{id}", // URL with parameters
MVC使用HandleErrorAttribute自定义异常new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
MVC使用HandleErrorAttribute自定义异常 );
MVC使用HandleErrorAttribute自定义异常
MVC使用HandleErrorAttribute自定义异常}
MVC使用HandleErrorAttribute自定义异常
MVC使用HandleErrorAttribute自定义异常protected void Application_Start()
MVC使用HandleErrorAttribute自定义异常{
MVC使用HandleErrorAttribute自定义异常 AreaRegistration.RegisterAllAreas();
MVC使用HandleErrorAttribute自定义异常
MVC使用HandleErrorAttribute自定义异常 RegisterGlobalFilters(GlobalFilters.Filters);
MVC使用HandleErrorAttribute自定义异常 RegisterRoutes(RouteTable.Routes);
MVC使用HandleErrorAttribute自定义异常}
MVC使用HandleErrorAttribute自定义异常

代码段里的filters.Add(new HandleErrorAttribute());设置是说整个程序所有的Controller都使用这个HandleErrorAttribute来处理错误。

2、开启web.config根目录里的customErrors(不是views目录下的那个web.config)

代码如下:

<customerrors mode="On" defaultredirect="~/Error/HttpError">
<error redirect="~/Error/NotFound" statuscode="404" />
</customerrors>

defaultredirect是设置为所有错误页面转向的错误页面地址,而里面的error元素可以单独定义不同的错误页面转向地址,上面的error行就是定义404所对应的页面地址。

3、定义我们所需要的错误页面的ErrorController

public class ErrorController : BaseController
{
//
// GET: /Error/
public ActionResult HttpError()
{
return View("Error");
}
public ActionResult NotFound()
{
return View();
}
public ActionResult Index()
{
return RedirectToAction("Index", "Home");
}
}

默认Error的view是/views/shared/Error.cshtml文件,我们来改写一下这个view的代码,代码如下:

@model System.Web.Mvc.HandleErrorInfo
@{
ViewBag.Title = "General Site Error";
} <h2>A General Error Has Occurred</h2> @if (Model != null)
{
<p>@Model.Exception.GetType().Name<br />
thrown in @Model.ControllerName @Model.ActionName</p>
<p>Error Details:</p>
<p>@Model.Exception.Message</p>
}

三、使用 handleError attribute 有以下局限:

1. 不支持exception记录
2. 无法捕捉到500之外的http exception
3. controller之外抛出的异常无法处理
4. ajax调用出现exception时,会将错误页面内容返回

http://www.studyofnet.com/news/316.html