首页 > 代码库 > MVC源码分析 - Error过滤器

MVC源码分析 - Error过滤器

接 上一篇  内容, 这里先看一下错误处理过滤器.

在看此部分之前, 先看看MVC已经提供的功能吧.

一. MVC 自带功能

1. 配置方法

<system.web>
  <!--mode : Off / On / RemoteOnly-->
  <customErrors mode="RemoteOnly">
    <error statusCode="404" redirect="~/NotFound/Index"/>
  </customErrors>
</system.web>

这里的mode默认是 Off , 就是会在页面中直接显示详细的错误信息. 

如果是 On,  则不会显示详细的错误信息, 显示是这样的:

技术分享

 

在没有配置具体 status 的跳转页面的时候, 显示是这样的:

技术分享

 

如果在下面配置了错误状态对应的跳转页面, 会跳转到我们事先指定的页面:

技术分享

 

这里的mode其实还有一个值:RemoteOnly. 这里的意思是在服务器端显示详细错误信息, 在客户端显示指定的页面. 还是很好用的.

 

2. 在方法上加特性的方法

在这里首先要介绍一下, 此特性的几个参数.

技术分享

从上图中能看到4个参数, 看一下每一个参数是干啥的.

参数 描述
ExceptionType 要处理的异常类型
Master 模板视图的名称, 存放在 Views/Shared 文件下
View 内容视图名称, 也是存放在 Views/Shared 文件中
Order 过滤器被应用的顺序, 越小越靠前, 最高级别为-1, 默认为-1
[HandleError(ExceptionType = typeof(Exception), View = "Error500", Master = "_Layout1")]
public ActionResult Index()
{
    throw new Exception("Home/Index 主动抛出的异常");
}

技术分享

 

二. 自定义过滤器 

 1. Controller 控制器中, 自定义 OnException 方法

在HomeController中, 加入如下两个方法:

public ActionResult Index()
{
    throw new Exception("Home/Index 主动抛出的异常");
}

protected override void OnException(ExceptionContext filterContext)
{
    filterContext.HttpContext.Response.Redirect("~/Errors/MyError?msg=" + filterContext.Exception.Message);
}

然后创建一个错误处理控制器 ErrorsController, 加入如下方法:

public ActionResult MyError(string msg)
{
    ViewBag.Msg = msg;
    return View();
}

到这里, 准备工作就差不多了, 视图部分我就不贴了, 直接上结果:

技术分享

这种方式, 跟之前的权限过滤器一样, 只对本控制器内的方法起作用.

那是不是也像之前的那样, 有一个全局的呢? Of course, yes.

 

2. 自定义全局/局部错误过滤器

 新建一个自定义过滤器MyErrorsAttribute

public class MyErrorsAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        base.OnException(filterContext);
        //标记此错误已经处理过, 如果别的错误捕捉器捕捉到此错误, 就不会重复处理了.
        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Redirect("~/Errors/MyError?msg=" + filterContext.Exception.Message);
    }
}

接下来就是全局和局部的区分了.

1). 全局方式:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new MyErrorsAttribute());
    }
}

2). 局部方式 - 特性的方式

[MyErrors]
public ActionResult Index()
{
    throw new Exception("Foot/Index 主动抛出的异常");
}

在错误处理里面, 可以使用log4来记录错误, 然后将友好的错误页面展现给用户, 目的就达到了.

 目录已同步

 

MVC源码分析 - Error过滤器