zoukankan      html  css  js  c++  java
  • asp.net MVC之Action过滤器浅析

    在asp.net MVC中,Action过滤器是一大利器,它可以在以下两个步骤执行相关的代码:

    1.执行Action方法之前:OnActionExecuting

    2.Action方法执行完毕后:OnActionExecuted

    一般我们自定义的Action过滤器会继承FilterAttribute类和IActionFilter接口。

    FilterAttribute类有两个关键属性:

    AllowMultiple:布尔型,指示是否可指定筛选器特性的多个实例。如果可指定筛选器特性的多个实例,则为 true;否则为 false。

    Order:int整型,获取或者设置执行操作筛选器的顺序。该属性后面会讲到。

    IActionFilter接口有两个关键方法:

    void OnActionExecuting(ActionExecutingContext filterContext):在进入Action之前执行该方法。

    void OnActionExecuted(ActionExecutedContext filterContext):Action方法执行完毕之后立刻执行该方法。

    接下来让我们用代码亲自实践。

    首先自定义一个Action过滤器:

        public class MyFirstActionFilterAttribute : FilterAttribute, IActionFilter {
            public void OnActionExecuting(ActionExecutingContext filterContext) {
                filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:black;color:white;'>{2} OnActionExecuting {0} {1}</h4>",
                    filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, this.GetType().Name));
            }
    
            public void OnActionExecuted(ActionExecutedContext filterContext) {
                filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:black;color:white;'>{2} OnActionExecuted {0} {1}</h4>",
                    filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName,GetType().Name));
            }
        }

    接着我们将该方法过滤器附加到一个Action上:

            [MyFirstActionFilter]    
            public ActionResult ActionFilterTest() {
                Response.Write("进入Action方法");
                return  new EmptyResult();
            }

    执行结果如下:

    执行的顺序果然是 OnActionExecuting》Action》OnActionExecuted。

    如果有很多Action过滤器附加到一个Action方法上,那么执行的顺序又是怎样的呢?相当于自上而下压栈式执行,可以将OnActionExecuting当做左大括号,OnActionExecuted当做右大括号。

    我们继续自定义两个Action过滤器来实践一下:

        public class MySecondActionFilterAttribute : FilterAttribute, IActionFilter {
            public void OnActionExecuting(ActionExecutingContext filterContext) {
    
                filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:yellow;color:red;'>{2} OnActionExecuting {0} {1}</h4>",
                    filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, this.GetType().Name));
            }
    
            public void OnActionExecuted(ActionExecutedContext filterContext) {
                filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:yellow;color:red;'>{2} OnActionExecuted {0} {1}</h4>",
                    filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, GetType().Name));
            }
        }
    public class MyThirdActionFilterAttribute : FilterAttribute, IActionFilter { public void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:aliceblue;color:blue;'>{2} OnActionExecuting {0} {1}</h4>", filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, this.GetType().Name)); } public void OnActionExecuted(ActionExecutedContext filterContext) { filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:aliceblue;color:blue;'>{2} OnActionExecuted {0} {1}</h4>", filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, GetType().Name)); } }

    附加到同一个Action方法上:

            [MyFirstActionFilter]
            [MySecondActionFilter]
            [MyThirdActionFilter]
            public ActionResult ActionFilterTest() {
                Response.Write("进入Action方法");
                return  new EmptyResult();
            }

    执行的结果如下图所示:

    执行的顺序果然是自上而下、压栈式执行。这是默认的方式。

    我们还可以通过设置每个Action过滤器的Order属性来自定义它们的执行顺序。这就是Action过滤器需要继承FilterAttribute的原因。

    接下来我们打乱每个Action过滤器的位置,并设置每个Action过滤器的Order属性。如下代码:

            [MyThirdActionFilter(Order = 3)]
            [MySecondActionFilter(Order = 2)]
            [MyFirstActionFilter(Order =1)]
            public ActionResult ActionFilterTest() {
                Response.Write("进入Action方法");
                return  new EmptyResult();
            }

    运行程序,看一看执行的结果:

    果然是根据Order的升序来执行的,且还是压栈式执行。

    介绍一个实际的用法。如果遇到跨域的情况,可以在OnActionExecuting方法中判断当前用户码和相关标识,表示是否可以跨域处理。

    类似如下代码:

            public void OnActionExecuting(ActionExecutingContext filterContext) {
                bool isAllowCrossDomain = false;
                //判断用户码和相关标识
                //......
                //判断完毕并设置isAllowCrossDomain
                //如果允许跨域
                if (isAllowCrossDomain) {
                    //在此返回正确结果
                }
                else {
                    //返回错误代码和消息说明
                }
                filterContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
            }
  • 相关阅读:
    Python开发入门与实战3-Django动态页面
    Python开发入门与实战2-第一个Django项目
    Python开发入门与实战1-开发环境
    牛客网剑指offer第12题——数值的整数次方
    再叙快速排序
    牛客网剑指offer第29题——最小的k个数
    牛客网剑指offer第59题——按之字形顺序打印二叉树
    牛客网剑指offer第33题——第N个丑数
    各种特征距离的计算方法及应用
    牛客网剑指offer第24题——二叉树中和为某一值的路径
  • 原文地址:https://www.cnblogs.com/williamwsj/p/7352936.html
Copyright © 2011-2022 走看看