zoukankan      html  css  js  c++  java
  • 过滤器

    MVC有4种过滤器。

    过滤器             接口                        默认实现

    Authorization    IAuthorizationFilter    AuthorizeAttribute

    Action              IActionFilter            ActionFilterAttribute

    Result              IResultFilter             ActionFilterAttribute

    Exception         IExceptionFilter         HandleErrorAttribute

    在生成过滤器时,可以直接实现过滤器的接口;也可以派生自默认实现,再重载里面的处理方法。

    一、动作和结果过滤器(Action和Result)

    动作过滤器内的方法有两个:

    OnActionExecuting()

    OnActionExecuted()

    结果过滤器内的方法有两个:

    OnResultExecuting()

    OnResultExecuted()

    执行时,在使用了过滤器的动作方法之前先执行OnActionExecuting(),然后执行动作方法,最后执行OnActionExecuted()。

    再然后,开始执行OnResultExecuting(),接着执行动作方法中返回的视图(实际就是ActionResult大类),最后执行OnResultExecuted()。

    例,新建MVC3项目13-21MvcFilters,在解决方案中新建目录 Infrastructure -> Filters,在此存放要建立的各个过滤器的类文件。

    1、直接实现Action过滤器接口和Result过滤器接口

    两个类放在一个文件中。

    namespace _13_21MvcFilters.Infrastructure.Filters
    {
        public class MyActionFilterAttribute : FilterAttribute, IActionFilter
        {
            public void OnActionExecuting(ActionExecutingContext filterContext)
            {
                ... ...
            }
            public void OnActionExecuted(ActionExecutedContext filterContext)
            {
                ... ...
            }
         }
    
        public class MyResultFilterAttribute : FilterAttribute, IResultFilter
        {
            public void OnResultExecuting(ResultExecutingContext filterContext)
            {
                ... ...
            }
            public void OnResultExecuted(ResultExecutedContext filterContext)
            {
                ... ...
            }
         }
    }

    2、也可以派生自动作、结果过滤器接口的默认实现ActionFilterAttribute

    编写ActionFilterAttribute的派生类,然后重载里面的OnActionExecuting()、OnActionExecuted()、OnResultExecuting()、OnResultExecuted()方法。

    namespace _13_21MvcFilters.Infrastructure.Filters
    {
        public class ProfileAllAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                ... ...
            }
    
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                ... ...
            }
    
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
               ... ...
            }
    
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                ... ...
            }
        }
    }

    例,在Infrastructure/Filters下新建类文件ProfileAllAttribute.cs,内容如下: 

    namespace _13_21MvcFilters.Infrastructure.Filters
    {
        public class ProfileAllAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                filterContext.HttpContext.Response.Write(
                    string.Format("OnActionExecuting<br>"));
            }
    
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                filterContext.HttpContext.Response.Write(
                    string.Format("OnActionExecuted<br>"));
            }
    
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
                filterContext.HttpContext.Response.Write(
                    string.Format("OnResultExecuting<br>"));
            }
    
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                filterContext.HttpContext.Response.Write(
                    string.Format("OnResultExecuted<br>"));
            }
        }
    }

    新建控制器HomeController:

    namespace _13_21MvcFilters.Controllers
    {
        public class HomeController : Controller
        {
           
            [ProfileAll]
            public ActionResult Index()
            {
                Response.Write("Action Method is running...<br>");
                return View();
            }
        }
    }

    添加视图Index.cshtml:

    @{
        ViewBag.Title = "Index";
    }
    
    <h2>Index</h2>

     结果显示为:

    3、全局过滤器;同一个过滤器带参数重复施加在一个动作方法上;施加在同一个动作方法上的过滤器执行顺序

    (1)在Infrastructure/Filters目录下,定义过滤器如下:

    namespace _13_21MvcFilters.Infrastructure.Filters
    {
        [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
        public class SimpleMessageAttribute : ActionFilterAttribute
        {
            public string Message { get; set; }
    
            public override void OnActionExecuting(ActionExecutingContext fileterContext)
            {
                fileterContext.HttpContext.Response.Write(
                    string.Format("[OnActionExecuting:{0}]<br>", Message));
            }
    
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                filterContext.HttpContext.Response.Write(
                    string.Format("[OnActionExecuted:{0}]<br>", Message));
            }
        }
    }

    如果要在同一个Action method上重复使用一个过滤器,那么在定义该过滤器时,需要加上属性:

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]

    如果没有此属性,会产生Duplicate attribute错误。

    (2)在HomeController的Index()动作方法上,以注解属性使用过滤器:

    namespace _13_21MvcFilters.Controllers
    {
        public class HomeController : Controller
        {
            [SimpleMessage(Message = "A", Order = 1)]
            [SimpleMessage(Message = "B", Order = 2)]
            public ActionResult Index()
            {
                Response.Write("Action Method is running...<br>");
                return View();
            }
        }
    }

    Index.cshtml视图为:

    @{
        ViewBag.Title = "Index";
    }
    
    <h2>Index</h2>

    (3)在Global.asax中,将过滤器SimpleMessageAttribute注册为全局过滤器,成为全局过滤器后,不需要显式的用注解属性来使用它,所有的动作方法都会自动施加该过滤器。

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
                filters.Add(new SimpleMessageAttribute() { Message = "Global" , Order = 1});
            }

    这样一来,施加在HomeController中,动作方法Index上的过滤器就相当于有3处,他们都设定了Order,按照Order的升序依次执行。最先执行的是全局过滤器。

    如果没有设置Order,最先执行的是全局过滤器,而按照注解属性来使用的过滤器,执行顺序是不确定的(并不是按照出现的先后顺序来执行)

    -lyj

  • 相关阅读:
    13.6 线程通信
    13.5 线程同步
    13.4 控制线程
    13.3 线程的生命周期
    13.2 线程的创建与启动
    13.1 线程概述
    12.10 NIO.2的功能和用法
    bs4
    mysql基本命令
    HDU-1021 Fibonacci Again
  • 原文地址:https://www.cnblogs.com/brown-birds/p/3770261.html
Copyright © 2011-2022 走看看