2010-11-30 98 views
15

Validator.TryValidateValue()を利用したいが、メカニックを理解していない。DataAnnotationsのValidationContextを理解する

public class User { 
    [Required(AllowEmptyStrings = false)] 
    [StringLength(6)] 
    public string Name { get; set; } 
} 

と方法:

public void CreateUser(string name) {...} 

私の検証コードは次のとおりです。

ValidationAttribute[] attrs = bit of reflection here to populate from User class 
var ctx = new ValidationContext(name, null, null); 
var errors = new List<ValidationResult>(); 
bool valid = Validator.TryValidateValue(name, ctx, errors, attrs); 

nameの値がnullになるまでそれが正常に動作しますが、私は、次のしている、と言います。私はをインスタンス化するときにValidationContextを理解していません。また、TryValidateValue()は、null以外のコンテキストも要求します。私は、検証する属性と値のリストを持っています。 ValidationContextとは何ですか?

+0

オブジェクト型をValidationContextに渡す必要があります。プロパティではなく、nullでないUserのインスタンスを渡す必要があります。 –

+0

DataAnnotationの属性をカスタマイズする場合は、[my post](http://weblogs.asp.net/thangchung/archive/2010/06/25/extending-resource-provider-for-soring- resources-in-the-database.aspx)さらに、バリデータをカスタマイズすることもできます。 – thangchung

答えて

18

あなたのコードについて間違っているのは、検証コンテキストのインスタンスオブジェクトだけです。インスタンスは、検証される値である必要はありません。 Validator.ValidatePropertyでは、プロパティを所有するオブジェクトである必要がありますが、Validator.ValidateValueでは "this"で十分です。

セットアップを行うための検証ヘルパークラスを作成しました。これによりどこからでも任意の値を渡すことができます。

public class ValidationHelper 
{ 
    private List<ValidationResult> m_validationResults = new List<ValidationResult>(); 
    private List<ValidationAttribute> m_validationAttributes = new List<ValidationAttribute>(); 

    public Tuple<bool, List<string>> ValidateDOB(DateTime? dob) 
    { 
     m_validationAttributes.Add(new CustomValidationAttribute(typeof(DateOfBirthValidator), "ValidateDateOfBirth")); 
     bool result = Validator.TryValidateValue(dob, 
          new ValidationContext(this, null, null), 
          m_validationResults, 
          m_validationAttributes); 
     if (result) 
     { 
      return Tuple.Create(true, new List<string>()); 
     } 
     List<string> errors = m_validationResults.Select(vr => vr.ErrorMessage).ToList(); 
     return Tuple.Create(false, errors); 
    } 
} 

あなたは検証が財産上の属性を持つプロパティを検証している場合、それは非常に簡単です:

internal void Validate(T value) 
{ 
    if (!m_Initializing && TrackChanges && !Entity.IsImmutable) 
    { 
     Validator.ValidateProperty(value, new ValidationContext(Entity, null, null) { MemberName = PropertyName ?? ModelName }); 
    } 
} 

「エンティティ」は、私がしたいオブジェクトを参照現在のクラスのプロパティです検証します。これにより、他のオブジェクトのプロパティを検証できます。あなたがすでにオブジェクトの中にいるならば、 "これ"はもう十分です。

+1

私の同僚は、ValidationContextにnull以外のものを渡すように提案してくれました。しかし、なぜTryValidateValue()がValidationContextを要求するのかまだ分かりません。デザインが悪いですか?クリエイターだけが知っていますが、私はあなたの答えをここで+50に見たいとは思わなかった。 – UserControl

+3

ありがとう!オブジェクトインスタンスはオブジェクトとプロパティの検証には意味がありますが、値の検証にはそれほど効果的ではなく、すべてのケースで同じValidationContextクラスです。 Visual Studioデバッガでソースコードを実行することで、デザイナの意図を把握できます。ソースのダウンロードと.NET FrameworkクラスへのデバッグのためのVisual Studioの設定については、http://referencesource.microsoft.com/を参照してください。 –

+3

@UserControlここでは、作成者の1人によるValidationContextについて説明しているブログ記事です:http://jeffhandley.com/archive/2010/10/25/RiaServicesValidationContext.aspx – Michael