zoukankan      html  css  js  c++  java
  • mvc源码解读(14)mvc四大过滤器之ExceptionFilter

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

    public Type ExceptionType{get;set}

     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();
            }

    对应的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内置的异常处理器到底有什么样的关系?望可以得到解释~~

  • 相关阅读:
    EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器前端源码重构(一)-从零开始搭建 webpack + vue + AdminLTE 多页面脚手架
    采用EasyDSS视频点播服务器搭建企业私有化的音视频多媒体、短视频、视频服务网站与管理后台
    基于EasyNVR摄像机无插件直播方案二次开发实现自己的摄像机IPC-NVR无插件化直播解决方案
    基于EasyNVR摄像机无插件直播流媒体服务器实现类似于单点登录功能的免登录直播功能
    实现RTSP摄像机进行网页直播和微信直播的技术方案:EasyNVR版本免费更新方法
    实现RTSP摄像机硬盘录像机NVR网站网页微信H5直播方案EasyNVR部署问题之:ERR_CONTENT_LENGTH_MISMATCH
    如何自己构建一套EasyNVR这样的无插件流媒体服务器实现摄像机硬盘录像机的网页可视化直播
    浏览器低延时播放监控摄像头RTSP海康大华硬盘录像机NVR视频(EasyNVR播放FLV视频流)
    基于EasyNVR摄像机流媒体服务器实现RTSP或Onvif监控摄像头Web无插件化直播监控
    基于EasyDarwin开源流媒体服务器框架实现EasyNVR H5无插件直播流媒体服务器方案
  • 原文地址:https://www.cnblogs.com/ghhlyy/p/2936486.html
Copyright © 2011-2022 走看看