作廢
一、自定義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頂部都加上標簽。