ASP.NET MVC 3: Using JSON result for jQuery Ajax Forms validation


This blog post is my third blog post about jQuery Ajax forms with ASP.NET MVC 3.

This third post shows how to customize the way the validation result is handled on the client side. The first post about jQuery Ajax forms with ASP.NET MVC 3 describes how to use partial page updates to avoid complete page reloads after submitting the form. In detail, the server validates the (form) data and returns HTML that either contains the form including server side errors or a success message and on the client side this HTML code is used to replace the old form with. Using this technique there is no way to customize the handling of the success message; for example it could be desirable to show the success message in a popup instead of replacing the form.

To make this flexibility possible the server’s response is changed from (pure) HTML code to a JSON array containing to values:

  1. A boolean that indicates whether the server side validation was successful
  2. A string that contains (depending of the validation result) the HTML code of the form with server side errors or the success message

To enable the server to create a JSON array containing the (rendered) HTML code of a view we will use the extension method RenderPartialViewToString() that I’ve described here.

We start with the source code of the second post and change the HomeController‘s Form action to look like this:

[HttpPost]
public ActionResult Form(ValidationModel validationModel)
{
  Thread.Sleep(2000); // Fake processing time
  if (!ModelState.IsValid)
  {
    return Json(new object[] {false, this.RenderPartialViewToString("Partial/_Form", validationModel)});
  }
  return Json(new object[] {true, this.RenderPartialViewToString("Partial/_Success", validationModel)});
}

On the client side we add a new “success dialog”

and some jQuery JavaScript that initializes this dialog:

// Initialize success dialog ...
$("#SuccessDialog").dialog({
  autoOpen: false,
  draggable: false,
  modal: true,
  resizable: false,
  title: "Success",
  buttons: [
    {
      text: "Continue",
      click: function () { $(this).dialog("close"); }
    },
    {
      text: "Reload",
      click: function () { location.reload(); }
    }
  ]
});

In this example we add two buttons to the dialog, one for closing the dialog and continuing editing and one to reload the page.

In a last step we adapt the success handler of the jQuery Ajax post to process the JSON array returned by the server:

success: function (data) {
  if (data[0]) {
    $("#SuccessContainer").html(data[1]);
    $("#SuccessDialog").dialog("open");
   } else {
     $("#FormContainer").html(data[1]);
     $.validator.unobtrusive.parse("form");
   }
}

You can download the Visual Studio 2010 project containing all the source code here.

Summarized all three blog posts have shown how to build Ajax’s forms with ASP.NET MVC 3 supporting client side and server side validation, partial page update and a customizable way how to send data to the server and how to handle the server’s response on the client side.

,

7 responses to “ASP.NET MVC 3: Using JSON result for jQuery Ajax Forms validation”

  1. I cannot get the client-side aspect of your example to work in IE8. Do you know how to fix this? I thought it might be a library version issue, but even the latest versions do not seem to work.

  2. Hi Joseph, thanks for your comment. IMHO, the example you can download here should work in IE8.
    Do you get any JavaScript error? Have you also tried the examples source code from part 1 or part 2 of my posts about jQuery Ajax forms with ASP.NET MVC 3?

  3. I think I fixed my IE8 issue. It appears to be that on IE8 the client side validation is not able to preempt the form submit event handler. The solution I’m using is to insert ‘if (!form.valid()) return;’ immediately after ‘var form = $(this);’ in the event handler. This seems to be working so far. If anyone has any additional insight or a better solution, I would love to know what it is.

  4. Hi Joseph,
    sorry for the delay in my response. I see the problem in IE8. I think, the reason is that in IE8 the submit handler that is registered using jQuery live is triggered before the validation has been performed (see http://forum.jquery.com/topic/jquery-validate-live-submit-firing-before-validation-in-ie). Using

    $("form").live("submit", function (event) {
      event.preventDefault();
      var form = $(this);
      if (!form.valid()) return;
      [...]
    

    as you have suggested seems to fix the problem.

  5. Hi Joseph,

    Great blob series, that took ,e far down the path of JQuery!

    Just a quick note – when I implemented this structure, I found that it looked like my PartialView was being cached.

    After many hours of searching, I found that this is actually based on the way that HtmlHelpers use ModelState, and so to prevent the behaviour I added

    ModelState.Clear() before reconstructing the PartialView.

    Hope this helps your readers,

    All the best,

    Leroy.

  6. These posts are helpful. One additional question: do you know whether a form added to the page after initial load (e.g., via some AJAX call) would require additional processing to “ajaxify” it? I’m having a curious issue where I can use such forms in the modern browsers (IE9, Chrome, Firefox), but not IE8. IE8 just posts the form contents, instead of submitting them via XHR. However, IE8 works properly if the form is loaded first along with the rest of the page. I’m guessing I need to tell AJAX-loaded forms to do something, but I’m not sure what.

Leave a Reply

Your email address will not be published. Required fields are marked *