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.