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", "*");
            }
  • 相关阅读:
    Json对象与Json字符串互转(4种转换方式)
    Web.config配置文件详解
    jQuery BlockUI Plugin Demo 6(Options)
    jQuery BlockUI Plugin Demo 5(Simple Modal Dialog Example)
    jQuery BlockUI Plugin Demo 4(Element Blocking Examples)
    jQuery BlockUI Plugin Demo 3(Page Blocking Examples)
    jQuery BlockUI Plugin Demo 2
    <configSections> 位置引起的错误
    关于jQuery的cookies插件2.2.0版设置过期时间的说明
    jQuery插件—获取URL参数
  • 原文地址:https://www.cnblogs.com/williamwsj/p/7352936.html
Copyright © 2011-2022 走看看