ASP.NET MVC Model驗證(二)
前言
上篇內容演示了一個簡單的Model驗證示例,然后在文中提及到Model驗證在MVC框架中默認所處的位置在哪?本篇就是來解決這個問題的,並且會描述一下ModelValidator類型對象相關的類型。
Model驗證
- Model驗證簡單運用示例
- ModelValidator使用生成過程
- 自定義實現DefaultModelBinder進行驗證
- 自定義ModelValidatorProvider 和ModelValidator
- ValidationAttribute特性類使用
- 自定義ValidationAttribute特性類的示例實現
ModelValidator使用生成過程
首先請允許我“盜”一張圖,這個示意圖是在我前面篇幅的ASP.NET MVC Model綁定(二)中的一張圖。
圖1
為什么要“盜”這個圖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類型的示例演示在后續的篇幅中會有講到。
作者:金源
出處:http://www.cnblogs.com/jin-yuan/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面