Monday, April 23, 2012

ASP.NET MVC 3 Generating an ActionLink in the controller - Html.ActionLink Equivalent

Generating routing links is extremely easy in MVC 3 using @Html.ActionLink(linkText,action,controller) when you're using Razor views this is great. However sometimes you need to generate the link within the controller - at which point you do not have direct access to the Html helper.

In these instances such as creating links for a wysiwyg editor or adding a link into an email it is preferable to have the system generate it with the appropriate protocol http/https and/or a port number if you're running locally. To this end I did some digging and put together the following little code snippet which does eactly that!

I thought I'd share it here to save me having to look it up again in the future!


            string absoluteAction = string.Format("{0}://{1}{2}",
                                                  Url.RequestContext.HttpContext.Request.Url.Scheme,
                                                  Url.RequestContext.HttpContext.Request.Url.Authority,
                                                  Url.Action("ActionName", "ControllerName", new {Id = "Data"}));
Read More

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);


Read More