ASP.NET MVCマークアップ特性に基づくModel検証:DataAnnotationsModelValidatorProvider

13844 ワード

DataAnnotationsModelValidatorは、最終的には、対応するModelValidatorProvider、すなわちDataAnnotationsModelValidatorProviderによって作成されます.前述の説明では、AssociatedValidatorProviderのサブクラスであることがわかります.後者は、ModelValidatorを取得するGetValidatorsメソッドで指定したModelメタデータのすべてのプロパティに基づいて作成されています.DataAnnotationsModelValidatorは、ValiationAttributeから継承された検証プロパティをフィルタリングし、オブジェクトを作成するDataAnnotationsModelValidatorだけでよいのです.[本文は『How ASP.NET MVC Works?』に同期しました.]
ディレクトリDataAnnotationsModelValidator Validator ValidationAttributeに基づくModelValidatorの作成IValidatableObjectに基づくModelValidatorの作成デフォルトのModelValidator作成メカニズムModelValidatorの作成方法のカスタマイズ

DataAnnotationsModelValidator


DataAnnotationsModelValidatorの定義と結びつけて、具体的なModelValidator提供メカニズムについて議論します.次のコード・セグメントに示すように、DataAnnotationsModelValidatorProviderには、2つの静的フィールドAttributeFactoriesとDefaultAttributeFactoryがあり、後者はDataAnnotationsModelValidationFactoryの依頼であり、前者はValueがTypeオブジェクトをKeyとする辞書である.
   1: public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
   2: {
   3:     //    
   4:     internal static readonly Dictionary AttributeFactories;
   5:     internal static DataAnnotationsModelValidationFactory DefaultAttributeFactory;
   6:  
   7:     internal static DataAnnotationsValidatableObjectAdapterFactory DefaultValidatableFactory;
   8:     internal static readonly Dictionary ValidatableFactories;
   9:     
  10:     protected override IEnumerable GetValidators(ModelMetadata metadata, HttpActionContext actionContext, IEnumerable attributes);
  11: }
  12:  
  13: public delegate ModelValidator DataAnnotationsModelValidationFactory(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute);
  14:  
  15: public delegate ModelValidator DataAnnotationsValidatableObjectAdapterFactory(ModelMetadata metadata, ControllerContext context);

ValidationAttributeベースのModelValidatorの作成


依頼DataAnnotationsModelValidationFactoryは、ModelMetadata、ControllerContext、ValidationAttributeに従ってModelValidatorオブジェクトを返します.フィールドAttributeFactoriesが示す辞書オブジェクトのKeyは、特定の検証プロパティのタイプです.つまり、ValidationAttributeプロパティのタイプと対応するModelValidatorファクトリのマッチング関係を維持します.書き換えられたGetValidatorsメソッドでは、指定された各ValidationAttributeについて、そのタイプに応じてAttributeFactoriesから対応するDataAnnotationsModelValidationFactory依頼を取得し、その依頼が存在する場合は対応するModelValidatorオブジェクトを作成します.そうでなければ、ModelValidatorの作成は、フィールドD e f a u ltAttributeFactoryで表されるDataAnnotationsModelValidationFactoryから依頼されます.

IValidatableObjectに基づくModelValidatorの作成


AttributeFactoriesとDefaultAttributeFactoryに加えて、DataAnnotationsModelValidatorProviderには、検証可能なオブジェクト(IValidatableObjectインタフェースが実装されている)に対するModelValidatorの作成に使用されるDefaultValidatableFactoryとValidatableFactoriesの2つの静的プロパティがあります.DataAnnotationsModelValidatorのタイプは、ModelMetadataおよびControllerContextに基づいて対応するModelValidatorを作成するDataAnnotationsValidatorの別のタイプです.ValidatableFactoriesは、この依頼をValueとし、TypeオブジェクトをKeyとする辞書です.
DataAnnotationsModelValidatorProviderが検証特性に基づくModelValidatorの作成を完了した後、Modelメタデータに基づいて解析されたModelタイプに基づいてIValidatableObjectインタフェースが実装された場合、まず辞書ValidatableFactoriesからこのタイプに基づいて対応するDataAnnotationsValidatableObjectAdapterFactory依頼を取得し、一致する依頼オブジェクトが存在する場合、ModelValidatorの作成に使用します.それ以外の場合は、フィールドD e f a ultValidatableFactoryで表されるデフォルトのファクトリを使用して、対応するModelValidatorオブジェクトを作成します.

デフォルトのModelValidator作成メカニズム


DataAnnotationsModelValidatorProviderタイプがロードされると、上記の4つのフィールドがスタティックコンストラクタ呼び出し時に初期化されます.次のコード・セグメントから分かるように、一般的なValidationAttributeでは、対応するModelValidatorはDataAnnotationsModelValidatorオブジェクト(DefaultAttributeFactoryフィールド)である.RangeAttribute、RegularExpressionAttribute、RequiredAttribute、StringLengthAttributeの4つの検証プロパティに対して、対応する適切なModelValidatorが作成されます.検証可能なオブジェクトの場合、デフォルトで提供されるModelValidatorリストにはValidatableObjectAdapterオブジェクトも含まれています.
   1: public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
   2: {
   3:     //    
   4:     static DataAnnotationsModelValidatorProvider()
   5:     {
   6:         //1、DefaultAttributeFactory
   7:         DefaultAttributeFactory = (metadata, context, attribute) => new DataAnnotationsModelValidator(metadata, context, attribute);
   8:  
   9:         //2、AttributeFactories
  10:         Dictionary dictionary = new Dictionary();
  11:         dictionary.Add(typeof(RangeAttribute), (metadata, context, attribute) => new RangeAttributeAdapter(metadata, context, (RangeAttribute)attribute));
  12:         dictionary.Add(typeof(RegularExpressionAttribute), (metadata, context, attribute) => new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute));
  13:         dictionary.Add(typeof(RequiredAttribute), (metadata, context, attribute) => new RequiredAttributeAdapter(metadata, context, (RequiredAttribute)attribute));
  14:         dictionary.Add(typeof(StringLengthAttribute), (metadata, context, attribute) => new StringLengthAttributeAdapter(metadata, context,(StringLengthAttribute)attribute));
  15:         AttributeFactories = dictionary;
  16:  
  17:         //3、DefaultValidatableFactory
  18:         DefaultValidatableFactory = (metadata, context) => new ValidatableObjectAdapter(metadata, context);
  19:  
  20:         //4、ValidatableFactories
  21:         ValidatableFactories = new Dictionary();
  22:     }
  23: }

ModelValidatorの作成方法のカスタマイズ


DataAnnotationsModelValidatorProviderの4つの委任ベースの静的フィールドは、ModelValidatorの提供メカニズムを体現しています.これらはすべて内部フィールドであるため、直接操作することはできませんが、次のように一連の静的メソッドがD a t a n o t i o n s ModelValidatorProviderで定義され、特定の必要に応じてデフォルトのModelValidatorを定義できます.
   1: public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
   2: {
   3:     //      
   4:    public static void RegisterAdapter(Type attributeType, Type adapterType);
   5:    public static void RegisterAdapterFactory(Type attributeType, DataAnnotationsModelValidationFactory factory);
   6:    public static void RegisterDefaultAdapter(Type adapterType);
   7:    public static void RegisterDefaultAdapterFactory(DataAnnotationsModelValidationFactory factory);
   8:  
   9:    public static void RegisterDefaultValidatableObjectAdapter(Type adapterType);
  10:    public static void RegisterDefaultValidatableObjectAdapterFactory(DataAnnotationsValidatableObjectAdapterFactory factory);
  11:    public static void RegisterValidatableObjectAdapter(Type modelType, Type adapterType);
  12:    public static void RegisterValidatableObjectAdapterFactory(Type modelType, DataAnnotationsValidatableObjectAdapterFactory factory);
  13: }

上記の8つの静的方法については,RegisterDefaultAdapterとRegisterValidatableObjectAdapterを除いてよく理解されている.RegisterDefaultAdapterは、ModelMetadata、ControllerContext、およびAttributeのパラメータタイプリストを持つデフォルトのModelValidatorタイプを登録します.検証プロパティのタイプに基づいて一致するDataAnnotationsModelValidationFactory委任オブジェクトが見つかった場合、対応するパラメータがコンストラクション関数に入力され、最終的に登録したModelValidatorオブジェクトが作成されます.
RegisterValidatableObjectAdapterとRegisterDefaultAdapterは比較的類似しており、ModelMetadataとControllerContexというパラメータタイプの構造関数を持つデフォルトのModelValidatorを登録するために使用されます.検証プロパティのタイプによって一致するDataAnnotationsValidatableObjectAdapterFactory委任オブジェクトが見つかった場合、対応するパラメータが構造関数に入力され、最終的に登録したModelValidatorオブジェクトが作成されます.
ASP.NET MVCマークアップ特性に基づくModel検証:ValidationAttribute ASP.NET MVCマークアップ特性に基づくModel検証:DataAnnotationsModelValidator ASP.NET MVCマークアップ特性に基づくModel検証:DataAnnotationsModelValidatorProvider ASP.NET MVCマークアップ特性に基づくModel検証:パラメータにValidationAttributeを適用するASP.NET MVCマークアップ特性に基づくModel検証:1つのModel、複数の検証ルール