Post JSON objects with nested classes to MVC action

Default view model binding of ASP.NET MVC has a disadvantage when using view models with nested classes and JSON objects. The binding is unable to recognize such nested classes and it initializes them to NULL value. This text describes a cause and solutions.

The Issue

Let’s we have the following declaration of objects in Javascript:

We’d like to post this data to MVC action with jQuery function $.post() this way:

In the MVC action we want to use the property Location. If you set a breakpoint into the action, you’ll see that the property is NULL in spite of the fact the data is sent. You may find that using FireBug. The requests’ form data represents all sent properties:

A sample code which demonstrates some aspects described in the text you can find here:

The Cause

JSON formatting does not corresponds to what MVC model binding expects. You can notice that when you’re using MVC extensions like @Html.EditorFor(...)  and others with submitting a form, the MVC model binding works correctly. Tracing requests to the server you can notice that data is passed in different formats:

  • MVC model binding cannot recognize JSON nested objects which are sent as array elements, like this way  Addr[Location]
  • MVC can recognized nested objects if they are sent as properties, like this way  Addr.Location

MVC DefaultModelBinder  has its own convention for naming complex objects and this is the reason we cannot use it as it is. Probably you would suggest using the following JSON object initialization:

It does not help here since representation of the object is the same when you post it to the server.

The Solution

The simplest solution to send JSON objects without any custom development is sending objects as text. That can be achieved with JSON function  stringify. In order to do that JSON object should be converted to string before posting to the server. When server receives the string, it should convert it back with  JavaScriptSerializer . The MVC action should receive strings instead of objects. The solution above can be automated with  ActionFilterAttribute  which encapsulate all deserialization logic and allows to use objects in action parameters. The automation can be useful in some big systems, but what if we want to use the default MVC model binding and have objects in action parameters?

In the later case we need to patch JSON object representation before sending it to the server. The following jQuery plugin helps with that.

This plugin was found here

No Comments

You can leave the first : )

Leave a Reply