請注明轉載地址:http://www.cnblogs.com/arhat
今天老魏和大家一起討論一下ASP.NET MVC中非常重要的一個知識:“過濾器”。那么這個“過濾器”乍一聽好像在ASP.NET中並沒有這個東東,反而在J2EE中常常提到這個知識,其實在傳統的ASP.NET中是存在“過濾器”的,只不過我們平時並沒有注意到它。反而到ASP.NET MVC中,這個“過濾器”就提到一個非常重要的位置。“過濾器”可以使我們在實現某些操作的時候非常的重要,如果沒有“過濾器”那么實現某些功能的時候就比較困難,比如登錄驗證等操作,或者是處理一些敏感的數據。
那么下面我們看看什么是“過濾器”。從名字上看“過濾器”的意思是就是把一些不需要東西給過濾掉,其實就像我們平時的下水管道一樣,有一個過濾網,這個過濾網就是把一下事物殘渣過濾掉,防止堵塞下水管道。那么在ASP.NET MVC中的“過濾器”也是這個作用。
只不過在ASP.NET MVC過濾器中所過濾的不是水,而是一個HttpRequest.而食物殘渣就好比是HttpRequest所帶的數據,我們可以定義一下過濾器的規則,把不需要的數據給過濾掉,只把合法的數據傳遞到服務器中並處理。
在Asp.net Mvc中當你有以下及類似以下需求時你可以使用Filter功能
1. 判斷登錄與否或用戶權限
2. 決策輸出緩存
3. 防盜鏈
4. 防蜘蛛
5. 本地化與國際化設置
6. 實現動態Action
上面說了那么多文字內容,可能還是不是很清楚過濾器所處的位置,那么下面我們通過一個圖來了解一下這個“過濾器”。
這個圖是老魏自己畫的,沒有采用微軟的圖。在瀏覽器發送請求的時候,這個請求會會在執行Action之前先過濾一下這個請求,把合法內容留下並傳遞給Aciton執行,當執行完畢之后服務器把處理結果發送給瀏覽器之前也就是執行Action之后還得在經歷一個過濾器,這個過濾器可以什么都不做,也可以對Action的執行結果進行修改再次的發送給瀏覽器。這個就是過濾器的執行過程。
在APS.NET MVC中提供幾種默認的過濾器。
Filter Type | 實現接口 | 執行時間 | Default Implementation |
Authorization filter | IAuthorizationFilter | 在所有Filter和Action執行之前執行 | AuthorizeAttribute |
Action filter | IActionFilter | 分別在Action執行之前和之后執行。 | ActionFilterAttribute |
Result filter | IResultFilter | 分別在Action Result執行之后和之前 | ResultFilterAttribute |
Exception filter | IExceptionFilter | 只有在filter, 或者 action method, 或者 action result 拋出一個異常時候執行 |
HandleErrorAttribute |
這四種過濾器AuthorizeAttribute,ActionFilterAttribute,ResultFilterAttribute,HandleErrorAttribute都是ASP.NET MVC提供的默認過濾器。如果我們要使用這些過濾器的時候,需要繼承這些類。由於這些類都是Attribute,所以我們的子類必須是以Attribute結尾的。
那么我們以ActionFilterAttribute為例來介紹一下過濾器。這個過濾器是針對Action的,那么這個Attribute必須只能作用於Action,也就是在Action執行之前,執行之后的過濾器。
在ActionFilterAttribute中,提供了四種方法來處理Action的請求過濾。
//在Action執行之后 public virtual void OnActionExecuted(ActionExecutedContext filterContext); //在Action執行之前 public virtual void OnActionExecuting(ActionExecutingContext filterContext); //解析ActionResult前執行 public virtual void OnResultExecuted(ResultExecutedContext filterContext); //解析ActionResult后執行 public virtual void OnResultExecuting(ResultExecutingContext filterContext);
我們來試驗一下,在我們的項目中創建一個文件夾Filter用來存放我們的過濾器。
首先,我們在Filter文件夾中創建一個過濾器“MyActionFilter.cs”,內容如下:
public class MyActionFilterAttribute:ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.HttpContext.Response.Write("執行Action之前....<br/>"); } public override void OnActionExecuted(ActionExecutedContext filterContext) { filterContext.HttpContext.Response.Write("執行Action之后....<br/>"); } public override void OnResultExecuting(ResultExecutingContext filterContext) { filterContext.HttpContext.Response.Write("呈現View之前....<br/>"); } public override void OnResultExecuted(ResultExecutedContext filterContext) { filterContext.HttpContext.Response.Write("呈現View之后....<br/>"); } }
同時,我們需要在HomeController的Index方法之上添加這個Filter
[Filter.MyActionFilter] public ActionResult Index() { return View(); }
那么我們來運行一下。看一下結果。
發現的確正如我們所猜測的那樣。但是這個例子只是給大家說名一下這個過濾器的四個方法分別是在什么之后執行的。
那么我們就可以利用這個可以實現登錄驗證的操作,比如我們的每個Action執行之前都需要判斷用戶有沒有登錄,如果沒有登錄那么就讓他訪問對應的Action。所以這個操作應該是在Action之前要判斷的。
我們更改一下MyActionFilterAttribute的方法。
public override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.HttpContext.Request.Cookies["user"] == null || filterContext.HttpContext.Request.Cookies["user"].Value == "") { filterContext.Result = new RedirectToRouteResult("default", new System.Web.Routing.RouteValueDictionary(new { controller="Login",action="index"})); } filterContext.HttpContext.Response.Write("執行Action之前....<br/>"); }
當檢查發送過來的請求,如果沒有對應的cookie 則我們跳轉到登錄頁面。運行效果如下:
不知道本章大家有沒有明白什么是過濾器呢?在以后的知識介紹中,我們還會使用過濾器,這個比較重要哦!好了,本章就到此結束吧!