本文,介紹了Filter在MVC請求的生命週期中的做用和角色,以及Filter的一些經常使用應用場景。 同時針對MVC中的對於Session,Cookie等的依賴,如何使用Filter解依賴。session
若是你們有什麼好的Filter應用方法,但願一塊兒多交流。mvc
閱讀目錄:asp.net
1、Filter在MVC生命週期中的位置ide
2、Filter常見的應用場景單元測試
3、Filter的執行順序測試
4、MVC中常見的對於Session, Cookie的依賴spa
5、使用Filter解除依賴.net
下面的圖中, 一個完成的MVC的生命週期分爲5個步驟, 對應圖例中的1~5日誌
Filter在MVC的生命週期中的角色就像是一個一個的截面,在MVC的處理過程當中,攔截請求。code
Filter分爲:
Authorization filters – 須要實現IAuthorizationFilter接口,用於驗證處理驗證相關的操做
Action filters –須要實現IActionFilter接口. 在Action處理的開始和結束作攔截操做
Result filters – 須要實現IResultFilter接口. 在View呈現前和呈現後作處理
Exception filters – 須要實現IExceptionFilter接口,只要是添加了Exception Filter的請求中出現異常,都會被攔截
每一個Filter的做用時機,對應於下圖中的2a, 2b, 4a, 4b.
下面是我的在開發中,經常使用到的Filter處理:
權限驗證
使用Authorization filters,攔截請求,在進入到Controller處理以前,驗證用戶是否登陸或者登陸用戶是否有權限訪問改頁面。
若是合法,就繼續交由Controller處理,若是非法,中斷流程,跳轉到登陸頁面。
日誌記錄
經過Action Filter跟蹤記錄Action處理開始的時間,結束時間,訪問的具體Controller和Action, 參數,訪問者ip等信息。
異常處理
異常處理Exception filter可以在發生異常的時候,記錄異常信息。若是是session過時引發的異常,則跳轉到登陸頁面,若是是程序運行致使的沒法處理異常,則跳轉到友好的錯誤頁面。
提高SEO效果
每篇博客文章的meta信息可以幫助提升SEO效果,可是不少人對於填寫keyword, description等信息以爲太繁瑣。
可使用Result filters,在最後呈現頁面前,使用程序分析內容,提取keyword和description來,而後填充到meta信息中。
這樣,每篇博客文章都可以有程序實現最佳的SEO效果,甚至生成一份SEO報告出來。
Filter之間執行的順序,首先根據類型區分:
分別是Authorization filters, Action filters, Result filters. Exception Filter沒有列入的緣由是, 它是在發生異常的時候處理,沒有特定的順序。
當同時一個類型的Filter的時候,執行順序能夠經過Filter的Order屬性來排序。
在Web程序中,對於Session和Cookie等的使用是必不可少的。
好比, 不少的Action的代碼中,會要從Session中獲取當前登陸用戶信息:
public ActionResult Index() { var user = Session[「UserAccuont」];//從Session中獲取當前登陸用戶的信息 //send email var email = user.Email; ………… }
上面的Index方法的問題就是和Session耦合,很難單元測試。
下面介紹如何使用Filter來解除對於Session的依賴。
添加一個SessionUserParameterAttribute的Action Filter, 它的功能是:
從Session中取得User, 將取得的User賦值給Action中的參數sessionUser.
public class SessionUserParameterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { const string key = "sessionUser"; if (filterContext.ActionParameters.ContainsKey(key)) { filterContext.ActionParameters[key] = Session[「UserAccuont」];//爲Action設置參數 } base.OnActionExecuting(filterContext); } }
改造後的Index Action方法以下:
[SessionUserParameter] public ActionResult Index(UserAccount sessionUser) { //send email var email = sessionUser.Email; ………… }
這樣Index方法就解除了對於Session的依賴, 而只是依賴於一個普通的實體類UserAccount.
在單元測試中,只須要簡單的構造一個UserAccount的對象就能夠了。