donc selon GuIValidatableObject.Validate()
devrait obtenir appelé lorsqu'un contrôleur valide son modèle (avant ModelState.IsValid
) mais tout simplement faire le modèle en œuvre IValidatableObject
ne semble pas fonctionner, parce que Validate(..)
ne soit pas appelé . Est-ce que quelqu'un sait s'il y a quelque chose d'autre que je dois câbler pour que cela fonctionne?ModelState.IsValid vs IValidateableObject dans MVC3
EDIT:
Voici le code tel que demandé.
public class LoginModel : IValidatableObject
{
[Required]
[Description("Email Address")]
public string Email { get; set; }
[Required]
[Description("Password")]
[DataType(DataType.Password)]
public string Password { get; set; }
[DisplayName("Remember Me")]
public bool RememberMe { get; set; }
public int UserPk { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var result = DataContext.Fetch(db => {
var user = db.Users.FirstOrDefault(u => u.Email == Email);
if (user == null) return new ValidationResult("That email address doesn't exist.");
if (user.Password != User.CreateHash(Password, user.Salt)) return new ValidationResult("The password supplied is incorrect.");
UserPk = user.UserPk;
return null;
});
return new List<ValidationResult>(){ result };
}
}
L'action. (Je ne fais rien de spécial dans le contrôleur ...)
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
return Redirect(Request.UrlReferrer.AbsolutePath);
}
if (ControllerContext.IsChildAction || Request.IsAjaxRequest())
return View("LoginForm", model);
return View(model);
}
Je mets un point d'arrêt sur la première ligne de LoginModel.Validate()
et il ne semble pas être touché.
Vous êtes le code semble très bien. Exactement comme il se doit. Juste un point d'intérêt, mais avez-vous un modèle en double? Je sais que j'ai un modèle de vue et un modèle db pour chaque objet. Votre contrôleur pourrait-il référencer le mauvais modèle? – Buildstarted
Aussi, en note: vous ne devriez certainement retourner qu'une seule erreur si le nom d'utilisateur ou mot de passe est invalide et pas des erreurs distinctes. C'est simplement pour la sécurité que je peux tester chaque champ individuellement pour trouver un nom d'utilisateur et ensuite travailler sur le mot de passe pour cet utilisateur. Ce n'est pas obligatoire mais c'est une bonne idée :) – Buildstarted
Vous pouvez utiliser 'return return DataContext ...' plutôt que de retourner une nouvelle liste. Ce serait plus joli et plus rapide. – pipedreambomb