Как я могу отправить массив строк в ASP.NET MVC Controller без формы?

Я создаю небольшое приложение, чтобы научить себя ASP.NET MVC и JQuery, и одна из страниц - это список элементов, в которых некоторые могут быть выбраны. Затем я хотел бы нажать кнопку и отправить список (или что-то подобное) моему контроллеру, содержащему идентификаторы элементов, которые были выбраны, используя функцию JQuery Post.

Мне удалось получить массив с идентификаторами элементов, которые были выбраны, и теперь я хочу опубликовать это. Один из способов сделать это - иметь фиктивную форму на моей странице со скрытым значением, а затем установить скрытое значение с выбранными элементами и опубликовать эту форму; это выглядит круто.

Есть ли более чистый способ достичь этого, отправив массив непосредственно на контроллер? Я пробовал несколько разных вещей, но похоже, что контроллер не может отобразить полученные данные. Здесь код пока:

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

И тогда мой контроллер выглядит следующим образом

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

Все, что мне удалось получить, это "null" в параметре контроллера...

Любые советы?

Ответ 1

Я изменил свой ответ, чтобы включить код для тестового приложения, которое я сделал.

Обновление: я обновил jQuery, чтобы установить "традиционный" параметр в true, чтобы это снова работало (на ответ @DustinDavis).

Сначала 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
    });
}

И вот код в моем классе контроллера:

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

Когда я вызываю эту функцию javascript, я получаю сообщение "Первый элемент в списке:" item1 ". Надеюсь, это поможет!

Ответ 2

FYI: JQuery изменил способ их сериализации почтовых данных.

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

Вы должны установить для параметра "Традиционный" значение true, другое мудрое

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

выйдет как

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

вместо

Values=1&Values=2&Values=3

Ответ 3

Спасибо всем за ответы. Еще одним быстрым решением будет использование метода jQuery.param с традиционным параметром true для преобразования объекта JSON в строку:

$.post("/your/url", $.param(yourJsonObject,true));

Ответ 5

В .NET4.5, MVC 5

JavaScript:

объект в JS: enter image description here

который делает сообщение.

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

С#

Объекты:

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

Контроллер:

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

Полученный объект:

enter image description here

Надеюсь, это сэкономит вам некоторое время.

Ответ 6

Другая реализация, которая также работает со списком объектов, а не только с строками:

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

Предполагая, что 'selectedValues' - это массив объектов.

В контроллере параметр представляет собой список соответствующих ViewModels.

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

Ответ 7

Как я обсуждал здесь,

если вы хотите передать пользовательский объект JSON в действие MVC, вы можете использовать это решение, оно работает как шарм.

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

Настоящая выгода от этого решения заключается в том, что вам не требуется определять новый класс для каждой комбинации аргументов, а кроме того, вы можете легко добавлять объекты к их оригинальным типам.

и вы можете использовать вспомогательный метод, подобный этому, чтобы облегчить вашу работу.

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

Ответ мне очень помог в моей ситуации, поэтому спасибо за это. Однако для будущих ссылок люди должны привязываться к модели, а затем проверять ее. Этот пост от Фила Хаака описывает это для MVC 2. http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

Надеюсь, это поможет кому-то.