J'utilise ASP.NET MVC 3 et Entity Framework 4.1 Code First.
Disons que j'ai un User
entité :
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
En l'éditant dans mon UserController
Je veux ajouter un PasswordConfirmation
et vérifiez que PasswordConfirmation == Password
1. Par composition
Mon premier essai était :
public class EditUserModel
{
[Required]
public User User { get; set; }
[Compare("User.Password", ErrorMessage = "Passwords don't match.")]
public string PasswordConfirmation { get; set; }
}
Dans ce cas, la validation côté client fonctionne mais ( Editar: la validation côté client fonctionnant était une coïncidence). ne fonctionne pas y el la validation côté serveur échoue avec le message suivant : Impossible de trouver une propriété nommée User.Password
Editar: Je pense que la meilleure solution, dans ce cas, serait de créer un fichier personnalisé CompareAttribute
Mise en œuvre de IValidatableObject
public class EditUserModel : IValidatableObject
{
[Required]
public User User { get; set; }
public string PasswordConfirmation { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(this.PasswordConfirmation != this.User.Password)
return new[] { new ValidationResult("Passwords don't match", new[] { "PasswordConfirmation " }) };
return new ValidationResult[0];
}
}
Dans ce cas, le la validation côté serveur fonctionne mais le la validation côté client ne fonctionne pas plus. Mise en œuvre de IClientValidatable
semble un peu trop compliqué et je préfère ne pas avoir de validation côté client dans ce cas.
2. Par héritage
public class EditUserModel : User
{
[Compare("Password", ErrorMessage = "Passwords don't match.")]
public string PasswordConfirmation { get; set; }
}
En essayant d'enregistrer directement EditUserModel
en utilisant EF, cela ne fonctionne pas, j'obtiens un message d'erreur à propos de l'utilisation de l'EF. EditUserModel
donc j'utilise AutoMapper pour passer de User
a EditUserModel
et en arrière. Cette solution travaux mais c'est plus complexe car je dois convertir le modèle en modèle de vue et inversement.
3. Par duplication
(Proposé par Malte Clasen)
Le modèle de vue aurait toutes les propriétés du modèle, plus des propriétés supplémentaires. AutoMapper peut être utilisé pour convertir l'un en l'autre.
public class EditUserModel {
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
[Compare("Password", ErrorMessage = "Passwords don't match.")]
public string ConfirmPassword { get; set; }
}
C'est la solution que je préfère le moins à cause de la duplication du code (DRY).
Questions
Quels sont les avantages et les inconvénients de l'héritage, de la composition et de la duplication dans ce cas ?
Existe-t-il un moyen simple d'avoir une validation côté client et côté serveur sans devoir convertir le modèle en modèle de vue et inversement ?