標籤:des style class blog code http
ASP.NET MVC 過濾器(一)前言
前面的篇幅中,瞭解到了控制器的產生的過程以及在產生的過程中的各種注入點,按照常理來說篇幅應該到了講解控制器內部的執行過程以及模型繫結、驗證這些知識了。但是呢,在MVC架構中提供了一種機制在控制器方法執行之前我們還可以通過這種機制來做一些橫向切面的操作,這種機制的實現就是過濾器了,在本篇和後續的篇幅中將會對幾種過濾器做一番講解,並且會對過濾器在架構中的一個執行過程進行粗略的講解。
ASP.NET MVC過濾器
- 過濾器在系統架構中的整體物件模型
- IAuthorizationFilter授權認證過濾器的執行過程
- 使用IAuthorizationFilter過濾器
- IActionFilter行為過濾器的執行過程
- 自訂實現IActionFilter行為過濾器
- 異常過濾器的使用
過濾器在系統架構中的整體物件模型
我們在獲得控制器工廠產生的控制器後,執行某些控制器行為之前,總是要驗證一些資料或者是請求資訊什麼的,這裡就要用到過濾器的機制了,而在架構中過濾器是怎麼運轉的,通過本小節的學習會讓你有個大概的瞭解。
現在我們切入主題來講解一下在MVC架構中的過濾器。
圖1
如所示的這樣,在控制器執行的時候會調用ControllerActionInvoker類型的InvokeAction()方法,而在InvokeAction()方法中,架構會預設的組建控制器描述對象ControllerDescriptor和控制器行為描述對象ActionDescriptor,這兩種類型的對象都是對當前的控制器和所要請求的控制器方法資訊的封裝,這個知識點我們會在後續的篇幅中講到,這裡只須瞭解一下,忽略它們的產生過程。參照如:
圖2
按照InvokeAction()方法的執行流程,到了產生FilterInfo類型的時候,我們都知道MVC架構給我們提供了四種過濾器,哪四種後面一一介紹,那麼FilterInfo類型是幹什麼的呢?來看一下它的對象結構:
1 //封裝有關可用的操作篩選器的資訊。 2 public class FilterInfo 3 { 4 public FilterInfo(); 5 public FilterInfo(IEnumerable<Filter> filters); 6 public IList<IActionFilter> ActionFilters { get; } 7 public IList<IAuthorizationFilter> AuthorizationFilters { get; } 8 public IList<IExceptionFilter> ExceptionFilters { get; } 9 public IList<IResultFilter> ResultFilters { get; }10 }
它的內部有著四種過濾器集合類型的屬性,並且有個建構函式是接收IEnumerable<Filter>類型的,當FilterInfo類型在初始化的時候會根據建構函式傳入的類型進行解析,並且對四個屬性分別賦值,這就要涉及到另一個中繼資料描述對象Filter了。
我們來看一下Filter對象的結構:
1 // 表示一個中繼資料類,它包含對一個或多個篩選器介面的實現、篩選器順序和篩選器範圍的引用。 2 public class Filter 3 { 4 public const int DefaultOrder = -1; 5 public Filter(object instance, FilterScope scope, int? order); 6 7 public object Instance { get; protected set; } 8 public int Order { get; protected set; } 9 public FilterScope Scope { get; protected set; }10 }
看到這裡有可能有的朋友不明白這個對象,具體怎麼表示?因為中繼資料編程模式很少見,這裡我給大家舉個例子,一看就明白了:
1 [Authorize(Order=1)]2 public class DemoController : Controller3 {4 ……5 }
上面的這個列子則會在系統產生的時候產生一個Filter類型的對象,並且賦值Order等於1,而Filter類型中的Instance屬性則是對上述例子中的Authorize類型執行個體引用,這就是中繼資料描述對象,當然了講的不是太詳細,能讓大家明白就行了,Authorize類型的具體使用在下一篇中會有講到。
現在我們迴歸主題,2中所表示的那樣,IEnumerable<Filter>集合類型是關鍵,那麼怎麼產生IEnumerable<Filter>集合類型?
先是調用ControllerActionInvoker類型中的GetFilters()方法,我們看到方法的參數類型為控制器參數內容物件和控制器行為中繼資料描述對象,這兩個對象就夠了,它們中包含的資訊已經很多了,在ControllerActionInvoker的GetFilters()方法內部調用FilterProviderCollection類型的GetFilters(),和上面所述的類型方法簽名一樣,只不過傳回型別有差異而已,而真正的根據參數執行產生Filter類型的對象是實現了IFilterProvider類型的對象,
看一下IFilterProvider類型的結構:
1 // 提供用於尋找篩選器的介面。2 public interface IFilterProvider3 {4 IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor);5 }
而這個對象是可以從外部注入進來的,在控制器(三)中提到過的,通過實現IDependencyResolver類型,而在架構中也會預設的實現一個(只是我通過反編譯工具沒看到,顯示的是錯誤資訊,表示很鬱悶,後文中就叫它為預設實現)。在FilterProviderCollection類型的GetFilters()中,會通過預設實現來得到當前請求的行為上的所有過濾器中繼資料描述對象,並且進行排序、驗證,這裡就不多敘述了。然後返回IEnumerable<Filter>集合類型並且產生FilterInfo類型的對象。
IAuthorizationFilter授權認證過濾器的執行過程
圖3
先來看一下IAuthorizationFilter類型的定義:
1 public interface IAuthorizationFilter 2 { 3 // 摘要: 4 // 在需要授權時調用。 5 // 6 // 參數: 7 // filterContext: 8 // 篩選器上下文。 9 void OnAuthorization(AuthorizationContext filterContext);10 }
看到如上的定義,再看圖3IAuthorizationFilter類型的執行過程一目瞭然,根據ControllerContext控制器參數內容物件和控制器行為據描述對象actionDescriptor產生AuthorizationContext授權認證過濾器參數內容物件,並且會遍曆FilterInfo類型中的AuthorizationFilters屬性,挨個的去執行我們定義的過濾器。
本篇的內容就講到這裡,下個篇幅中會講到IAuthorizationFilter類型的使用
金源
出處:http://www.cnblogs.com/jin-yuan/
本文著作權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面