Accueil

Les ValidationAttribute du framework v4.5

by Jean-Camille Mercier 28. avril 2013 11:24

Voici un diagrame de classe récapitulatif des attributs de validation pour les données (Data Annotation) disponible dans le framework dotNet 4.5. Ces attributs sont disponibles dans l'assembly :

System.ComponentModel.DataAnnotations.dll (MSDN).

Elles dérivent toutes de ValidationAttribute : MaxLenghtAttribute, MinLenghtAttribute, StringLenghtAttribute, RequiredAttribute, CompareAttribute, RegularExpressionAttribute, RangeAttribute et CustomAttribute. Les 4 dernières : EmailAttribute, PhoneAttribute, CreditCardAttribute et FileExtensionsAttribute sont elles sur DataTypeAttribute

 

 Un exemple d'utilisation de chacun d'eux : 

[DataItemValidation]
public class DataItem
{
  [MaxLength(12, ErrorMessage = "Chaine1 ne doit pas faire plus de 12 caractères")]
  public string Chaine1 { get; set; }

  [MinLength(3, ErrorMessage = "Chaine2 doit avoir au moins 3 caractères")]
  public string Chaine2 { get; set; }

  [StringLength(12, MinimumLength = 3, 
              ErrorMessage = "Chaine3 doit faire entre 3 et 12 caractères")]
  public string Chaine3 { get; set; }

  [RegularExpression(@"/^[a-zA-Z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$/", 
                     ErrorMessage = "Format d'e-mail incorrect")]
  public string Email { get; set; }

  [EmailAddress(ErrorMessage = "Format d'e-mail incorrect")]
  public string Email2 { get; set; }

  [Required(AllowEmptyStrings = false, ErrorMessage = "Chaine4 ne doit pas être vide")]
  public string Chaine4 { get; set; }

  [Range(5, 99, ErrorMessage = "L'age doit être compris entre 5 et 99 ans")]
  public int Age { get; set; }

  [Chaine5Custom]
  public string Chaine5 { get; set; }

  [Required, Compare("Chaine5", ErrorMessage = "Les mots de passes doivent être identiques")]
  public string MotDePasse { get; set; }

  [CreditCard(ErrorMessage = "Numéro de carte de crédit incorrect")]
  public string NumeroCarte { get; set; }

  [FileExtensions(Extensions = "jpg,jpeg", ErrorMessage="Ce doit être un jpeg")]
  public string Ext { get; set; }

  [Phone(ErrorMessage="Numéro de téléphone incorrect")]
  public string Telephone { get; set; }
}

// Validation Custom d'une propriété
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class Chaine5CustomAttribute : ValidationAttribute
{
  override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    if ( ... )
      return new ValidationResult("Chaine5 non valide");
    else
      return ValidationResult.Success;
  }
}

// Validation Custom d'une classe (2 propriétés entre elles)
[AttributeUsage(AttributeTargets.Class)]
public class DataItemValidationAttribute : ValidationAttribute
{
  override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    var toValid = value as DataItem;
    if (string.IsNullOrEmpty(toValid.Chaine1) && string.IsNullOrEmpty(toValid.Chaine2))
      // Attention a bien préciser les noms de propriétés affectées, ici Chaine1 et Chaine2
      return new ValidationResult("Vous devez renseigner soit Chaine1, soit Chaine2",
                                   new List<string>() { "Chaine1", "Chaine2" });
    else
      return ValidationResult.Success;
  }
}

Et pour finir, voici comment valider votre objet entièrement :

var erreurs = new List<ValidationResult>();
var context = new ValidationContext(toValide);
bool validateAllProperties = true;
Validator.TryValidateObject(toValide, context, erreurs, validateAllProperties);

Personnellement j'aime beaucoup cette manière de valider les objets car on distingue facilement le code métier de validation du code d'exécution "normal" de l'objet.