mvc源码解读(14)-mvc四大过滤器之ExceptionFilter

这一章我们主要来讲异常过滤器ExceptionFilter,废话不多说,mvc3中默认的异常过滤器特性类是HandleErrorAttribute,该类的主要主要成员有:

public Type ExceptionType 
{
    getset
}
public string View 
{
    get 
    {
        if (string.IsNullOrEmpty(this._view)) 
        {
            return "Error";
        }
        return this._view;
    }
    set 
    {
        this._view = value;
    }
}
public virtual void OnException(ExceptionContext filterContext) 
{
    if (filterContext == null) 
    {
        throw new ArgumentNullException("filterContext");
    }
    if (!filterContext.IsChildAction && (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled)) 
    {
        Exception innerException = filterContext.Exception;
        if ((new HttpException(null, innerException).GetHttpCode() == 500) && this.ExceptionType.IsInstanceOfType(innerException)) 
        {
            string controllerName = (string) filterContext.RouteData.Values["controller"];
            string actionName = (string) filterContext.RouteData.Values["action"];
            HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
            ViewResult result = new ViewResult {
                                    ViewName = this.View,
                                    MasterName = this.Master,
                                    ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
                                    TempData = filterContext.Controller.TempData
                                };
            filterContext.Result = result;
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = 500;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
    }
}

其中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>
    <customErrors mode="On"></customErrors>
</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();
}

对应的index的View如下:

@{     Layout = null; }

<!DOCTYPE html>

<html><head><title>Index</title> </head> <body><div>        

<p>这个是我自己try-Catch到的异常哦~~~</p></div></body></html>

运行结果如下:
这里写图片描述

我们可以看到,这一次他并没有执行OnException方法,异常直接被Catch住了。try-Catchmvc内置的异常处理器到底有什么样的关系?望可以得到解释~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET Core MVC 是一个开源的、基于 .NET Core 的 Web 应用程序框架,它是 ASP.NET 的最新版本且经过专门设计以支持现代化 Web 开发。ASP.NET Core MVC 源码可以从官方的 GitHub 仓库中获取。 ASP.NET Core MVC源码是以 C# 编写的,它提供了一套丰富的类库和组件,用于构建 Web 应用程序中的模型(Model)、视图(View)和控制器(Controller)。这个框架采用了分层架构的方式,使得开发者可以更好地组织和管理 Web 应用程序的代码。 在 ASP.NET Core MVC 源码中,可以找到一些重要的组件和模块,比如路由系统、模型绑定器、过滤器、视图引擎等。这些组件都经过精心设计和优化,以提供高性能和可扩展性。 通过阅读 ASP.NET Core MVC 源码,开发者可以深入了解这个框架的工作原理和内部机制。他们可以看到其中的设计思路、模式和最佳实践,从而更好地理解和应用这个框架。 ASP.NET Core MVC 源码也是一个很好的学习资源,开发者可以通过阅读源码来学习优秀的编程技巧和实践方法。在阅读源码的过程中,可以发现许多设计上的巧妙之处,从而提升自己的编码水平。 总之,ASP.NET Core MVC 源码是一个宝贵的资源,通过阅读和学习可以帮助开发者更好地掌握这个框架并创建高质量的 Web 应用程序。它展示了如何构建一个现代化、可扩展和高性能的 Web 应用程序框架。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值