1

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>

2 Answers 2

2

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 } ] } ] }
Sign up to request clarification or add additional context in comments.

3 Comments

I've updated the post to clarify... I'm not creating the form params myself. Again, this is just how Fiddler displays them.
@c_bit, the fact that Fiddler is displaying the parameters like this means that they are sent like this and as I explained in my answer the default model binder is not capable of understanding such syntax which explains why you are getting nulls. I've shown the correct syntax you need if you want to use query string parameters. var data = { Id: Model.Id, Foos: Model.Foos }; is simply not going to work with complex parameter collections. You might try sending a JSON request instead as shown in my answer. For this of course you need a JSON valueprovider. MVC 3 has out of the box.
And here's a blog post which illustrates how to send JSON requests in prior versions of MVC 3.
0

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.

5 Comments

That's just how Fiddler represents the form params. I'll get a JSON sample
@c_bit, yes, I'm sure that's how Fiddler is representing them, but it's also because that's how they're being sent over. jQuery allows you to send data via AJAX using a variety of mechanisms, including both form POST and JSON. You are clearly using the form POST variant, and the name part of the name/value pairs are formatted incorrectly for the ASP.NET MVC model binder.
Not sure if I understand, the method is POST. The data is a JSON object.
@c_bit, no the data is a Javascript object. When the data is transported over the wire using the { name: value } syntax, only then is it JSON. What you have here is a Javascript object being transported via form POST parameters.
Thanks for the terminology correction, though it doesn't answer the problem. I'll try Darin's JSON valueprovider recommendation and see what happens. Thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.