Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am creating a small app to teach myself ASP.NET MVC and JQuery, and one of the pages is a list of items in which some can be selected. Then I would like to press a button and send a List (or something equivalent) to my controller containing the ids of the items that were selected, using JQuery's Post function.

I managed to get an array with the ids of the elements that were selected, and now I want to post that. One way I could do this is to have a dummy form in my page, with a hidden value, and then set the hidden value with the selected items, and post that form; this looks crufty, though.

Is there a cleaner way to achieve this, by sending the array directly to the controller? I've tried a few different things but it looks like the controller can't map the data it's receiving. Here's the code so far:

function generateList(selectedValues) {
   var s = {
      values: selectedValues //selectedValues is an array of string
   };
   $.post("/Home/GenerateList", $.toJSON(s), function() { alert("back") }, "json");
}

And then my Controller looks like this

public ActionResult GenerateList(List<string> values)
{
    //do something
}

All I managed to get is a "null" in the controller parameter...

Any tips?

share|improve this question
Although, you can access the same data by using Request["values[]"] – Tocco Jul 18 '11 at 18:46

6 Answers

up vote 109 down vote accepted

I modified my response to include the code for a test app I did.

Update: I have updated the jQuery to set the 'traditional' setting to true so this will work again (per @DustinDavis' answer).

First the javascript:

function test()
{
    var stringArray = new Array();
    stringArray[0] = "item1";
    stringArray[1] = "item2";
    stringArray[2] = "item3";
    var postData = { values: stringArray };

    $.ajax({
        type: "POST",
        url: "/Home/SaveList",
        data: postData,
        success: function(data){
            alert(data.Result);
        },
        dataType: "json",
        traditional: true
    });
}

And here's the code in my controller class:

public JsonResult SaveList(List<String> values)
{
    return Json(new { Result = String.Format("Fist item in list: '{0}'", values[0]) });
}

When I call that javascript function, I get an alert saying "First item in list: 'item1'". Hope this helps!

share|improve this answer
1  
It worked, thanks a lot :) – rodbv Nov 22 '08 at 9:15
1  
It's good that I found this answer, now I am able to send array of Guid's and Action receives them to List<Guid>. Thanks – Tx3 May 17 '11 at 9:36
10  
There two important things to note here . 1)dataType: "json"2.) traditional: true .Without them string array wont be passed to action methods – SnakeEyes Jul 25 '11 at 7:32
@SnakeEyes i was struggling with this, and your comment about the traditional:true helped me solve it, thanks – Vamsi Krishna Mar 15 at 7:37
100th vote! thanks :) – nvrtheless May 17 at 12:53

FYI: JQuery changed the way they serialize post data.

http://forum.jquery.com/topic/nested-param-serialization

You have to set the 'Traditional' setting to true, other wise

{ Values : ["1", "2", "3"] }

will come out as

Values[]=1&Values[]=2&Values[]=3

instead of

Values=1&Values=2&Values=3
share|improve this answer
1  
Thanks! I was pretty confused until I scrolled down to this! – Chris Apr 13 '10 at 1:15
2  
This is something that got me scraching my head for a while. setting $.ajax({ ..., traditional: true}); will help to revert to traditional serialization. – juhan_h May 31 '11 at 8:52

Thanks everyone for the answers. Another quick solution will be to use jQuery.param method with traditional parameter set to true to convert JSON object to string:

$.post("/your/url", $.param(yourJsonObject,true));
share|improve this answer

Don't post the data as an array. To bind to a list, the key/value pairs should be submitted with the same value for each key.

You should not need a form to do this. You just need a list of key/value pairs, which you can include in the call to $.post.

share|improve this answer
2  
Thanks. Updated url is: haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx – Zidad Mar 1 '10 at 13:46

The answer helped me a lot in my situation so thanks for that. However for future reference people should bind to a model and then validate. This post from Phil Haack describes this for MVC 2. http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

Hope this helps someone.

share|improve this answer

As I discussed here ,

if you want to pass custom JSON object to MVC action then you can use this solution, it works like a charm.

    public string GetData()
    {
        // InputStream contains the JSON object you've sent
        String jsonString = new StreamReader(this.Request.InputStream).ReadToEnd();

        // Deserialize it to a dictionary
        var dic = 
          Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<String, dynamic>>(jsonString);

        string result = "";

        result += dic["firstname"] + dic["lastname"];

        // You can even cast your object to their original type because of 'dynamic' keyword
        result += ", Age: " + (int)dic["age"];

        if ((bool)dic["married"])
            result += ", Married";


        return result;
    }

The real benefit of this solution is that you don't require to define a new class for each combination of arguments and beside that, you can cast your objects to their original types easily.

and you can use a helper method like this to facilitate your job

public static Dictionary<string, dynamic> GetDic(HttpRequestBase request)
{
    String jsonString = new StreamReader(request.InputStream).ReadToEnd();
    return Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);
}
share|improve this answer

protected by Will Oct 20 '10 at 10:29

This question is protected to prevent "thanks!", "me too!", or spam answers by new users. To answer it, you must have earned at least 10 reputation on this site.

Not the answer you're looking for? Browse other questions tagged or ask your own question.