April 24 2012

MVC3 Partial View Validation

I came across a problem recently with server side validation of partial views in MVC3.

I have a partial view containing a login form located in a layout page, it posts to  the Login action of the AccountController and is redirected back to the page that it was submitted from.

For successful logins this works fine, but if a login is unsuccessful the view model and modelstate errors are lost in the redirect.

I initially thought there'd be an elegant solution built into MVC3 to deal with this scenario since it's pretty common to have forms within partial views, but surprisingly when I searched around I couldn't find anything.

So to get around the issue I added the view model to TempData before the redirect and revalidated it in my BaseController. Here's the code:

Account Controller

public class AccountController : BaseController
{
    ...

    [HttpPost]
    public ActionResult Login(LoginModel viewModel)
    {
        if (!ModelState.IsValid)
        {
            TempData["LoginModel"] = viewModel;
            return Redirect(Request.UrlReferrer.AbsolutePath);
        }

        ...
    }
}

 BaseController

public class BaseController : Controller
{
    ...

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (TempData["LoginModel"] != null)
            TryValidateModel((LoginModel)TempData["LoginModel"]);

        base.OnActionExecuting(filterContext);
    }
}

Sponsored by