a tal fine i GuIValidatableObject.Validate()
dovrebbe ottenere chiamato quando un controller di convalida è il modello (cioè prima ModelState.IsValid
) tuttavia semplicemente facendo il modello implementare IValidatableObject
non sembra funzionare, perché Validate(..)
non ottiene chiamato .ModelState.IsValid vs IValidateableObject in MVC3
Qualcuno sa se c'è qualcos'altro che devo cablare per farlo funzionare?
EDIT:
Ecco il codice come richiesto.
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'azione. (Non faccio nulla di speciale nel Controller ...)
[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);
}
Ho impostato un punto di interruzione sulla prima riga del LoginModel.Validate()
e non sembra essere colpito.
Il codice sembra perfetto. Esattamente come dovrebbe Solo un punto di interesse, ma hai un modello duplicato? So di avere un modello di vista e un modello db per ogni oggetto. Il tuo controller potrebbe fare riferimento al modello sbagliato? – Buildstarted
Inoltre, come nota a margine: è necessario restituire un solo errore se il nome utente o la password non sono validi e non sono errori distinti. Questo è semplicemente per sicurezza, poiché posso testare ogni campo individualmente per trovare un nome utente e poi lavorare sulla password per quell'utente. Non è obbligatorio ma è una buona idea :) – Buildstarted
Si potrebbe usare 'yield return DataContext ...' piuttosto che restituire una nuova lista. Sarebbe più carino e più veloce. – pipedreambomb