zoukankan      html  css  js  c++  java
  • MVC之 自定义过滤器(Filter)

    一、自定义Filter

      自定义Filter需要继承ActionFilterAttribute抽象类,重写其中需要的方法,来看下ActionFilterAttribute类的方法签名。

    复制代码
        //表示所有操作-筛选器特性的基类。
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
        public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
        {
            protected ActionFilterAttribute();
            //    在Action执行之后由 MVC 框架调用。
            public virtual void OnActionExecuted(ActionExecutedContext filterContext);
            //     在Action执行之前由 MVC 框架调用。
            public virtual void OnActionExecuting(ActionExecutingContext filterContext);
            //     在执行Result后由 MVC 框架调用。
            public virtual void OnResultExecuted(ResultExecutedContext filterContext);
            //     在执行Result之前由 MVC 框架调用。
            public virtual void OnResultExecuting(ResultExecutingContext filterContext);
        }
    复制代码

    因此自定义过滤器可以选择适当的方法来重写方可。下面来举个简单的例子:检查登录状态的过滤器,没有登录则跳转到登录页

      控制器代码:

    复制代码
            [CheckLogin]  //此处为自定义属性,要引用相应的命名空间
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult Login()   //此Action自动往cookie里写入登录信息
            {
                HttpCookie hcUserName = new HttpCookie("username","admin");
                HttpCookie hcPassWord = new HttpCookie("password","123456");
                System.Web.HttpContext.Current.Response.SetCookie(hcUserName);
                System.Web.HttpContext.Current.Response.SetCookie(hcPassWord);
                return View();
            }
    复制代码

      过滤器代码

    复制代码
        public class CheckLogin : ActionFilterAttribute
        {
            //在Action执行之前 乱了点,其实只是判断Cookie用户名密码正不正确而已而已。
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                HttpCookieCollection CookieCollect = System.Web.HttpContext.Current.Request.Cookies;if (CookieCollect["username"] == null || CookieCollect["password"] == null)
                {
                    filterContext.Result = new RedirectResult("/Home/Login");
                }
                else
                {
                    if (CookieCollect["username"].Value != "admin" && CookieCollect["password"].Value != "123456")
                    {
                        filterContext.Result = new RedirectResult("/Home/Login");
                    }
                }
            }
        }//本示例贪图方便,将要跳转到的Action放在同一个Controller下了,如果将过滤器放到Controller类顶部,则永远也跳不到这个LoginAction。
    复制代码

      此过滤器实现的效果是,当用户Cookie中用户名和密码不正确则跳转到登录页,注意过滤器也可以放在整个Controller类的顶部,表示该Controller下的所有Action都执行该项检查。这样一来,控制器里的代码非常漂亮,再也不用所有的Action里都充斥着判断登录的代码了。

    二、带参数的自定义Filter

      首先,还是按照之前添加自定义过滤器的方法,添加一个自定义过滤器,只是里面多了一个属性,代码如下:

    复制代码
        public class FilterAttribute : ActionFilterAttribute
        {
            public string Message { get; set; }
    
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                base.OnActionExecuting(filterContext);
                filterContext.HttpContext.Response.Write("Action执行之前" + Message + "<br />");
            }
    
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                base.OnActionExecuted(filterContext);
                filterContext.HttpContext.Response.Write("Action执行之后" + Message + "<br />");
            }
    
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
                base.OnResultExecuting(filterContext);
                filterContext.HttpContext.Response.Write("返回Result之前" + Message + "<br />");
            }
    
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                base.OnResultExecuted(filterContext);
                filterContext.HttpContext.Response.Write("返回Result之后" + Message + "<br />");
            }
        }
    复制代码

      然后在调用过滤器的时候,添加上该参数,Controller代码如下:

            [Filter(Message="刘备")]  //参数给上
            public ActionResult Index()
            {
                return View();
            }

      输出结果如下:

      

       如果标签打到Controller上的话,TestFilterAttributeFilter将作用到Controller下的所有的Action。

      默认情况下Action上打了某个自定义标签后,虽然在Controller上也打上了此标签,但它只有Action上的标签起作用了。
      补充:如果Action没有打上该标签,那么Controller上的标签便会被执行。

       如果想让Action上的标签执行一次,然后Controller上的标签也执行一次,那么应该如何操作呢?

       我们只需在FilterAttribute类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]即可【下面类的最上面红色字体部分】,也就是让其成为可以多次执行的Action代码如下:

        [AttributeUsage(AttributeTargets.All,AllowMultiple = true)]
        public class FilterAttribute : ActionFilterAttribute
        {
            public string Message { get; set; }
            ......

    三、全局过滤器  

      有时我们想有些公共的方法需要每个Action都执行,但是又不想再每一个Controller上都打上Action标签,怎么办?幸好Asp。Net MVC3带来了一个美好的东西,全局Filter。而怎么注册全局Filter呢?答案就在Global.asax中。让我们看以下代码,我是如何将上面我们定义的TestFilterAttribute 注册到全局Filter中。

         public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
                //注册全局过滤器
                filters.Add(new TestFilterAttribute() { Message="全局"});
            }

      这样就每个Action都会执行此过滤器,而不必每个Controller顶部都加上标签。

  • 相关阅读:
    微服务架构技术栈选型手册(万字长文)
    Visual Studio 2013 always switches source control plugin to Git and disconnect TFS
    Visual Studio 2013 always switches source control plugin to Git and disconnect TFS
    MFC对话框中使用CHtmlEditCtrl
    ATL开发 ActiveX控件的 inf文件模板
    ActiveX: 如何用.inf和.ocx文件生成cab文件
    Xslt 1.0中使用Array
    如何分隔两个base64字符串?
    An attempt was made to load a program with an incorrect format
    JQuery 公网 CDN
  • 原文地址:https://www.cnblogs.com/Alex80/p/4383139.html
Copyright © 2011-2022 走看看