lo que de acuerdo a GuIValidatableObject.Validate()
debería ser llamado cuando un controlador valida su modelo (es decir, antes ModelState.IsValid
) sin embargo, simplemente haciendo que el modelo de implementar IValidatableObject
no parece funcionar, porque Validate(..)
no recibe llamados .ModelState.IsValid vs IValidateableObject en MVC3
¿Alguien sabe si hay algo más que deba cablear para que funcione?
EDIT:
Aquí está el código conforme a lo solicitado.
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 };
}
}
La acción. (No hago nada especial en el controlador ...)
[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);
}
puse un punto de quiebre en la primera línea de LoginModel.Validate()
y no parece que le peguen.
Tu código se ve bien. Exactamente como debería. Solo un punto de interés, pero ¿tienes un modelo duplicado? Sé que tengo un modelo de vista y un modelo de base de datos para cada objeto. ¿Podría su controlador hacer referencia al modelo incorrecto? – Buildstarted
Además, como nota al margen: definitivamente debe devolver solo un error si el nombre de usuario o la contraseña no son válidos y no son distintos. Esto es simplemente por seguridad, ya que puedo probar cada campo individualmente para encontrar un nombre de usuario y luego trabajar en la contraseña para ese usuario. No es obligatorio, pero es una buena idea :) – Buildstarted
Puede usar 'yield return DataContext ...' en lugar de devolver una nueva lista. Sería más bonito y más rápido. – pipedreambomb