ASP.NET MVC 2 est arrivé avec une nouveauté très pratique : la validation de données par DataAnnotation. Le principe : on définit sur notre modèle les contraintes à vérifier, et MVC se charge de faire les vérifications (côté serveur uniquement dans la première preview, et normalement une vérification client devrait être générée à l’aide de jQuery dans les prochaines versions).

Par exemple, j’ai la classe suivante :

public class Contact 
{ 
    public String Login { get; set; } 
    public String Email { get; set; } 
    public Int16 Age { get; set; } 
}

Je vais pouvoir lui ajouter les règles de validation de cette manière (sans oublier de référencer System.ComponentModel.DataAnnotations) :

public class Contact 
{ 
    [Required(ErrorMessage="The login is required")] 
    [StringLength(20, ErrorMessage="Must be less than 20 characters")] 
    public String Login { get; set; } 

    [Required(ErrorMessage="The e-mail is required")] 
    [RegularExpression(@"([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})",ErrorMessage="Incorrect e-mail address")]
    public String Email { get; set; } 

    [Range(0,120)] 
    public Int16 Age { get; set; } 
}

Par contre, un problème se pose lorsque notre modèle provient de code généré. Si on veut annoter nos classes, toutes nos règles de validations disparaitront si on regénère le code.

Heureusement, les p’tits gars de chez Microsoft ont pensé à tout, et nous ont fourni un système pour mettre nos annotations dans une classe partielle :

[MetadataType(typeof(ContactMD))] 
public partial class Contact 
{ 

    private class ContactMD 
    { 
        [Required(ErrorMessage = "The login is required")] 
        [StringLength(20, ErrorMessage = "Must be less than 20 characters")] 
        public String Login { get; set; } 

        [Required(ErrorMessage = "The e-mail is required")] 
        [RegularExpression(@"([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})", ErrorMessage = "Incorrect e-mail address")]
        public String Email { get; set; } 

        [Range(0, 120)] 
        public Int16 Age { get; set; } 
    } 
}

Ici, la classe Contact a été générée par LinqToSql, et contient les propriétés Login, Email et Age. Je ne peux donc pas les remettre dans la classe partielle. Il faut dans ce cas créer une autre classe, ContactMD, qui contient les mêmes propriétés que Contact, et sur laquelle on mets nos annotations. Et on ajoute une annotation MetadataType sur notre classe Contact pour définir dans quelle classe se trouvent les annotations.