I’m sure that some (if not many) of you know this little approach for posting data from a JSON POST action (through jQuery) to an MSMVC Controller. If you don’t, keep reading otherwise go read something more important :)
As Phil noted, what the title should read is Receiving JSON Data from An Action Method, so my apologies for being misleading on the title. To see how you can actually post JSON data, check out Phil's Sending JSON to an ASP.NET MVC Action Method Argument post.
What are you trying to do?
While working on MSMVC sites, I (like many of you) find myself doing a lot of user interaction with AJAX (via jQuery) on the client. At times, I will need to post several pieces of related data to an action and then get a response back from the server. If you’re doing some clever routing to create a more RESTful resource, then this will not work for you since you’ll need to pass the information as dictated by your route. But if you have a controller action that takes a chunk of data, then this will work perfectly for you.
Again, the goal here is to keep things pretty simple and leverage as much as the runtime’s out of box wiring as possible.
How do we do it?
Take the following form (design and html):
The whole purpose of this form is to take the data, do some simple data validation and then POST the data to the server for processing. This can be done in several ways, since we’re doing a POST action, we opt to use the jQuery.post() method. As the documentation states, this is nothing more than an explicit setting of the jQuery.ajax() API function which specifies POST as the action method.
One of the parameters that can be passed to the post API call is the actual data for the call. The type of this data parameter can be either a map (structure) or string since this will be passed as part of the request body. To get the most “bang for your buck” with this API, you’ll want to have the data parameter be a map (structure) and let the jQuery and MSMVC runtime do the heavy lifting for you. Let’s examine the data that’s request by our controller for the above form.
All we need for this request to be valid is a nothing more than a simple input model to hold the “person” information as well as an action to receive it:
As you can see, there's nothing complicated about these pieces. Just a simple controller action that takes in an Input (View) Model and returns a JSON data structure back to the caller. The only thing that can be consider complicated about this action is the [HttpPost] restriction, since as we stated earlier, we're doing a jQuery post API call.
One of the nicest features of MSMVC is the concept of a IModelBinder, which performs a lot of heavy lifting for you when you transfer complex objects via a request. Out of the box, the DefaultModelBinder will wire up primitive, (light) complex types and collections for you by pulling information from the request (request body, query string, form data, etc.) In other words, if you provide the right information for a request, the DefaultModelBinder will do the rest for you. Let’s go back and examine our jQuery POST code.
What we need to do here is simple,
- Get the values out of the input elements
- Perform (poor/simple) validation
- POST the data to the server
- Get the response and display the information
The previous list can be accomplished by the following:
In the above sample, all the magic takes place with the aide of the "Person" structure that's passed as a parameter to the POST call. If we examine the request body (with the aide of Firebug) we can see how the request is actually structured:
The outlined area show that the data within the request is passed as key-value pairs (application/x-www-form-urlencoded) to the server processing. Again, since MSMVC comes with the DefaultModelBinder, we get the mapping of the request data into our input (view) model for free:
From here, we can easily return JSON back to the client and allow it to do processing as it sees fit. In our case, we’ll just display the data to the user as a simple message:
Pretty straight forward and simple, huh? If you’re interested on the code, go here: http://github.com/jglozano/samples/tree/master/JSONMvc