zoukankan      html  css  js  c++  java
  • [Asp.net MVC]HandleErrorAttribute异常过滤器

    摘要

    在asp.net mvc中除了使用try...catch/finally来处理异常外,它提供了一种通过在Controller或者Action上添加特性的方式来处理异常。

    HandleErrorAttribute

    首先看一下该特性的定义

    using System;
    
    namespace System.Web.Mvc
    {
        // 摘要: 
        //     表示一个特性,该特性用于处理由操作方法引发的异常。
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
        public class HandleErrorAttribute : FilterAttribute, IExceptionFilter
        {
            // 摘要: 
            //     初始化 System.Web.Mvc.HandleErrorAttribute 类的新实例。
            public HandleErrorAttribute();
    
            // 摘要: 
            //     获取或设置异常的类型。
            //
            // 返回结果: 
            //     异常的类型。
            public Type ExceptionType { get; set; }
            //
            // 摘要: 
            //     获取或设置用于显示异常信息的母版视图。
            //
            // 返回结果: 
            //     母版视图。
            public string Master { get; set; }
            //
            // 摘要: 
            //     获取此特性的唯一标识符。
            //
            // 返回结果: 
            //     此特性的唯一标识符。
            public override object TypeId { get; }
            //
            // 摘要: 
            //     获取或设置用于显示异常信息的页视图。
            //
            // 返回结果: 
            //     页视图。
            public string View { get; set; }
    
            // 摘要: 
            //     在发生异常时调用。
            //
            // 参数: 
            //   filterContext:
            //     操作筛选器上下文。
            //
            // 异常: 
            //   System.ArgumentNullException:
            //     filterContext 参数为 null。
            public virtual void OnException(ExceptionContext filterContext);
        }
    }

    ExceptionType:属性,相当于try catch(Exception)中的catch捕获的异常类型,默认所有异常类型。

    View:异常展示视图,这个视图需要在目录Views/Shared/下。例如:

    Order:该属性是父类FilterAttribute的一个属性,用来获取或者设置执行操作筛选器的顺序,默认-1,-1最先执行。

    一个例子

    在Index中直接抛出一个异常,我们现在需要做的就是通过HandlerError特性捕获到这个异常,并且在视图MyError上显示详细信息。

    步骤1:添加特性

        public class UserController : Controller
        {
            // GET: User
            [HandleError(ExceptionType = typeof(Exception), View = "MyError")]
            public ActionResult Index()
            {
                throw new Exception("Sorry,threre is an error in your web server.");
            }
    
        }

    步骤2:定义错误视图,并通过@Model获取异常对象并显示错误信息。

    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title></title>
    </head>
    <body>
        <div>
            @Model.Exception.GetType().Name<br />
            @Model.Exception.Message<br />
            @Model.ControllerName<br />
            @Model.ActionName<br />
            @Model.Exception.StackTrace<br />
        </div>
    </body>
    </html>

    步骤3:注册过滤器。

    在App_Start目录添加类FilterConfig

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

    在Global.asax中注册

        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                GlobalConfiguration.Configure(WebApiConfig.Register);
    
            }
        }

    步骤4:开启自定义错误配置

      <system.web>
        ...
        <customErrors mode="On"></customErrors>
      </system.web>

    测试

    以上是采用ErrorHanlder的默认实现的方式,当然我们也可以自定义异常处理过滤器,方法很简单继承HandleErrorAttribute类,并且重写OnException方法即可。

        /// <summary>
        /// 自定义异常过滤器
        /// </summary>
        public class CustomerErrorAttribute : HandleErrorAttribute
        {
            public override void OnException(ExceptionContext filterContext)
            {
                //如果没有处理该异常
                if (!filterContext.ExceptionHandled)
                {
                    if (filterContext.Exception.Message.Contains("Sorry,threre is an error in your web server."))
                    {
                        filterContext.ExceptionHandled = true;
                        filterContext.HttpContext.Response.Write("这是一个自定义异常处理过滤器");
                    }
                }
            }
        }
        public class UserController : Controller
        {
            // GET: User
            [CustomerError(ExceptionType = typeof(Exception), View = "MyError")]
            public ActionResult Index()
            {
                throw new Exception("Sorry,threre is an error in your web server.");
            }
    
        }
        public class FilterConfig
        {
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
                filters.Add(new CustomerErrorAttribute());
            }
        }

    测试

    好了,自定义的异常处理过滤器已经起作用了。

    需要注意在自定义处理异常过滤器的时候需要重写OnException方法,该方法有一个ExceptionContext类型的参数。

        // 摘要: 
        //     提供使用 System.Web.Mvc.HandleErrorAttribute 类的上下文。
        public class ExceptionContext : ControllerContext
        {
            // 摘要: 
            //     初始化 System.Web.Mvc.ExceptionContext 类的新实例。
            public ExceptionContext();
            //
            // 摘要: 
            //     使用指定的控制器上下文针对指定的异常初始化 System.Web.Mvc.ExceptionContext 类的新实例。
            //
            // 参数: 
            //   controllerContext:
            //     控制器上下文。
            //
            //   exception:
            //     异常。
            //
            // 异常: 
            //   System.ArgumentNullException:
            //     exception 参数为 null。
            public ExceptionContext(ControllerContext controllerContext, Exception exception);
    
            // 摘要: 
            //     获取或设置异常对象。
            //
            // 返回结果: 
            //     异常对象。
            public virtual Exception Exception { get; set; }
            //
            // 摘要: 
            //     获取或设置一个值,该值指示是否已处理异常。
            //
            // 返回结果: 
            //     如果已处理异常,则为 true;否则为 false。
            public bool ExceptionHandled { get; set; }
            //
            // 摘要: 
            //     获取或设置操作结果。
            //
            // 返回结果: 
            //     操作结果。
            public ActionResult Result { get; set; }
        }

    需要注意的是,在自定义的异常过滤器中,如果对异常已经处理了,需要将ExceptionHandled设置为true,这样其它的过滤器可以根据该值判断当前异常是否已经处理过了。

    通过异常处理过滤器的特性,你可以更方便的来处理action或者Controller中的异常,比try--catch用起来更方便,用这种方式,也可以简化异常处理的代码,少一些大块儿大块儿的异常处理代码。

  • 相关阅读:
    java利用zxing编码解码一维码与二维码
    Spring和MyBatis环境整合
    ML中Boosting和Bagging的比較
    理解x64代码模型
    python list.remove(),del()和filter &amp; lambda
    限制文本域中字符输入个数
    arcgis api for flex之专题图制作(饼状图,柱状图等)
    Linux I/O复用中select poll epoll模型的介绍及其优缺点的比較
    开发H5游戏引擎的选择:Egret或Laya?
    C++刷题——2830: 递归求1*1+2*2+3*3+……+n*n
  • 原文地址:https://www.cnblogs.com/wolf-sun/p/6757529.html
Copyright © 2011-2022 走看看