<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ASP.NET MVC以ModelValidator為核心的Model驗證體系: ModelValidatorProviders

      前面篇文章我們分別介紹用真正用于實施Model驗證的ModelValidator(《ASP.NET MVC以ModelValidator為核心的Model驗證體系: ModelValidator》),以及用于提供ModelValidator的ModelValidatorProvider(《ASP.NET MVC以ModelValidator為核心的Model驗證體系: ModelValidatorProvider》),那么對于ASP.NET MVC的Model驗證體系來說,最終是通過怎樣的方式對ModelValidatorProvider進行注冊,又是如何利用它們來創建相應的ModelValidator來實施Model驗證的呢?這就是本篇文章論述的重點。[本文已經同步到《How ASP.NET MVC Works?》中]

      目錄
      一、ModelValidatorProviders
      二、ModelValidator、ModelValidatorProvider和ModelValidatorProviders
      三、CompositeModelValidator
      四、實例演示:探測CompositeModelValidator采用的驗證行為

      一、ModelValidatorProviders

      我們通過靜態類型ModelValidatorProviders對ModelValidatorProvider進行注冊。如下面的代碼片斷所示,ModelValidatorProviders具有一個靜態只讀屬性Providers,其類型為ModelValidatorProviderCollection,表示注冊的基于整個Web應用范圍的ModelValidatorProvider列表。

         1: public static class ModelValidatorProviders
         2: {   
         3:     public static ModelValidatorProviderCollection Providers { get; }
         4: }
         5:  
         6: public class ModelValidatorProviderCollection : Collection<ModelValidatorProvider>
         7: {   
         8:     public ModelValidatorProviderCollection();
         9:     public ModelValidatorProviderCollection(IList<ModelValidatorProvider> list);
        10:     public IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context);   
        11: }

      值得一提的是,ModelValidatorProviderCollection定義了一個GetValidators方法用于返回一個通過集合中每個ModelValidatorProvider創建的ModelValidator集合。在這個方法中,指定的Model元數據和Controller上下文會被傳入每個ModelValidatorProvider對象的GetValidators方法,得到的每個ModelValidator對象將會作為最終返回的ModelValidator集合的元素。

      在默認的情況下,通過ModelValidatorProviders的Providers表示注冊的ModelValidatorProvider列表會包含三個對象,對應著我們前面介紹的三種ModelValidatorProvider類型,即DataAnnotationsModelValidatorProviderClientDataTypeModelValidatorProviderDataErrorInfoPropertyModelValidator

      如果我們需要添加一個自定義ModelValidatorProvider,可以直接將相應的對象添加到ModelValidatorProviders的Providers列表中。如果需要采用自定義ModelValidatorProvider來替換掉現有的ModelValidatorProvider,比如我們創建了一個擴展的DataAnnotationsModelValidatorProvider,還需要將現有的ModelValidatorProvider從該列表中移除。

      實現在ModelValidatorProvider中的ModelValidator提供機制是基于Model元數據和Controller上下文的,實際上用于描述Model元數據的ModelMetadata類型同樣定義了一個GetValidators方法用于根據指定的Controller上下文的所有ModelValidator對象。如下面的代碼片斷所示,該方法直接調用了通過ModelValidatorProviders的Providers屬性表述的ModelValidatorProviderCollection對象的同名方法。

         1: public abstract class ModelValidator
         2: {
         3:     //其他成員
         4:     public virtual IEnumerable<ModelValidator> GetValidators(ControllerContext context)
         5:     {
         6:         return ModelValidatorProviders.Providers.GetValidators(this, context);
         7:     }
         8: }

      二、ModelValidator、ModelValidatorProvider和ModelValidatorProviders

      上面我們介紹用于進行Model驗證的ModelValidator,用于提供ModelValidator的ModelValidatorProvider,以及用于注冊ModelValidatorProvider的ModelValidatorProviders,整個ModelValidator的提供機制以此三類組件為核心,下圖所示的UML體現了它們之間的關系。

      image

      三、CompositeModelValidator

      雖然CompositeModelValidator僅僅是定義在程序集System.Web.Mvc.dll中的一個私有類型,但是它在ASP.NET MVC的Model驗證系統中具有重要的地位,可以說真正用于Model驗證的ModelValidator就是這么一個對象。從如下所以的成員定義代碼并不能看出CompositeModelValidator有何特別之處。

         1: private class CompositeModelValidator : ModelValidator
         2: {
         3:     public CompositeModelValidator(ModelMetadata metadata, ControllerContext controllerContext);
         4:     public override IEnumerable<ModelValidationResult> Validate(object container);
         5: }

      從其類型名稱可以看出CompositeModelValidator實際上并不是一個真正對Model對象實施驗證的ModelValidator,它是一系列ModelValidator的組合,它根據基于Model本身類型及其屬性的Model元數據動態地獲取相應的ModelValidator(通過調用ModelMetadata的GetValidators方法)對Model對象實施驗證。

      定義在Validate方法中的驗證邏輯是這樣的:CompositeModelValidator通過在構造函數中初始化的表示驗證對象類型的Model元數據的ModelMetadata對象的Properties屬性得到基于屬性的Model元數據列表。然后遍歷該列表的每個ModelMetadata對象,調用其GetValidators方法得到一組用于驗證屬性值得ModelValidator列表,然后使用該ModelValidator列表依次對相應的屬性值進行驗證,驗證失敗得到的ModelValidationResult對象被添加到最終返回的ModelValidationResult集合中。

      只有在所有屬性值都通過驗證的情況下,CompositeModelValidator采用調用基于被驗證類型Model元數據的ModelMetadata對象的GetValidators方法得到在類型級別ModelValidator列表對指定的數據對象實施驗證,驗證失敗得到的ModelValidationResult對象被添加到最終返回的ModelValidationResult集合中。

      抽象類ModelValidator具有一個靜態的GetModelValidator方法根據指定的Model元數據和Controller上下文得到相應的ModelValidator對象。如下面的代碼片斷所示,該方法返回的正是一個CompositeModelValidator對象。

         1: public abstract class ModelValidator
         2: {
         3:     //其他成員
         4:     public static ModelValidator GetModelValidator(ModelMetadata metadata, ControllerContext context) 
         5:     {
         6:         return new CompositeModelValidator(metadata, context);
         7:     }
         8: }

      四、實例演示:探測CompositeModelValidator采用的驗證行為

      為了使讀者對CompositeModelValidator的驗證邏輯具有一個深刻的理解,我們來演示一個具體的Model驗證的實例。我們創建了如果一個名稱為AlwaysFailsAttribute的驗證特性。如下面的代碼片斷所示,重寫的IsValid方法總是返回False,意味著針對數據的驗證總是會失敗。我們還重寫了只讀屬性TypeId,讓它能夠真正能夠唯一標識一個AlwaysFailsAttribute特性實例,具體原因我們會在本章后續部分講述。

         1: [AttributeUsage( AttributeTargets.Class| AttributeTargets.Property)]
         2:  public class AlwaysFailsAttribute : ValidationAttribute
         3: {
         4:     private object typeId;
         5:     public override bool IsValid(object value)
         6:     {
         7:         return false;
         8:     }
         9:     public override object TypeId
        10:     {
        11:         get { return typeId ?? (typeId = new object()); }
        12:     }
        13: }

      我們將AlwaysFailsAttribute應用到具有如下定義的表示聯系人的Contact類型上。如下面的代碼片斷所示,我們在Contact和Address的類型和屬性都應用了該特性,并且指定了相應的錯誤消息。

         1: [AlwaysFails(ErrorMessage = "Contact")]
         2: public class Contact
         3: {
         4:     [AlwaysFails(ErrorMessage = "Contact.Name")]
         5:     public string Name { get; set; }
         6:  
         7:     [AlwaysFails(ErrorMessage = "Contact.PhoneNo")]
         8:     public string PhoneNo { get; set; }
         9:  
        10:     [AlwaysFails(ErrorMessage = "Contact.EmailAddress")]
        11:     public string EmailAddress { get; set; }
        12:  
        13:     [AlwaysFails(ErrorMessage = "Contact.Address")]
        14:     public Address Address { get; set; }
        15: }
        16:  
        17: [AlwaysFails(ErrorMessage = "Address")]
        18: public class Address
        19: {
        20:     [AlwaysFails(ErrorMessage = "Address.Province")]
        21:     public string Province { get; set; }
        22:  
        23:     [AlwaysFails(ErrorMessage = "Address.City")]
        24:     public string City { get; set; }
        25:  
        26:     [AlwaysFails(ErrorMessage = "Address.District")]
        27:     public string District { get; set; }
        28:  
        29:     [AlwaysFails(ErrorMessage = "Address.Street")]
        30:     public string Street { get; set; }
        31: }

      在一個通過Visual Studio的ASP.NET MVC項目模板創建的空Web應用中,我們創建了具有如下定義的默認HomeController類。在Action方法Index中,我們使用當前的ModelMetadataProvider創建了基于Contact類型的ModelMetadata,然后調用ModelValidator的靜態方法GetValidator方法得到基于該ModelMetadata和ControllerContext的ModelValidator對象(一個CompositeModelValidator對象)。最后我們通過該ModelValidator對象來驗證手工創建的Contact對象,并將得到的ModelValidationResult對象的MemberName和Message屬性呈現出來。

         1: public class HomeController : Controller
         2: {
         3:     public void Index()
         4:     {
         5:         Address address = new Address
         6:         {
         7:             Province = "江蘇",
         8:             City     = "蘇州",
         9:             District = "工業園區",
        10:             Street   = "星湖街328號"
        11:         };
        12:         Contact contact = new Contact
        13:         {
        14:             Name         = "張三",
        15:             PhoneNo      = "123456789",
        16:             EmailAddress = "zhangsan@gmail.com",
        17:             Address      = address
        18:         };
        19:  
        20:         ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => contact, typeof(Contact));
        21:         ModelValidator validator = ModelValidator.GetModelValidator(metadata, ControllerContext);
        22:         foreach (ModelValidationResult result in validator.Validate(contact))
        23:         { 
        24:             Response.Write(string.Format("{0}: {1}<br/>", string.IsNullOrEmpty(result.MemberName)? "N/A": result.MemberName, result.Message));
        25:         }
        26:     }
        27: }

      運行該程序后會在瀏覽器中得到如下所示的輸出結果。這樣的輸出結果至少反映了兩個問題,其一,CompositeModelValidator對數據的驗證并不是遞歸進行的,因為只有應用在Contact屬性上的驗證特性參與了驗證,而應用在Address類型屬性上的驗證特性則沒有被使用;其二,在屬性認證失敗的情況下是不會進行基于類型的驗證的,因為瀏覽器中并不存在應用在Contact類型上的驗證特性對應的輸出。

         1: Name        : Contact.Name
         2: PhoneNo     : Contact.PhoneNo
         3: EmailAddress: Contact.EmailAddress
         4: Address     : Contact.Address
         5: Address     : Address

      上面的輸出結果還反映了另外一個細節,針對某個屬性的ModelValidator列表會同時包含應用在屬性和屬性對應類型的驗證特性生成的ModelValidator。輸出的最后兩個ModelValidationResult都是針對Contact的Address屬性的,分別對應著應用在Contact的Address屬性和Address類型上的兩個AlwaysFailsAttribute特性。現在我們按照如下的方式將應用在Contact的四個屬性以及Address類型上的AlwaysFailsAttribute特性注冊掉,只保留應用在Contact類型的AlwaysFailsAttribute特性。

         1: [AlwaysFails(ErrorMessage = "Contact")]
         2: public class Contact
         3: {
         4:     //[AlwaysFails(ErrorMessage = "Contact.Name")]
         5:     public string Name { get; set; }
         6:  
         7:     //[AlwaysFails(ErrorMessage = "Contact.PhoneNo")]
         8:     public string PhoneNo { get; set; }
         9:  
        10:     //[AlwaysFails(ErrorMessage = "Contact.EmailAddress")]
        11:     public string EmailAddress { get; set; }
        12:  
        13:     //[AlwaysFails(ErrorMessage = "Contact.Address")]
        14:     public Address Address { get; set; }
        15: }
        16:  
        17: //[AlwaysFails(ErrorMessage = "Address")]
        18: public class Address
        19: {
        20:     //省略成員
        21: }

      在此運行我們的程序將會在瀏覽器中得到如下的輸出結果。不難看出輸出的ModelValidationResult對應于著應用在Contact類型上的AlwaysFailsAttribute特性,這充分反映了上面所說的:基于類型的驗證只有在基于屬性的驗證失敗的情況下才會進行

         1: N/A: Contact

       

      ASP.NET MVC以ModelValidator為核心的Model驗證體系: ModelValidator
      ASP.NET MVC以ModelValidator為核心的Model驗證體系: ModelValidatorProvider
      ASP.NET MVC以ModelValidator為核心的Model驗證體系: ModelValidatorProviders

      posted @ 2012-06-03 09:19  Artech  閱讀(6146)  評論(7)    收藏  舉報
      主站蜘蛛池模板: 99人中文字幕亚洲区三| 精品少妇av蜜臀av| 亚洲av激情久久精品人| 婷婷久久综合九色综合88| 免费吃奶摸下激烈视频| 日韩中文字幕高清有码| V一区无码内射国产| 婷婷成人丁香五月综合激情| 最近中文字幕完整版hd| 国产乱码精品一区二区三| 国产成人无码综合亚洲日韩| 久久国产成人高清精品亚洲| 欧美成人精品三级在线观看| 最新国产AV最新国产在钱| 亚洲欧洲日产国码久在线| 日韩亚洲中文图片小说| 69精品丰满人妻无码视频a片| 久久99亚洲网美利坚合众国| 国产一区二区三区的视频| 欧美老熟妇乱子伦牲交视频| 欧美性XXXX极品HD欧美风情| 怀化市| 亚洲精品午夜精品| 正在播放的国产A一片| 新兴县| 免费国产拍久久受拍久久| 欧美综合人人做人人爱| 中文字幕成熟丰满人妻| 久色伊人激情文学你懂的| 少妇熟女久久综合网色欲| 无码人妻熟妇av又粗又大| 亚洲熟女一区二区av| 精品国产欧美一区二区五十路| 九九在线精品国产| 色综合热无码热国产| 乱码中字在线观看一二区| 人妻少妇精品中文字幕| 亚洲国产精品久久久久秋霞| 亚洲精品欧美综合二区| 成全我在线观看免费第二季| 精品人妻少妇嫩草av专区|