Carlos Bittencourt
Carlos Bittencourt

Reputation: 352

asp.net mvc json deserializer not working

In a POST to an MVC controller, I'm using JQuery to send a JSON object with two properties: Id and Foos. For some reason all the properties of each FooModel instance are all null/empty.

Here's the method:

[HttpPost]
public ActionResult EditFoo(int Id, FooModel[] foos)

This is my fiddler-retrieved form parameters (I can confirm that the data is being passed to the server). I've also validated with two debuggers that the JSON object contains all the correct values.

Id                             17934
Foos[0][Label]                 My Foo
Foos[0][Bars][0][Label]        First Bar
Foos[0][Bars][0][Id]           1
Foos[0][Bars][1][Label]        Second Bar
Foos[0][Bars][1][Id]           2

FooModel looks like this:

public class FooModel
{
    public string Label { get; set; }
    public IList<Bar> Bars { get; set; }
}

In the EditFoo method, I can see the array with the right number of Foo items (in this example, 1). However all the properties in each FooModel instance are all null/empty.

EDIT 1:

To clarify: I'm not creating the form parameters by hand. I'm passing a true JSON object back to the $.ajax() through a ajaxArgs.data.

The form data itself looks like this:

Id=17934&Foos%5B0%5D%5BId%5D=1&&Foos%5B0%5D%5BLabel%5D=My+Foo...

And I can't find an fast way to get the JSON itself as a string, but this is the variable assigned to ajaxArgs.data (the Foos have all their properties):

var data = { Id: Model.Id, Foos: Model.Foos };

EDIT 2:

I'm using JavaScriptSerializer to create a string that like below:

    public static string ToJson(this object obj)
    {
        var serializer = new JavaScriptSerializer();
        var foo =  serializer.Serialize(obj);
        return foo;
    }

and then making the Model available to javascript in the view like this:

<script type="text/javascript">
    var Model = <%= Model.ToJson() %>;
</script>

Upvotes: 1

Views: 591

Answers (2)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038830

The problem is that the default model binder doesn't understand a request as the one you have shown. Your request values should look like this:

Id                           17934
Foos[0].Labe                 My Foo
Foos[0].Bars[0].Label        First Bar
Foos[0].Bars[0].Id           1
Foos[0].Bars[1].Label        Second Bar
Foos[0].Bars[1].Id           2

or if you are using ASP.NET MVC 3 JSON request factory provider you could send a JSON request like this:

$.ajax({
    url: '/foo',
    type: 'POST',
    data: JSON.stringify({
        Id: 17934,
        Foos: [
            { 
                Bars: [
                    { Label: 'First Bar', Id: 1 },
                    { Label: 'Second Bar', Id: 2 }
                ]
            }
        ]
    }),
    contentType: 'application/json',
    success: function(result) {
        alert('success');    
    }
});

which should send the following request:

{ Id: 17934, Foos: [ { Bars: [ { Label: 'First Bar', Id: 1 }, { Label: 'Second Bar', Id: 2 } ] } ] }

Upvotes: 2

Kirk Woll
Kirk Woll

Reputation: 77546

You're using brackets incorrectly. This:

Foos[0][Bars][0][Label]

Should look like this:

Foos[0].Bars[0].Label

Also, this isn't JSON, they're form POST parameters.

Upvotes: 0

Related Questions