Reputation: 38529
I've got an ajax post being constructed like this:
var myData = [
{
id: "a",
name: "Name 1"
},
{
id: "b",
name: "Name 2"
}
];
$.ajax({
type: 'POST',
url: '/myurl/myAction',
data: { items: myData },
dataType: 'json',
error: function (err) {
alert("error - " + err);
}
});
And an MVC controller:
[HttpPost]
public JsonResult MyAction(MyClass[] items)
{
}
MyClass
is just a simple representation of the data:
public class MyClass {
public string Name {get; set; }
public string Id {get; set; }
}
When the javascript makes the post request, the controller action does indeed receive 2 items, however the properties (id, name) in these items are null.
Checking the request in fiddler, the body looks like this:
Name | Value
items[0][Name] | Name 1
items[0][Id] | a
items[1][Name] | Name 2
items[1][Id] | b
Have I missed something?
Upvotes: 34
Views: 37349
Reputation: 1934
you can use this code to solve the problem :
$.ajax({
url: '/myurl/myAction',
data: { '': items },
method: "POST",
dataType: 'json',
success: function (xhr, status, response) {
},
error: function (xhr, status, response) {
}
});
[HttpPost]
public JsonResult MyAction(IEnumerable<MyClass> items)
{
}
Upvotes: -4
Reputation: 1039438
Have I missed something?
Yes, take a look at the following article to understand the correct wire format that the default model binder expects for binding collections. In other words, for this to work, instead of:
items[0][Name] | Name 1
items[0][Id] | a
items[1][Name] | Name 2
items[1][Id] | b
your payload should have looked like this:
items[0].Name | Name 1
items[0].Id | a
items[1].Name | Name 2
items[1].Id | b
Unfortunately with jQuery it can be quite frustrating to achieve this payload. For this reason I would recommend that you use a JSON payload if you want to send complex objects/arrays to your server with AJAX:
$.ajax({
type: 'POST',
url: '/myurl/myAction',
data: JSON.stringify({ items: myData }),
contentType: 'application/json',
error: function (err) {
alert("error - " + err);
}
});
Things to notice:
data: JSON.stringify({ items: myData })
instead of data: { items: myData }
contentType: 'application/json'
dataType: 'json'
Now your payload looks like this:
{"items":[{"id":"a","name":"Name 1"},{"id":"b","name":"Name 2"}]}
Upvotes: 65