MVC3 - Combining Client & Server Side Validation with Unobtrusive Ajax

6. April 2012 20:00 by viperguynaz in .NET, MVC  //  Tags: , , ,   //   Comments (1)
It took a lot of searching and testing to combine several solutions that work in MVC3 to combine client-side and server-side validation with an unobtrusive AJAX post using Ajax.BeginForm. Here is my solution.

It took a ton of Google searches and testing to combine several solutions that work in MVC3 to combine client-side and server-side validation with an unobtrusive AJAX post using Ajax.BeginForm.  To get started, create a new ASP.NET MVC3 Web Application and select "Internet Application" to populate the project with models, views and controllers.  In web.config <appSettings>, you should have:

<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

Copy Views/Account/Register.cshtml to Views/Shared/_register.cshtml.  In _register.cshtml, delete the @{ ViewBag.Title } lines.  Next, change @Html.BeginForm  line to:

<script type="text/javascript">
    function ReloadForm(xhr) {
        $('#formcontent').html(xhr.responseText);
    }
    function ClearValidationErrors(){
        $('.validation-summary-errors').html('');
        $('.input-validation-error').removeClass('input-validation-error');
        $('.field-validation-error').remove();
    }
</script>

@using (Ajax.BeginForm("IndexPost", "Home", Model, new AjaxOptions { 
    UpdateTargetId = "formresults", 
    HttpMethod = "Post", 
    OnSuccess = "ClearValidationErrors", 
    OnFailure = "ReloadForm(xhr)" }))
This changes the form to an unobtrusive ajax post form that handles errors with the new method ReloadForm.  The ReloadForm callback includes the response object xhr.  If the post is successful, the contents of the div with id="formresults" gets replaced with the response and any errors are cleared with the callback function ClearValidationErrors specified in the OnSuccess property.  If the post fails (response status code other than 200), then the callback function ReloadForm replaces the contents of the div with id="formcontent" with the response.  
 
Next, create the partial Views/Shared/_results and just add some simple html to see that results are returned:
<h2>Thanks for registering!</h2>
<p>You have successfully registered</p>
 
Now - in Views/Shared/_Layout.cshtml, define a new header section to insert lines into the header:
    @if (IsSectionDefined("Header"))
    {
        @RenderSection("Header")
    }
 
Then, in Views/Home/Index.cshtml instantiate the header section to add the required JavaScript files:
@section Header
{
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
}
 
And, at the bottom of the same file, add the divs mentionted above and render the _register partial:
<div id="formcontent">
    @{ Html.RenderPartial("_register", Model); }
</div>
<div id="formresults"></div>
Finally, again in Index.cshtml - declare the view model:
@model AjaxTest.Models.RegisterModel
 
Last, but not least, update the Home controller with:
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View(new AjaxTest.Models.RegisterModel());
        }

        [HttpPost]
        public ActionResult IndexPost(AjaxTest.Models.RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                return PartialView("_results");
            }

            HttpContext.Response.StatusCode = 500;
            HttpContext.Response.Clear();
            return PartialView("_register", model);
        }
 
So, client-side validation is enabled and will catch most errors.  If we get back to the server and the model is still not valid, then we set the response code to reflect a server error and return the original form with the model and validation errors.  in this simple example, you will never get past client-side validation.  To test the server-side validation, go back to the web.config and set ClientValidationEnabled to false, then run and test with partial input.
 
 
The complete solution is attached below.
 
Cheers and happy coding!!!

AjaxTest.zip (2.38 mb)

Comments (1) -

Micle
4/9/2012 3:05:10 AM #

Great Article

We can also submit our .net related article links on http://www.dotnettechy.com to improve website traffic.

Its good place for .NET Professionals

Pingbacks and trackbacks (3)+

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading