前面的篇幅中,瞭解到了控制器的生成的過程以及在生成的過程當中的各類注入點,依照常理來講篇幅應該到了解說控制器內部的運行過程以及模型綁定、驗證這些知識了。html
但是呢,在MVC框架中提供了一種機制在控制器方法運行以前咱們還可以經過這樣的機制來作一些橫向切面的操做,這樣的機制的實現就是過濾器了。在本篇和興許的篇幅中將會對幾種過濾器作一番解說,並且會對過濾器在框架中的一個運行過程進行粗略的解說。編程
咱們在得到控制器工廠生成的控制器後。運行某些控制器行爲以前。老是要驗證一些數據或者是請求信息什麼的。這裏就要用到過濾器的機制了,而在框架中過濾器是怎麼運轉的,經過本小節的學習會讓你有個大概的瞭解。框架
現在咱們切入主題來解說一下在MVC框架中的過濾器。ide
圖1函數
如上圖所看到的的這樣,在控制器運行的時候會調用ControllerActionInvoker類型的InvokeAction()方法,而在InvokeAction()方法中,框架會默認的生成控制器描寫敘述對象ControllerDescriptor和控制器行爲描寫敘述對象ActionDescriptor。這兩種類型的對象都是對當前的控制器和所要請求的控制器方法信息的封裝,這個知識點咱們會在興許的篇幅中講到,這裏僅僅須瞭解一下,忽略它們的生成過程。參照例如如下圖:工具
圖2post
依照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 }spa
它的內部有着四種過濾器集合類型的屬性,並且有個構造函數是接收IEnumerable<Filter>類型的。當FilterInfo類型在初始化的時候會依據構造函數傳入的類型進行解析,並且對四個屬性分別賦值,這就要涉及到還有一個元數據描寫敘述對象Filter了。.net
咱們來看一下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 : Controller 3 { 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 IFilterProvider 3 { 4 IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor); 5 }
而這個對象是可以從外部注入進來的。在控制器(三)中提到過的。經過實現IDependencyResolver類型,而在框架中也會默認的實現一個(僅僅是我經過反編譯工具沒看到,顯示的是錯誤信息。表示很是鬱悶,後文中就叫它爲默認實現)。在FilterProviderCollection類型的GetFilters()中,會經過默認實現來獲得當前請求的行爲上的所有過濾器元數據描寫敘述對象,並且進行排序、驗證。這裏就很少敘述了。而後返回IEnumerable<Filter>集合類型並且生成FilterInfo類型的對象。
圖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://blog.csdn.net/jinyuan0829
本文版權歸做者和CSDN共同擁有,歡迎轉載,但未經做者容許必須保留此段聲明,且在文章頁面