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標簽,怎么辦?幸好AspNet MVC3帶來了一個美好的東西,全局Filter。而怎么注冊全局Filter呢?答案就在Global.asax中。讓我們看以下代碼,我是如何將上面我們定義的TestFilterAttribute 注冊到全局Filter中。

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

  這樣就每個Action都會執行此過濾器,而不必每個Controller頂部都加上標簽。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM