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

185

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

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

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

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
}

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

Какие-нибудь советы?

rodbv
источник
Request["values[]"]
Tocco

Ответы:

247

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

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

Сначала яваскрипт:

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 »». Надеюсь это поможет!

MrDustpan
источник
3
Хорошо, что я нашел этот ответ, теперь я могу отправить массив Guid и Action получает их в List <Guid>. Спасибо
Tx3
43
Здесь нужно отметить две важные вещи. 1) dataType: "json" 2.) Традиционный: true. Без них массив строк не будет передан в методы действия
Танигайнатан
1
Обратите внимание, что dataType: 'JSON'jQuery попытается проанализировать ответ как JSON и выдаст ошибку, если он не является допустимым JSON.
сеннет
8
@Thanigainathan dataType: 'json'для возвращаемого типа и не требуется отправлять массив в Action. contentType: "application/json; charset=utf-8", это один, но в некоторых случаях, как это не требуется.
Ручан
1
@emzero usevar postData = { id: 45, [{myClassProp1: 1, myClassProp2: 2}, {}...], anotherParam: "some string" };
Ник М
108

К вашему сведению: 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
Дастин Дэвис
источник
8
Это то, что заставило меня немного почесать голову. настройка $.ajax({ ..., traditional: true});поможет вернуться к традиционной сериализации.
juhan_h
Мне это нужно для того, чтобы маршрут ASP.NET MVC правильно использовал простой массив строковых значений js.
BrandonG
Ваш ответ действительно полезен. У меня такая же ситуация, но она есть ints. Когда я использую traditional: true, это работает, ваш ответ и ссылка объясняет, почему это так. Это также работает, когда я использую type: "POST", без использования traditional: true. Это почему? Не могли бы вы уточнить. К вашему сведению, я использую Asp.Net Mvc.
Барнс
Есть ли способ в ASP.NET для анализа анонимного массива, как это без индексов? Значения [] = 1 & Значения [] = 2 & Значения [] = 3
Чарльз Оуэн
24

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

$.post("/your/url", $.param(yourJsonObject,true));
Евгений
источник
Работает хорошо и идеально подходит для меня, так как я использую $ .post () вместо $ .ajax (). Спасибо !
ПОПРАВИТЬ
9

Не размещайте данные в виде массива. Для привязки к списку пары ключ / значение должны быть представлены с одинаковым значением для каждого ключа.

Вам не нужна форма для этого. Вам просто нужен список пар ключ / значение, которые вы можете включить в вызов $ .post.

Крейг Штунц
источник
3
Спасибо. Обновленный URL: haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Wiebe Tijsma
6

В .NET4.5,MVC 5

Javascript:

объект в JS: введите описание изображения здесь

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

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

C #

Объекты:

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)
{
....
}

Объект получен:

введите описание изображения здесь

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

Матас Вайткявичюс
источник
4

Еще одна реализация, которая также работает со списком объектов, а не только со строками:

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) 
    });
}
d.popov
источник
1

Как я уже говорил здесь ,

если вы хотите передать пользовательский объект 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);
}
Мохсен Афшин
источник
0

Вы можете установить глобальный параметр с

jQuery.ajaxSettings.traditional = true;
mr_squall
источник
-1

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

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

DavidW
источник