MVC Model Binding with an Ajax Form Submit

MVC Model Binding with an Ajax Form Submit

You may come across a time where you would like to submit a form using Ajax, and still want to preserve the useful model binding of MVC. Normally when you submit a form using a standard submit (non async), the MVC framework will automatically take care of pulling your values out of your form and populating a model on your controller. This is one of the most useful, time-saving features of MVC.

But when you want to submit a form using Ajax, you are forced to provide these values to the controller yourself, usually through the use of JSON to Model binding. But how do you easily take your existing form and transform it into valid JSON? This is what we’ll be talking about in this post, so read on.

Let’s say you have a basic controller that takes a model as its only parameter (pretty standard):


[HttpPost]
public void MyController(MyViewModel model)
{
    _someService.DoSomething(model);
    return View(model);
}

Now some jQuery to submit this form asynchronously using Ajax:


function SubmitForm() {

 var $form = $("#myFormID");
 var jsonData = $form.serializeObjectIntoJson();
 var jsonString = JSON.stringify(jsonData);

 $.ajax({
 type: 'POST',
 url: '/MyController',
 data: jsonString,
 contentType: 'application/json; charset=utf-8',
 success: function () {
 window.location.reload(true); //whatever you need to do after a successful ajax response
 }
 });
}

//very useful extension taken from
//http://stackoverflow.com/questions/1184624/convert-form-data-to-js-object-with-jquery
//All credit goes to Tobias Cohen

$.fn.serializeObjectIntoJson = function () {
 var o = {};
 var a = this.serializeArray();
 $.each(a, function () {
 if (o[this.name] !== undefined) {
 if (!o[this.name].push) {
 o[this.name] = [o[this.name]];
 }
 o[this.name].push(this.value || '');
 } else {
 o[this.name] = this.value || '';
 }
 });
 return o;
};

A few things I want to point out here. First, is that we’re using jQuery’s serializeArray function to serialize our form into an array of JavaScript objects, essentially key/value pairs. You can read more about serializeArray here, but essentially it’s description is: “Encode a set of form elements as an array of name and values.”.

Once we call serializeArray on our form, we’ll end up with a data structure like this:


[
 {
 name: "a",
 value: "1"
 },
 {
 name: "b",
 value: "2"
 },
 {
 name: "c",
 value: "3"
 },
 {
 name: "d",
 value: "4"
 },
 {
 name: "e",
 value: "5"
 }
]

As you can tell, that’s not JSON. So how do we convert this to JSON? Well thanks to Tobias Cohen from this Stack Overflow Question, we have a simple JavaScript extension that will do this for us. You can see it above, but it’s basically like so:


$.fn.serializeObjectIntoJson = function () {
 var o = {};
 var a = this.serializeArray();
 $.each(a, function () {
 if (o[this.name] !== undefined) {
 if (!o[this.name].push) {
 o[this.name] = [o[this.name]];
 }
 o[this.name].push(this.value || '');
 } else {
 o[this.name] = this.value || '';
 }
 });
 return o;
};

<pre>

So with any luck, if you convert your form into JSON using the serializeArray and serializeObjectIntoJson extension provided above, and THEN send it to your controller action, MVC model binding will take over and do the rest for you, and you’ll have a nicely correctly bound model.

As a side note. MVC model binding relies heavily on naming convention. If you run into any problems where custom binding needs to be done. (For example in the case of changing names on inputs so that they no longer match model property names). You can simple set those properties on the JSON data yourself before sending back to the controller, like below:


function SubmitForm() {

 var $form = $("#myFormID");
 var jsonData = $form.serializeObjectIntoJson();

//set anything that was not properly serialized here
 jsonData.SomeCustomProperty = $('crazyNamedInput').val();
 jsonData.SomeOtherCustomProperty = $('anotherCrazyNamedInput').val();</pre>
<pre> var jsonString = JSON.stringify(jsonData);

 $.ajax({
 type: 'POST',
 url: '/MyController',
 data: jsonString,
 contentType: 'application/json; charset=utf-8',
 success: function () {
 window.location.reload(true); //whatever you need to do after a successful ajax response
 }
 });
}

I hope this solution will help you out the next time you find yourself needing to convert a form into JSON for an ajax request.

Share Your Thoughts!

Testimonials

What My Clients Say

Karin - Hope and Future

Brent has always been very prompt and generally exceeds our expectations with his work. His maintenance fee is very reasonable. I strongly recommend him!  We get many compliments on our beautiful web site!

Dan

I contacted Krueger Web Design and Brent did everything.  He setup a test site with the changes so we could verify everything was correct before we transferred from my old hosting provider.  During the setup and conversion Brent was extremely professional and responsive. He responded to any issues the same day.

Dan Kaufman
Emily - GFCLT

We've had a great experience working with Krueger Web Design. Prompt responses, great ideas, effective work... all at a reasonable price! This was the perfect fit for our organization.

Mahmud - ACMC

I would love to recommend you to anyone! You have been very helpful when we needed you the most.

Brian - SEMNIC

Working with Krueger Web Design was effortless. Communicating what I wanted for the website and the results that I saw were identical. The customer service was always prompt and I am completely satisfied with the product.

Zach - Stadium Club

Exactly what I wanted! Fast turnaround time and very affordable. Answered all of our questions quickly and made adjustments promptly. Very easy to work with and puts everything into terminology that even I can understand!

Contact Krueger Web Design

Have a question for me? Need an estimate on some work? You can email me at brent@kruegerwebdesign.com or drop me a line using the button below:

Copyright © 2017 Krueger Web Design - All rights reserved
Web Design in Madison, WI