zoukankan      html  css  js  c++  java
  • ASP.NET MVC 中的过滤器

    这里用实例说明各种过滤器的用法,有不对的地方还请大神指出,共同探讨。

    1. ActionFilter 方法过滤器:

      接口名为 IActionFilter ,在控制器方法调用前/后执行。

    在新建的MVC程序中,添加一个类 MyFilter1Attribute 并继承ActionFilterAttribute抽象类

    从上图可以看到 ActionFilterAttribute 中的所有方法,且有相应的介绍,我们可以通过继承 ActionFilterAttribute 类,并重写(override)它的方法,从而实现自定义Filter

       public class MyFilter1Attribute: ActionFilterAttribute
        {
            /// <summary>
            /// 该方法会在Action方法执行之前调用
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在Ation方法调用前执行<br/>");
                base.OnActionExecuting(filterContext);
            }
    
    
            /// <summary>
            /// 该方法会在Action方法执行之后调用
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                filterContext.HttpContext.Response.Write("我是OnActionExecuted,我在Action方法调用后执行<br/>");
                base.OnActionExecuted(filterContext);
            }
    
        }

    然后创建一个HomeController控制器,并添加FilterTest的测试Action

        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            [MyFilter1]
            public void FilterTest()
            {
                Response.Write("我是Action方法,我在这里执行了.....<br/>");
            }
        }

    运行程序并访问FilterTest方法:

     上图可看出它的一个执行顺序

     但是有时候也有可能有这样的场景:当检查到Action有标识某个Attribute的时候,我们需要跳出,并不执行后续的方法的情况,我们可以通过filterContextActionDescriptior类中的IsDefained方法进行判断检查

         /// <summary>
            /// 该方法会在Action方法执行之前调用
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在Ation方法调用前执行<br/>");
                //判断Action方法时是否有贴上MyFilter1Attribute标签
                if (filterContext.ActionDescriptor.IsDefined(typeof(MyFilter1Attribute), false))
                {
                    //如果有,为该Action方法直接返回ContentResult,则该Action方法在这里就有了返回值,相当于在这里就结束了,不会再去执行之后的方法,例如:OnActionExecuted
                    filterContext.Result = new ContentResult();
                }
                base.OnActionExecuting(filterContext);
            }

    2.ResultFilter 结果过滤器:

      接口名为 IResultFilter,在控制器方法调用完,跳转至View页面前/后调用

     同样在 MyFilter1Attribute 类中重写 OnResultExecuting 方法和  OnResultExecuted 方法

            /// <summary>
            /// 该方法在Action方法返回结果之前执行
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
                filterContext.HttpContext.Response.Write("我是OnResultExecuting,我在Action方法返回结果前执行<br/>");
                base.OnResultExecuting(filterContext);
            }
    
            /// <summary>
            /// 该方法在Action方法返回结果之后执行
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                filterContext.HttpContext.Response.Write("我是OnResultExecuted,我在Action方法返回结果后执行<br/>");
                base.OnResultExecuted(filterContext);
            }
    View Code

    然后在HomeController控制器中添加 FilterTest1

            [MyFilter1]
            public ActionResult FilterTest1()
            {
                Response.Write("我是测试Action1方法,我在这里执行了.....<br/>");
                return View();
            } 
    View Code

    运行程序,并访问 FilterTest1 ,执行结果如下:

    可以看出OnResultExecuting 方法是在返回结果页面之前执行的,而OnResultExecuted是返回结果页面之后执行的

    3.ExceptionFilter 异常操作过滤器:

      接口名为 IExceptionFilter,在控制器的Action方法抛出异常时执行

     可以通过异常过滤器捕获Controller中发生的异常,并记录到日志。

    添加MyExceptionAttribute类,并继承HandleErrorAttribute,如下

            /// <summary>
            /// 
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnException(ExceptionContext filterContext)
            {
                filterContext.HttpContext.Response.Write("我是OnException,在Controller中发生异常时进入<br/>");
    
                //获取到异常对象
                Exception ex = filterContext.Exception;
                //获取请求的Controller和Action
                string controllerName = filterContext.RouteData.Values["controller"].ToString();
                string actionName = filterContext.RouteData.Values["action"].ToString();
                //记录日志
                string errMessage = string.Format("异常消息:控制器为:{0},Action为:{1},异常信息为:{2};", controllerName, actionName, ex.Message);
                OutPutLog(errMessage);
    
                //标记异常已做处理
                filterContext.ExceptionHandled = true;
                base.OnException(filterContext);
            }
    
            /// <summary>
            /// 输出日志
            /// </summary>
            /// <param name="message"></param>
            public void OutPutLog(string message)
            {
                string path = AppDomain.CurrentDomain.BaseDirectory + "/Logs.txt";
                using (StreamWriter sw = new StreamWriter(path, true, Encoding.Default))
                {
                    sw.Flush();
                    sw.WriteLine("时间:" + DateTime.Now);
                    sw.WriteLine("内容:" + message);
                    sw.WriteLine("---------------------------------------------");
                }
            }
    View Code

    HomeController中添加FilterTest3

     [MyException]
     public ActionResult FilterTest3()
     {
         Response.Write("我是测试Action3方法,我在这里执行了.....<br/>");
         string str = "131464ddddd";
         int i = int.Parse(str);
         return View();
     }

    运行程序并访问 FilterTest3方法,将会在 str 转换成int类型时抛出异常,随后将进入OnException方法,并记录日志如下:

    4.AuthorizationFilter 授权过滤器:

      接口名为 IauthorizationFilter,在所有过滤器中最先执行

    添加一个MyFilter2Attribute类,并继承AuthorizeAttribute类,然后重写其OnAuthorization方法:

        public class MyFilter2Attribute: AuthorizeAttribute
        {
    
            /// <summary>
            /// 在所有的Action方法过滤之前执行
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
                filterContext.HttpContext.Response.Write("我是OnAuthorization,在所有Action方法过滤器之前执行<br/>");//base.OnAuthorization(filterContext);
            }
        }

    HoneController控制器中添加 FilterTest2

        [MyFilter1]
        [MyFilter2]
        public ActionResult FilterTest2()
        {
            Response.Write("我是测试Action2方法,我在这里执行了.....<br/>");
            return View();
        }

    运行程序并访问 FilterTest2  结果如下:

    从上图执行结果可以看出,OnAuthorization 权重是最高的,将会在其他所有过滤器之前执行。

    注意:

      ActionFilter 和 ResultFilter 不仅可以对单个方法进行操作,也能对整个Controller进行操作,将过滤的头部属性移至控制名称上面即可。

  • 相关阅读:
    python note 30 断点续传
    python note 29 线程创建
    python note 28 socketserver
    python note 27 粘包
    python note 26 socket
    python note 25 约束
    Sed 用法
    python note 24 反射
    python note 23 组合
    python note 22 面向对象成员
  • 原文地址:https://www.cnblogs.com/Struggle-xh/p/11400368.html
Copyright © 2011-2022 走看看