Wednesday, April 18, 2012

MVC 3 ModelState Validation after Postback - Page.Validate() equivalent

I've been tinkering with MVC 3 for a while now and I have to say I'm extremely impressed - it is a joy to work with as are its supporting technologies Entity Framework, ASP.NET Routing and Razor view engines to name a few.

However I've been working on WebForms for so long that I'm finding more than a few stumbling blocks as I grapple my way up the learning curve. One such hurdle was "How do I re-validate a model after its been posted back to the server". The scenario being I want a user to type a plain text password into a form which is required but not persisted - I used [NotMapped] DataAnnotation attribute in the model definition to get this bit done.

Following that on postback I need to create a Salt (required and persisted) and a PasswordHash (required and persisted). Trouble was, I originally had the Salt and Hash properties within my if (ModelState.IsValid) statement.

The Model was at this point invalid because no password hash or salt had been created yet. "Easy" I thought simply elevate the property assignments above the if condition. No luck (but along the right lines) as the properties were now filled but I needed to Re-Validate the model, no Page.Validate() to rely upon at this point so I did some digging. As it turns out you simply need to call two methods (below) and they are roughly equivalent to what a WebForms guy would consider to be Page.Validate().


p.Salt = CreateSalt(36);
p.PasswordHash = GenerateSaltedHash(UTF8.GetBytes(p.Password), p.Salt);
ModelState.Clear();
TryValidateModel(model);
if (ModelState.IsValid)
{
p.Id = Guid.NewGuid();
db.People.Add(p);
db.SaveChanges();
return RedirectToAction("Index");  
}
return View(person);



No comments: