Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

De-serializing object in MVC4 action results in null values

I am using jQuery 1.9.1 and MVC 4.

I have the following javascript:

$.ajax({
    url: '/Home/doSomething',
    type: 'POST',
    data: JSON.stringify({ devices: [{ Id: 123, Name: "something", MapName: "map" },{ Id: 321, Name: "a name", MapName: "another map" }] }),
    dataType: 'json',
    contentType: 'application/json'
}

And the following c# in my HomeController:

[HttpPost]
public string doSomething( Device[ ] devices )
{
    //stuff consuming that array
}

The Device class is defined like this:

[Serializable]
public class Device
{
    public long Id;
    public string Name;
    public string MapName;
}

According to the debugger, the devices array is a 2-element array with all properties of each Device element being null.

According to chrome, the post data looks like this:

{
    "devices": [
        {
            "Id": 123,
            "Name": "something",
            "MapName": "map"
        },
        {
            "Id": 321,
            "Name": "a name",
            "MapName": "another map"
        }
    ]
}

What is wrong here that is making MVC swear up and down that those objects are null, yet still giving me an appropriate-length array of them?

I have tried posting the array directly, without calling JSON.stringify on it. I have tried posting the array inside an object as a property called "devices", again without strigifying it. I have tried posting the array inside an object as a property called "devices", while only stringifying the array itself.

All of these result in bad behavior of one form or another. Either chrome does not post the appropriate data in the first place, or MVC does not de-serialize it.

I have scoured the web and can't seem to find any examples of why this should be broken.

Edit 2013-02-21 13:12 UTC-5:

I have also tried this without using JSON and just letting jQuery post it as form data. Here is the code for that:

var postData = { devices: [{ Id: 123, Name: "something", MapName: "map" }, { Id: 321, Name: "a name", MapName: "another map" }] };
$.ajax({
    url: '/Home/doSomething',
    type: 'POST',
    data: postData
});

And the C# is still the same as above.

The behavior is still the same as when it was JSON, though. MVC sees an array of 2 elements, but all values of the objects in that array are default (0 for the integer and null for the strings).

like image 628
dodexahedron Avatar asked Feb 20 '13 21:02

dodexahedron


1 Answers

Here's what finally worked...

First, I changed the javascript to make the object with a property called "devices" that contains the stringified array:

var postData = { devices: JSON.stringify([{ Id: 123, Name: "something", MapName: "map" }, { Id: 321, Name: "a name", MapName: "another map" }]) };
$.ajax({
    url: '/Home/doSomething',
    type: 'POST',
    dataType: 'json',
    data: postData
    }

Then I made the controller action take a single string called "devices" and de-serialized it manually using JSON.Net:

[HttpPost]
public string MakeMmLinks( string devices )
{
    List<Device> devicesList = JsonConvert.DeserializeObject<List<Device>>( devices );
    ...
}

This worked fine, but what bothers me is that object de-serialization is supposed to be something that MVC handles natively.

If anyone has any insight on what happened here or what I did wrong, I'd love to hear it.

like image 128
dodexahedron Avatar answered Oct 02 '22 01:10

dodexahedron