zoukankan      html  css  js  c++  java
  • MVC过滤器:自定义异常过滤器

    一、异常过滤器

    异常筛选器用于实现IExceptionFilter接口,并在ASP.NET MVC管道执行期间引发了未处理的异常时执行。异常筛选器可用于执行诸如日志记录或显示错误页之类的任务。HandleErrorAttribute类是异常筛选器的一个示例。

    先来看看HandleErrorAttribute类的定义:

    #region 程序集 System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
    // D:PracticeMVC自定义异常过滤器MVCCuetomerExcepFilterpackagesMicrosoft.AspNet.Mvc.5.2.7lib
    et45System.Web.Mvc.dll
    #endregion
    
    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:
            //     操作筛选器上下文。
            //
            // 异常:
            //   T:System.ArgumentNullException:
            //     filterContext 参数为 null。
            public virtual void OnException(ExceptionContext filterContext);
        }
    }

     从代码中可以看出HandleErrorAttribute继承了IExceptionFilter接口,并且有一个虚方法,如果要自定义异常过滤器,只需要继承HandleErrorAttribute类并重写HandleErrorAttribute类里面的虚方法即可。

    二、示例

    1、创建异常类

    新建一个ExceptionFilters类继承自HandleErrorAttribute,并重写OnException方法,代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace MVCCuetomerExcepFilter.Extension
    {
        /// <summary>
        /// 异常过滤器
        /// </summary>
        public class ExceptionFilters : HandleErrorAttribute
        {
            /// <summary>
            /// 在异常发生时调用
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnException(ExceptionContext filterContext)
            {
                // 判断是否已经处理过异常
                if(!filterContext.ExceptionHandled)
                {
                    // 获取出现异常的controller和action名称,用于记录
                    string strControllerName = filterContext.RouteData.Values["controller"].ToString();
                    string strActionName = filterContext.RouteData.Values["action"].ToString();
                    // 定义一个HandleErrorInfo,用于Error视图展示异常信息
                    HandleErrorInfo info = new HandleErrorInfo(filterContext.Exception, strControllerName, strActionName);
    
                    ViewResult result = new ViewResult
                    {
                        ViewName = this.View,
                        // 定义ViewData,泛型
                        ViewData = new ViewDataDictionary<HandleErrorInfo>(info)
                    };
                    // 设置操作结果
                    filterContext.Result = result;
                    // 设置已经处理过异常
                    filterContext.ExceptionHandled = true;
                }
                //base.OnException(filterContext);
            }
        }
    }

    2、创建控制器

    新建一个控制器,代码如下:

    using MVCCuetomerExcepFilter.Extension;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace MVCCuetomerExcepFilter.Controllers
    {
        public class ExceptionController : Controller
        {
            // GET: Exception
            /// <summary>
            /// View表示发生异常时指定的视图
            /// 这里表示发生异常时使用ExceptionDetails视图
            /// </summary>
            /// <returns></returns>
            [ExceptionFilters(View =("ExceptionDetails"))]
            public ActionResult Index()
            {
                // 测试抛出异常
                throw new NullReferenceException("测试抛出的异常");
            }
        }
    }

     异常发生时使用ExceptionDetails视图,所以在Shared文件夹里面新建ExceptionDetails视图,代码如下:

    <!--使用强类型视图-->
    @model System.Web.Mvc.HandleErrorInfo
    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>异常</title>
    </head>
    <body>
        <p>
            抛错控制器:<b>@Model.ControllerName</b> 抛错方法:<b>@Model.ActionName</b> 抛错类型:<b>
                @Model.Exception.GetType().Name
        </b>
    </p>
    <p>
        异常信息:<b>@Model.Exception.Message</b>
    </p>
    <p>
        堆栈信息:
    </p>
    <pre>@Model.Exception.StackTrace</pre>
    </body>
    </html>

    三、测试

    运行程序,访问Exception控制器的Index方法,效果如下:

    四、总结

    上面的案例演示了一个自定义异常类,很明显比HandleError要灵活,在自定义异常类里面可以写很多与业务相关的代码。

    GitHub代码地址:git@github.com:JiangXiaoLiang1988/CustomerHandleErrorFilter.git

  • 相关阅读:
    redis 写入数据 越来越慢 是什么原因
    redis slowlog
    JavaCC 规格严格
    Lucene 规格严格
    数据库建立索引要点 规格严格
    编辑距离 规格严格
    Lucene NRT (Near Real Time) 规格严格
    事件关联 规格严格
    linux下mysql5.5.19编译安装笔记【已验证】 规格严格
    关于CLOSE BY CLIENT STACK TRACE 规格严格
  • 原文地址:https://www.cnblogs.com/dotnet261010/p/10848078.html
Copyright © 2011-2022 走看看