上篇對於Model綁定的簡單演示想必你們對Model綁定的使用方式有一點的瞭解,那你們有沒有想過Model綁定器是在何時執行的?又或是執行的過程是什麼樣的?將在本篇爲你們解除這些疑惑,在其中涉及到的一些描述類型和上下文參數會在後續的篇幅中講到。框架
不廢話直接進入主題,Model綁定器顧名思義是爲了Model的綁定提供幫助的這麼一個功能模塊,暫且就這麼理解。Model這裏所指的就是ViewModel,通常都是在控制器方法參數中使用Model,從而使Model綁定器可使用起來,但是有沒有想過爲何要這樣用呢?世間的事物都是有因果的,固然這樣的使用方式也逃脫不了,這跟MVC框架中生成Model綁定器的位置是有關係的,咱們來看示意圖1。ide
圖1工具
看到圖1,可能有的朋友可能以爲很突兀,這裏建議朋友們先去看一下博主前面所寫過的ASP.NET MVC過濾器系列的文章,看過的朋友確定就會以爲很熟悉了,但也要考慮沒有看過前面篇幅的朋友。this
ControllerActionInvoker類型的InvokeAction()方法是MVC框架中執行控制器方法的必經方法,咱們就按照圖1所示的來說解,黃色的指示線條爲主要流程(雖然不是流程圖)。首先MVC會生成一個ControllerDescriptor類型,而後根據ControllerDescriptor類型再生成ActionDescriptor類型,而後再根據ActionDescriptor類型生成FilterInfo類型的對象,對於ControllerDescriptor類型和ActionDescriptor類型分別表示着控制器描述類型(對象內部包含着控制器的各類信息)和控制器方法描述類型(同控制器描述類型一個意思),這兩個類型的含義和生成過程後面篇幅會有講解,這裏暫時只需瞭解它們表明着什麼就行。spa
對於FilterInfo類型的解釋是它包含着當前所被調用的控制其方法上的全部過濾器信息(博主仍是建議朋友們去看ASP.NET MVC過濾器系列的文章),從它的結構中能夠看出它包含着各類類型過濾器類型集合對象屬性。code
重點來了,從圖1中能夠看出MVC框架會先執行受權認證IAuthorizationFilter過濾器,在執行完IAuthorizationFilter過濾器後和執行控制器行爲過濾器IActionFilter以前,MVC會根據ActionDescriptor類型獲取到ParameterDescriptor類型的對象【這裏說句題外話看過前面Model元數據的朋友,想必知道ParameterDescriptor類型和Model元數據的都是用來描述Model的,ParameterDescriptor類型重在描述Model自己,而Model元數據更側重於Model的外部修飾,感嘆MVC的強大】。對象
而後再根據ParameterDescriptor類型中ParameterType屬性,表示着Model的類型(Type類型)來生成Model綁定器(IModelBinder),至於生成的細節在下一小節來說解,不能搶樓下的生意。blog
想必你們如今知道爲何要把ViewModel放在控制器方法中做爲參數來使用了吧。ip
本小節講解Model綁定器生成的具體過程,也不是太複雜,而且會在後續篇幅控制器方法執行篇幅會將這些知識點所有串聯起來。get
如今咱們仍是先看一下Model綁定器生成的細節吧,圖2
圖2
(黑體字部分表示爲屬性名稱,黑體字前面的青色表示屬性類型,而在黑體字上面的表示屬性所屬類型)
按照圖2所示的來說解,首先MVC調用了ControllerActionInvoker類型的GetModelBinder ()方法來生成IModelBinder類型,在方法的內部,MVC首先會判斷參數parameterDescriptor中的BindingInfo屬性中的Binder屬性是否爲空,若是爲空的話(此部份內容在下篇中會詳解ParameterDescriptor類型,而且以反推的方法來往上講解幾種描述類型),則是調用ControllerActionInvoker類型中的Binders屬性。
如今咱們就來看一下Binders屬性的定義,如代碼1-1。
代碼1-1
protected internal ModelBinderDictionary Binders { get { if (this._binders == null) { this._binders = ModelBinders.Binders; } return this._binders; } set { this._binders = value; } }
從代碼1-1中能夠清楚的看到,對於Binders屬性的使用實際是在使用當前系統上下文中的ModelBinders.Binders屬性,這裏先暫停一下,咱們看下ModelBinders.Binders屬性中系統給默認提供的綁定器,代碼1-2。
代碼1-2
private static ModelBinderDictionary CreateDefaultBinderDictionary() { ModelBinderDictionary dictionary2 = new ModelBinderDictionary(); dictionary2.Add(typeof(HttpPostedFileBase), new HttpPostedFileBaseModelBinder()); dictionary2.Add(typeof(byte[]), new ByteArrayModelBinder()); dictionary2.Add(typeof(Binary), new LinqBinaryModelBinder()); return dictionary2; }
這裏沒有其它的意思,就是讓你們看一下系統默認提供的幾種Model綁定器類型,一樣是使用ModelBinderDictionary類型的Add()方法,惟一不一樣的就是這是在系統啓動時就會添加生成好的,而咱們自定義的Model綁定器則是後面手動添加的。
切回主題,從圖2中咱們能夠看到在ModelBinderDictionary類型調用GetBinder()方法的時候實際是調用的ModelBinderProviderCollection類型的GetBinder()方法,其實在ModelBinderDictionary類型的內部有着一個ModelBinderProviderCollection類型的字段,再看圖2,在實際調用ModelBinderProviderCollection類型的GetBinder()方法的時候其實真正調用的是IModelBinderProvider類型中的GetBinder()方法。
然而在反編譯工具中也有反編譯不了的,比如ModelBinderProviderCollection類型,我就沒看到它實例化的細節,不過不要緊在下一篇中會證實出來它的內部細節。
本篇內容就講解到這,後續的篇幅中會講解如何使用這些類型來實現生成Model綁定器而且進行Model綁定。
做者:金源
出處:http://www.cnblogs.com/jin-yuan/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面