上篇內容演示了一個簡單的Model驗證示例,而後在文中說起到Model驗證在MVC框架中默認所處的位置在哪?本篇就是來解決 這個問題的,而且會描述一下ModelValidator類型對象相關的類型。框架
Model驗證簡單運用示例ide
ModelValidator使用生成過程函數
自定義實現DefaultModelBinder進行驗證spa
自定義ModelValidatorProvider 和ModelValidator 對象
ValidationAttribute特性類使用繼承
自定義ValidationAttribute特性類的示例實現ip
ModelValidator使用生成過程源碼
首先請容許我“盜”一張圖,這個示意圖是在我前面篇幅的ASP.NET MVC Model綁定(二)中的一張圖。it
圖1io
爲何要“盜”這個圖1,由於Model驗證的過程將是在這個圖中的某個位置,對於這個示意圖的意思我就不詳細 說明了,只說明一下藍色線條部分,那是Model綁定器生成部分,咱們須要的也是這個部分。看下圖2
圖2
圖2的部分也是圖1中的,這樣一步步的分解下來,讓你們有個由大到小的由遠到近的層次感,便於記憶和留下印象。這裏有 的朋友會說了這是Model綁定部分拉過來有什麼用?這個是有用的,看一下【IModelBinder.BindModel()】這個部分到【獲取控 制器方法參數值】部分,也就是整個Model綁定的過程了,主題是Model驗證又扯綁定了,沒辦法阿,由於在Model綁定以前會進 行Model驗證。
在咱們沒有自定義Model綁定器的時候,系統默認實現的都是DefaultModelBinder類型,那麼我就來看一 下DefaultModelBinder類型的內部的具體實現吧。。。
開個玩笑,是看一下內部實現不過不是源碼而是示意圖(圖3),這樣給你們留個印象,感興趣的本身去扒源碼看吧。
圖3
感受是否是有點坑,別急你們,坑誰不敢坑大家,實際上還有一條流程這裏沒有顯示,這裏顯示就是綁定複雜類型的Model所 要執行的內部方法。而在BindComplexModel)(方法內部的實現裏纔會進行Model驗證,咱們看一下方法的內部執行示意圖(圖4) 。
圖4
長話短說,執行Model驗證的過程是先執行Model中的屬性級驗證,而後執行Model級驗證。
在BindComplexElementalModel()方法中,首先會執行BindProperties()方法,在此方法內部會遍歷PropertyDescriptor集合 類型(圖4中顯示PropertyDescriptorCollection是不足的地方),正如你們所看到的同樣,SetProperty()方法纔是最後真正對 Model屬性進行驗證的函數(下個篇幅會有講解實現自定義的Model綁定器執行Model驗證會講到這個方法)。
而在SetProperty()方法中真正執行驗證的,能夠是自定義的,固然了系統默認的就是從 ModelValidatorProviders.Providers中獲取的了,全部驗證的後的錯誤信息(假使有)都存在了ModelBindingContext類型的參數中了,以此向下傳遞。
驗證完Model屬性後則會驗證Model自己,就會調用OnModelUpdated()方法,這個方法有個毛病,就是本身不幹 活,在它內部使用CompositeModelValidator類型的實例來進行驗證,不過驗證最後使用的仍是 ModelValidatorProviders.Providers中咱們自定義的ModelValidator類型或者是默認的(這裏具體的細節本人也沒有去細看, 大概的流程是這樣若是有偏差請指正,感激涕零)。
最後咱們說一下ModelValidator類型的註冊,首先系統是不認它的,它可能不是“親 生”的。系統的ModelValidatorProviders類型中的Providers屬性是ModelValidatorProviderCollection類型的,這下大 家應該看到系統認誰了吧,就是認識ModelValidator類型的“爹”ModelValidatorProvider類型 (畢竟不是繼承關係),這裏就很少說相關的模型了,跟前面好多的模型都相像。
對於自定義實現ModelValidator類型的示例演示在後續的篇幅中會有講到。