本篇講解行爲過濾器的執行過程,過濾器實現、使用方式有AOP的意思,能夠經過學習瞭解過濾器在框架中的執行過程從而得到一些AOP方面的知識(在順序執行的過程當中,這種編程模式就是橫向的插入點),言歸正傳,咱們仍是以學習過濾器爲主。對於IAuthorizationFilter受權認證過濾器的使用篇幅,我知道怎麼用可是寫不出來,裏面包含知識點不少,功底尚淺寫了一半又給刪掉了,寧願不發也不能坑人,在後面的學習中假使我能夠掌握了,必定會及時的寫出來跟你們分享。這個目錄也空在這也算是給本身的一個提醒吧。編程
過濾器在系統框架中的總體對象模型c#
IAuthorizationFilter受權認證過濾器的執行過程框架
使用IAuthorizationFilter過濾器ide
IActionFilter行爲過濾器的執行過程學習
自定義實現IActionFilter行爲過濾器this
異常過濾器的使用spa
咱們直接進入主題,這裏的執行過程仍是接着過濾器(一)中的部分,咱們看下執行過程的示意圖:xml
圖1對象
如圖1所示,就是整個的一個執行過程,圖太大拆開來看,這樣比較細緻一點(這裏捎帶一句,後面許多部分的內容都都包含在這個示意圖裏,好比說Model元數據、Model綁定和Model驗證)。繼承
圖2
首先是調用了ControllerActionInvoker類型的GetParameterValues()方法,GetParameterValues()方法的參數是控制器上下文參數對象【ControllerContext類型】和控制器方法描述對象【ActionDescriptor類型】,而後在此方法中會根據ActionDescriptor類型的參數來調用GetParameters()方法獲取到控制器方法參數的描述對象【ParameterDescriptor類型】的集合,這裏對ParameterDescriptor類型不作過多的講解,只需瞭解它是包含了控制器方法參數的一些信息,好比說參數名稱、參數類型等等。
圖3
從圖2中所示的那樣,獲取到了ParameterDescriptor類型的集合後,便會遍歷此集合而且調用圖3中所示的ControllerActionInvoker類型的GetParameterValue()方法【這裏注意一下跟上面的圖2所示的方法是不一樣的】,調用GetParameterValue()方法的目的是生成一個鍵值隊類型的對象【紅色箭頭所指】,鍵值隊中的鍵表示參數名稱,值則爲參數的值,而生成的過程是:首先MVC框架會調用用戶自定義的模型綁定器(若是有自定義的)【實現了IModelBinder接口的類型】,而且調用自定義模型綁定器的方法以此來獲取控制器方法參數的參數值,若是沒有發現自定義的模型綁定器,則會調用默認的Model綁定器進行參數綁定,若是沒有匹配的類型返回一個默認值【ParameterDescriptor.DefaultValue】。(關於Model綁定器內容後續系列會有講解)
圖4
有了參數值信息的鍵值隊事後,接着調用ControllerActionInvoker類型的InvokeActionMethodWithFilters()方法,在此方法會生成兩種參數類型以便由ControllerActionInvoker類型的InvokeActionMethodFilter()方法調用,下面咱們先講解這兩種參數類型:
ActionExecutingContext
Func<ActionExecutedContext>
第一個參數
1 public class ActionExecutingContext : ControllerContext 2 { 3 public ActionExecutingContext(); 4 public ActionExecutingContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> actionParameters); 5 6 public virtual ActionDescriptor ActionDescriptor { get; set; } 7 public virtual IDictionary<string, object> ActionParameters { get; set; } 8 public ActionResult Result { get; set; } 9 }
在上面類型的定義中,咱們瞭解到ActionExecutingContext類型繼承至ControllerContext類型,而且包含着一些信息的引用,這即是能夠在控制器方法執行以前執行本身的一些自定義操做。
第二個參數
1 public class ActionExecutedContext : ControllerContext 2 { 3 4 public ActionExecutedContext(); 5 public ActionExecutedContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, bool canceled, Exception exception); 6 7 public virtual ActionDescriptor ActionDescriptor { get; set; } 8 public virtual bool Canceled { get; set; } 9 public virtual Exception Exception { get; set; } 10 public bool ExceptionHandled { get; set; } 11 public ActionResult Result { get; set; } 12 }
ActionExecutedContext類型跟ActionExecutingContext類型的區別在於前者多了兩個屬性一個是用於保存異常信息的,另外一個屬性是用來設置是否處理了異常,這個會在異常過濾器篇幅中講解。
切回主題,大概知道這兩種類型的定義就好了,說到Func<ActionExecutedContext>類型的參數,在MVC框架中默認的設置了Lambda表達式,而且對返回類型中的Result屬性又設置了一個表達式調用的是ControllerActionInvoker類型的InvokeActionMethod()方法,這個方法後面會講到。咱們看一下表達式的定義,否則有點混亂:
1 Func<ActionExecutedContext> seed = () => 2 { 3 new ActionExecutedContext(controllerContext,actionDescriptor, false,null) 4 { 5 Result = this.InvokeActionMethod(controllerContext, actionDescriptor, parameters) 6 } 7 };
上述的這些參數都準備完畢後,能夠調用執行最後的ControllerActionInvoker類型的InvokeActionMethodFilter()方法,而其中的IActionFilter類型的參數則有在前面篇幅中講到的FilterInfo類型中的ActionFilters屬性提供,而且是遍歷執行的,最後能夠看到在InvokeActionMethodFilter()方法的內部首先是由IActionFilter類型的參數調用了OnActionExecuting()方法,而後執行Func<ActionExecutedContext>類型的參數,由於上面說到的,這個委託類型的參數已經定義好了默認的執行方式,是執行ControllerActionInvoker類型的中的InvokeActionMethod()方法,在此方法執行後在執行IActionFilter類型的OnActionExecuted()方法,而且最終的結果值返回到了ActionExecutedContext類型的Result屬性中。
最後咱們看一下IActionFilter類型的結構定義:
1 public interface IActionFilter 2 { 3 // 摘要: 4 // 在執行操做方法後調用。 5 // 6 // 參數: 7 // filterContext: 8 // 篩選器上下文。 9 void OnActionExecuted(ActionExecutedContext filterContext); 10 // 11 // 摘要: 12 // 在執行操做方法以前調用。 13 // 14 // 參數: 15 // filterContext: 16 // 篩選器上下文。 17 void OnActionExecuting(ActionExecutingContext filterContext); 18 }
行爲過濾器大概的執行過程講解完畢了,下一篇會對這種類型的過濾器的應用做大概講解。