2010-11-30 3 views
15

Je veux utiliser Validator.TryValidateValue() mais ne comprennent pas la mécanique. Dis, je donne les résultats suivants:ValidationContext Comprendre dans DataAnnotations

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

et la méthode:

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

Mon code de validation est:

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

Il fonctionne bien jusqu'à ce que la valeur de name est null. Je reçois ArgumentNullException lors de l'instanciation ValidationContext et je ne comprends pas pourquoi. TryValidateValue() exige également un contexte non nul. J'ai une valeur et une liste d'attributs à valider. Qu'est-ce que c'est ValidationContext?

+0

Ne pas avoir dupé avec ce avant qu'il me semble que vous devriez passer le type d'objet dans le ValidationContext, pas la propriété ... passant ainsi dans une instance de l'utilisateur qui est non nulle. –

+0

Si vous souhaitez personnaliser l'attribut DataAnnotation, vous pouvez accéder à [mon message] (http://weblogs.asp.net/thangchung/archive/2010/06/25/extending-resource-provider-for-soring- resources-in-the-database.aspx) A côté de cela, vous pouvez également personnaliser le validateur. – thangchung

Répondre

18

La seule chose qui ne va pas dans votre code est l'objet d'instance pour votre contexte de validation. L'instance n'a pas besoin d'être la valeur en cours de validation. Pour Validator.ValidateProperty, oui, il doit être l'objet qui possède la propriété, mais pour Validator.ValidateValue, "this" est suffisant. J'ai écrit une classe d'aide de validation pour faire l'installation; Cela me permet de transmettre des valeurs arbitraires de n'importe où.

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

Si vous validez les propriétés qui ont la validation des attributs sur la propriété, il est beaucoup plus facile:

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

est une « entité » propriété de la classe actuelle qui fait référence à l'objet que je veux valider. Cela me permet de valider les propriétés sur d'autres objets. Si vous êtes déjà dans l'objectif, "ceci" sera à nouveau suffisant.

+1

Merci, mon collègue m'a également suggéré de passer quelque chose de non-nul à ValidationContext et cela a fonctionné. Mais je ne comprends toujours pas pourquoi TryValidateValue() exige ValidationContext. Mauvais design? Seuls les créateurs le savent mais je n'ai pas espéré voir leur réponse ici, donc +50 à vous. – UserControl

+3

Merci! L'instance d'objet a un sens pour la validation des objets et des propriétés, mais beaucoup moins pour la validation des valeurs, et c'est la même classe ValidationContext dans tous les cas. Vous pouvez obtenir un aperçu de l'intention du concepteur en parcourant le code source dans le débogueur Visual Studio. Consultez http://referencesource.microsoft.com/ pour obtenir des instructions sur le téléchargement de la source et la configuration de Visual Studio pour le débogage dans les classes de structure .NET. –

+3

@UserControl Voici un blog expliquant ValidationContext par l'un des créateurs: http://jeffhandley.com/archive/2010/10/25/RiaServicesValidationContext.aspx – Michael