18

When I send a list of int's with jQuery like this:

$.ajax('@Url.Action("Execute")', {
    type: 'POST',
    data: {
        pkList: [1,2,3]
    }
});

Then jQuery will transform the pkList object and send it by post like this:

pkList[]:1
pkList[]:2
pkList[]:3

Which would be fine if the server is PHP but I use Asp.NET MVC3 and try to get these values with the default model binder:

public ActionResult Execute(ICollection<int> pkList)

But pkList is always null, it seems that the default model binder cannot bind it.

How do I solve this correctly?


ADDED SOLUTION

I used the solution from Darin Dimitrov with setting the traditional option in jQuery:

$.ajax('@Url.Action("Execute")', {
    type: 'POST',
    traditional: true,
    data: {
        pkList: [1,2,3]
    }
});

Now jQuery doesn't add the [] to the parameters anymore and they are sent like this:

pkList:1
pkList:2
pkList:3

And the MVC default model binder gets the values correctly.

Hope this helps someone.

3 Answers 3

21

You could use a JSON request as it will allow you to send any complex objects you wish:

$.ajax({
    url: '@Url.Action("Execute")',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify({ pkList: [1, 2, 3] }), // you could throw any javascript object you like here
    success: function(result) {
        // process the results
    }
});

The JSON.stringify method is built in modern browsers and if you want to support legacy browsers you could include the json2.js script to your site.

And to answer your question you could use set the traditional: true option to indicate to jQuery to fallback to traditional serialization of parameters since this has changed in jQuery 1.4 and if you are using a later version you have the possibility to switch back to the way parameters are serialized:

$.ajax({ 
    url: '@Url.Action("Execute")',
    type: 'POST',
    data: {
        pkList: [1, 2, 3]
    },
    traditional: true
});
Sign up to request clarification or add additional context in comments.

5 Comments

Won't the default model binder also handle comma separated lists of form encoded data as well? Something like data: { pkList: '1,2,3' }? But otherwise I use this method for all of my model serialization, the way to go for more complex objects in JS.
@PaulT., no, the default model binder will not accept data: { pkList: '1,2,3' }. If you want to handle such requests a custom model binder will be necessary where you would need to split the entries and then parse each one back to an integer. It wouldn't be necessary to go through this pain if the goal is to send an array of integers to a controller action.
ah yeah I see what you mean now, just tested it, its weird though because if you have two inputs with the same name it does actually deserialize that to a list, just jQuery's serialization to form post data doesn't handle that (ie. pkList=1&pkList=2 works)
@PaulT.: You point it out exactly, the (new) default jQuery json list serialization doesn't match the default mvc 3 default model binder json deserialization. Isn't that a little bit weird just because mvc is shipped with jQuery?
@DarinDimitrov: Thanks a lot, never known the traditional option in jQuery. I set it in my default ajax options and never have to care about that again in my projekt, works great! Also is good to know the JSON.stringify method. I don't know why this isn't included in jQuery (with fallback to legacy browsers), I think it should be?
1

Adding this because @Darin miss the controller action.

Java script code:

function sendArray() {
    var list = ["a", "b"];

    $.ajax({
        url: '@Url.Action("ActionName")',
        type: 'POST',
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify({ list }),
        dataType: "json",
        success: function (response) {},
        error: function (response) {}
    });
}

C# code

[HttpPost]
public ActionResult ActionName(List<string> list)
{
    return View();
}

1 Comment

I am going through the same method. But, null is getting received in the server.
0

Phil Haack has a great article on his blog that should point you in the right direct.

Model Binding To A List

1 Comment

Thanks mate, I read that before, but it doesn't help me, the problem was more on the jQuery side :)

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.