zoukankan      html  css  js  c++  java
  • 【转】MVC之 自定义过滤器(ActionFilterAttribute)

    原文地址:https://www.cnblogs.com/hnsongbiao/p/8717553.html


    一、自定义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();
            }
    
        </span><span style="color: #0000ff;">public</span> ActionResult Login()   <span style="color: #008000;">//</span><span style="color: #008000;">此Action自动往cookie里写入登录信息</span>
    

    {
    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; }
    
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> OnActionExecuting(ActionExecutingContext filterContext)
        {
            </span><span style="color: #0000ff;">base</span><span style="color: #000000;">.OnActionExecuting(filterContext);
            filterContext.HttpContext.Response.Write(</span><span style="color: #800000;">"</span><span style="color: #800000;">Action执行之前</span><span style="color: #800000;">"</span> + Message + <span style="color: #800000;">"</span><span style="color: #800000;">&lt;br /&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        }
    
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> OnActionExecuted(ActionExecutedContext filterContext)
        {
            </span><span style="color: #0000ff;">base</span><span style="color: #000000;">.OnActionExecuted(filterContext);
            filterContext.HttpContext.Response.Write(</span><span style="color: #800000;">"</span><span style="color: #800000;">Action执行之后</span><span style="color: #800000;">"</span> + Message + <span style="color: #800000;">"</span><span style="color: #800000;">&lt;br /&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        }
    
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> OnResultExecuting(ResultExecutingContext filterContext)
        {
            </span><span style="color: #0000ff;">base</span><span style="color: #000000;">.OnResultExecuting(filterContext);
            filterContext.HttpContext.Response.Write(</span><span style="color: #800000;">"</span><span style="color: #800000;">返回Result之前</span><span style="color: #800000;">"</span> + Message + <span style="color: #800000;">"</span><span style="color: #800000;">&lt;br /&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        }
    
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> OnResultExecuted(ResultExecutedContext filterContext)
        {
            </span><span style="color: #0000ff;">base</span><span style="color: #000000;">.OnResultExecuted(filterContext);
            filterContext.HttpContext.Response.Write(</span><span style="color: #800000;">"</span><span style="color: #800000;">返回Result之后</span><span style="color: #800000;">"</span> + Message + <span style="color: #800000;">"</span><span style="color: #800000;">&lt;br /&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        }
    }</span></pre>
    
    复制代码

    后在调用过滤器的时候,添加上该参数,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带
    复制代码
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                filters.Add(new HandleErrorAttribute());
                //注册全局过滤器
                filters.Add(new TestFilterAttribute() { Message="全局"});
            }
    复制代码

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



    如果您认为这篇文章还不错或者有所收获,您可以通过右边的“打赏”功能 打赏我一杯咖啡【物质支持】,也可以点击文章下方“推荐”按钮【精神支持】,您的“推荐”将是我最大的写作动力!
    欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,凡是转载于本人的文章,不能设置打赏功能,如有特殊需求请与本人联系!
  • 相关阅读:
    h.264宏块与子宏块类型
    h.264语法结构分析
    [傅里叶变换及其应用学习笔记] 关于任何信号都能表现成傅里叶级数形式的推导
    [傅里叶变换及其应用学习笔记] 课程概览
    [傅里叶变换及其应用学习笔记] 三十. 拉东变换
    [傅里叶变换及其应用学习笔记] 二十九. 高维Ш函数修改版
    后端解决 微信H5支付 商户参数格式错误 方法
    PhpStorm一次性折叠所有函数或者方法
    js生成的cookie在yii2中获取不到的解决办法
    Android webview 调起H5微信支付
  • 原文地址:https://www.cnblogs.com/dawenxi0/p/11193505.html
Copyright © 2011-2022 走看看