Як я можу розмістити масив рядків на контролері ASP.NET MVC без форми?


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
}

Все, що мені вдалося отримати, це "нуль" у параметрі контролера ...

Якісь поради?


Хоча ви можете отримати доступ до тих же даних, скориставшисьRequest["values[]"]
Tocco

Відповіді:


247

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

Оновлення: я оновив 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'". Сподіваюся, це допомагає!


3
Добре, що я знайшов цю відповідь, тепер я можу надіслати масив Guid's, і Action отримує їх у Список <Guid>. Спасибі
Tx3

43
Тут слід зазначити дві важливі речі. 1) dataType: "json" 2.) Традиційний: true. Без них рядковий масив не буде переданий методам дій
Thanigainathan

1
Зауважте, що dataType: 'JSON'змушує jQuery намагатися проаналізувати відповідь як JSON, і буде помилка, якщо вона не є дійсною JSON.
sennett

8
@Thanigainathan the dataType: 'json'- це тип повернення і не потрібно відправляти масив Action. contentType: "application/json; charset=utf-8", є одним, але в деяких випадках подібного не потрібно.
Ручан

1
@emzero usevar postData = { id: 45, [{myClassProp1: 1, myClassProp2: 2}, {}...], anotherParam: "some string" };
Nick M

108

FYI: JQuery змінив спосіб серіалізації публікацій.

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

Ви повинні встановити "Традиційне" налаштування на істинне, інше

{ 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 значень рядків.
БрендонГ

Ваша відповідь справді корисна. У мене така ж ситуація, але це і з ints. Коли я використовую traditional: true, він працює, ваша відповідь і посилання пояснюють, чому саме так. Він також працює, коли я використовую type: "POST", без використання traditional: true. Чому так? Чи можете ви, будь ласка, докладно. FYI Я використовую Mpc Asp.Net Mvc.
barnes

Чи існує спосіб в ASP.NET проаналізувати подібний анонімний масив без індексів? Значення [] = 1 & Значення [] = 2 & Значення [] = 3
Чарльз Оуен

24

Дякую всім за відповіді. Іншим швидким рішенням буде використання методу jQuery.param з традиційним параметром, встановленим у true, для перетворення об'єкта JSON у рядок:

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

Добре працює і чудово підходить для мене, оскільки я використовую $ .post () замість $ .ajax (). Дякую !
AFract

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

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;

-1

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

Сподіваюся, що це комусь допоможе.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.