How can I post an array of string to ASP.NET MVC C

2018-12-31 23:36发布

问题:

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?

回答1:

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!



回答2:

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


回答3:

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));


回答4:

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.



回答5:

In .NET4.5, MVC 5

Javascript:

object in JS: \"enter

mechanism that does post.

    $(\'.button-green-large\').click(function() {
        $.ajax({
            url: \'Quote\',
            type: \"POST\",
            dataType: \"json\",
            data: JSON.stringify(document.selectedProduct),
            contentType: \'application/json; charset=utf-8\',
        });
    });

C#

Objects:

public class WillsQuoteViewModel
{
    public string Product { get; set; }

    public List<ClaimedFee> ClaimedFees { get; set; }
}

public partial class ClaimedFee //Generated by EF6
{
    public long Id { get; set; }
    public long JourneyId { get; set; }
    public string Title { get; set; }
    public decimal Net { get; set; }
    public decimal Vat { get; set; }
    public string Type { get; set; }

    public virtual Journey Journey { get; set; }
}

Controller:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Quote(WillsQuoteViewModel data)
{
....
}

Object received:

\"enter

Hope this saves you some time.



回答6:

Another implementation that is also working with list of objects, not just strings:

JS:

var postData = {};
postData[values] = selectedValues ;

$.ajax({
    url: \"/Home/SaveList\",
    type: \"POST\",
    data: JSON.stringify(postData),
    dataType: \"json\",
    contentType: \"application/json; charset=utf-8\",
    success: function(data){
        alert(data.Result);
    }
});

Assuming that \'selectedValues\' is Array of Objects.

In the controller the parameter is a list of corresponding ViewModels.

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


回答7:

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);
}


回答8:

You can setup global parameter with

jQuery.ajaxSettings.traditional = true;


回答9:

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.