2010-11-30 11 views
15

Validator.TryValidateValue() kullanmak istiyorum ancak mekaniği anlamıyorum. De ki, ben şu var:Veri'de DoğrulamaKontext'i AnlamaAnlatılar

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

ve yöntemi:

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

Benim doğrulama kodudur:

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 değeri null kadar iyi çalışır. ValidationContext'u başlatırken ArgumentNullException alıyorum ve nedenini anlamıyorum. TryValidateValue() ayrıca null olmayan bir içerik ister. Doğrulamak için bir değer ve bir nitelikler listesi var. Bu ValidationContext nedir?

+0

Önceden bununla aldatılmamış olmanız, nesne türünü ValidationContext'e iletmeniz gerektiğini görmüyor, bu nedenle null olmayan bir Kullanıcı örneğinden geçiriliyorsunuz. –

+0

DataAnnotation özniteliğini özelleştirmek isterseniz, [gönderim] 'e (http://weblogs.asp.net/thangchung/archive/2010/06/25/extending-resource-provider-for-soring- resources-in-the-database.aspx) Ayrıca, doğrulayıcıyı da özelleştirirsiniz. – thangchung

cevap

18

Kodunuzda yanlış olan tek şey doğrulama içeriğinizin örnek nesnesidir. Örneğin doğrulanması gereken değer olması gerekmez. Validator.ValidateProperty için, evet, bu özellik sahibi olan nesne olması gerekir, ancak Validator.ValidateValue için, "bu" yeterlidir.

Kurulumu yapmak için bir doğrulama yardımcı sınıfı yazdım; Bu, herhangi bir yerden rastgele değerler aktarmamı sağlar.

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); 
    } 
} 

doğrulama mülkiyet nitelikleri olan özelliklere doğrulayarak ise, bu çok kolay:

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

"Varlık" Ben istediğiniz nesneyi başvuran akım sınıfının bir özelliktir Doğrulamak. Bu, diğer nesnelerdeki özellikleri doğrulamamı sağlar. Eğer zaten objektifin içinde iseniz, "bu" yine yeterli olacaktır.

+1

Teşekkürler, iş arkadaşım da null olmayan bir şeyi ValidationContext'e aktarmamı önerdi ve işe yaradı. Ama hala TryValidateValue() neden ValidationContext talep ettiğini anlamıyorum. Kötü tasarım mı? Sadece içerik oluşturucular biliyor, ancak cevabını burada görmeyi umuyordum. – UserControl

+3

Teşekkürler! Nesne örneği, nesneleri ve özellikleri doğrulamak için anlamlıdır, ancak değerleri doğrulamak için çok daha azdır ve tüm durumlarda aynı ValidationContext sınıfıdır. Visual Studio hata ayıklayıcıdaki kaynak koduna bakarak tasarım amacına bir bakış sağlayabilirsiniz. Kaynak indirme ve .NET Framework sınıflarına hata ayıklamak için Visual Studio'yu ayarlama hakkında talimatlar için http://referencesource.microsoft.com/ adresine bakın. –

+3

@UserControl İşte, ValidationContext'i içerik oluşturuculardan biri tarafından açıklayan bir blog gönderisi: http://jeffhandley.com/archive/2010/10/25/RiaServicesValidationContext.aspx – Michael