Передайте масив mvc Action через AJAX


123

Я намагаюся передати масив (або IEnumerable) входів через AJAX до дії MVC, і мені потрібна невелика допомога.

javascript є

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {...

і дія контролера

public ActionResult MyAction(IEnumerable<int> arrayOfValues )

На даний момент запит форматується як

controller/MyAction?_=1301503418429&arrayOfValues[]=491&arrayOfValues[]=368&arrayOfValues[]=235&arrayOfValues[]=437

Тому я майже там, якщо я зніму квадратні дужки, я отримаю правильну відповідь. Як я повинен передавати цей масив в моє отримання, щоб контролер міг розпізнати, що це таке?

Велике спасибі за вашу допомогу

Дейв

Відповіді:


149

Встановіть традиційне властивість на істинне, перш ніж здійснити дзвінок. тобто:

jQuery.ajaxSettings.traditional = true

$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {... 

3
спасибі! Ви можете, будь ласка, окреслити відмінності між традиційним та нетрадиційним аяксом? Я хотів би краще зрозуміти, що я роблю в іншій частині своєї заяви.
Том Бук

5
Ви також можете додати традиційний параметр до одного дзвінка. Тоді це не вплине на відпочинок
Gluip

1
Ця відповідь правильна, але якщо ви віддаєте перевагу встановити "традиційне" для одного дзвінка, перевірте відповідь @RionWilliams. Голосування обох. Дякую!
kzfabi

@Tom Beech Станом на jQuery 1.4 метод $ .param () рекурсивно виконує глибокі об'єкти для розміщення сучасних мов сценаріїв та рамок, таких як PHP та Ruby on Rails. Ви можете відключити цю функціональність у всьому світі, встановивши jQuery.ajaxSettings.traditional = true;
Олексій Шевельов

Жодна з цих відповідей не працювала для мене (можливо, тому, що мій контролер був контролером API?), Але я знайшов своє рішення у такій відповіді ТА
Lopsided

119

У мене в минулому виникали проблеми при спробі виконати POST (не впевнений, чи це саме те, що ви робите, але я пам'ятаю при передачі масиву в, для традиційного потрібно встановити значення true .

 var arrayOfValues = new Array();

 //Populate arrayOfValues 
 $.ajax({ 
      type: "POST",
      url: "<%= Url.Action("MyAction","Controller")%>",
      traditional: true,
      data: { 'arrayOfValues': arrayOfValues }              
 });

4
Це набагато краще, ніж просто сліпо встановити його у всьому світі у файлі web.config, як деякі люди пропонують. У іншого є свій набір хороших випадків, але ваш варіант повинен бути рішенням за замовчуванням.
Panzercrisis

Це лише відправка даних як параметр ActionResult, чи буде він викликати код Inside ActionResult? Наприклад, якщо в базу даних є якийсь код для вставки масивів значень, чи запуститься цей код?
Саураб

Це вирішило саме те, що мені було потрібно. Мої масиви поверталися як нульові в моєму контролері, поки я не додав це і отримав їх у свій контролер, як: IEnumerable <string> масив
SeanMC

52

Досить пізно, але по- різному відповідь на вже наявні тут:

Якщо замість цього $.ajaxви хочете використовувати скорочені функції $.getабо $.post, ви можете передавати масиви таким чином:


Стенограма GET

var array = [1, 2, 3, 4, 5];
$.get('/controller/MyAction', $.param({ data: array }, true), function(data) {});


// Action Method
public void MyAction(List<int> data)
{
    // do stuff here
}

Скорочена пошта

var array = [1, 2, 3, 4, 5];
$.post('/controller/MyAction', $.param({ data: array }, true), function(data) {});


// Action Method
[HttpPost]
public void MyAction(List<int> data)
{
    // do stuff here
}


Примітки:

  • Булевий параметр в $.param- це traditionalвластивість, ЯКІ ПОВИНЕН бути, trueщоб це працювало .

2
Дякуємо за пораду про традиційну власність. Я не міг зрозуміти, чому мій параметр C # недійсний. Я виявив, що тип "int []" також буде працювати в методі C # Action.
Ден Рендольф

9

Ви повинні зробити це просто чудово:

$.ajax({
   url: 'controller/myaction',
   data: JSON.stringify({
      myKey: myArray
   }),
   success: function(data) { /* Whatever */ }
});

Тоді ваш спосіб дії буде таким:

public ActionResult(List<int> myKey)
{
    // Do Stuff
}

Для вас це виглядає так, що вам просто потрібно впорядкувати свої цінності. JSONValueProvider в MVC перетворить це назад в IEnumerable для вас.


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

9

Відповідь на використання традиційного варіанту правильна. Я просто надаю додаткову додаткову інформацію для цього, хто хоче дізнатися більше.

З документації jQuery:

Станом на jQuery 1.8, метод $ .param () більше не використовує jQuery.ajaxSettings.traditional як його за замовчуванням, а за замовчуванням буде false.

Ви також можете прочитати більше тут: http://michaelsync.net/2012/04/05/tips-asp-net-mvc-javascriptserializer-3-questions-and-3-answers та http://haacked.com/archive /2008/10/23/model-binding-to-a-list.aspx

HTH


2

ЯКЩО ВСІ ВІДБУТИ НЕПРАВИ ...

Жодна з інших відповідей тут не вирішила моєї проблеми. Я намагався здійснити виклик методу GET з JavaScript на контролер веб-API MVC та надіслати масив цілих чисел як параметр у цьому запиті. Я спробував усі рішення тут, але все-таки параметр на моєму контролері з'явився NULL (або нічого для вас, користувачі VB).

Зрештою, я знайшов своє рішення в іншому записі SO , і це було насправді дуже просто: Просто додайте [FromUri]анотацію перед параметром масиву в контролері ( я також повинен був здійснити виклик за допомогою "традиційного" налаштування AJAX, щоб уникнути анотацій дужок ). Нижче див. Фактичний код, який я використав у своїй програмі.


Підпис контролера:

Підпис контролера ПРИМІТКА. Анотація в C # буде [FromUri]


JavaScript:

$.get('/api/InventoryApi/GetBalanceField', $.param({productIds: [42], inventoryFormId: 5493, inventoryBalanceType: 'Beginning'},true)).done(function(data) {console.log(data);});

Фактична рядок URL-адреси:

http://randomhostname/api/InventoryApi/GetBalanceField?productIds=42&inventoryFormId=5493&inventoryBalanceType=Beginning

2

Тут трохи пізно, але я міг використати рішення SNag далі в $ .ajax (). Ось код, якщо він допоможе комусь:

var array = [1, 2, 3, 4, 5];

$.ajax({
    type: "GET",
    url: '/controller/MyAction',
    data: $.param({ data: array}, true),
    contentType: 'application/json; charset=utf-8',
    success: function (data) {
    },
    error: function (x, y, z) {
    }
});

// Action Method
public void MyAction(List<int> data)
{
    // do stuff here
}

1

Якщо ви переходите на ASP.NET Core MVC з .Net Framework MVC, як я, справи дещо змінилися. Виклик ajax повинен бути на необробленому об'єкті, використовуючи stringify, а не передавати його дані { vals: arrayOfValues }слід JSON.stringify(arrayOfValues)таким чином:

$.ajax({
   url: 'controller/myaction',
   data: JSON.stringify(arrayOfValues),
   success: function(data) { /* Whatever */ }
});

Інша зміна, внесена в ASP.NET Core, полягає в тому, щоб запобігти підробці запиту між сайтом, тому для викликів до дії MVC методом ajax [FromBody]атрибут слід застосовувати до параметра дії таким чином:

public ActionResult MyAction([FromBody] IEnumerable<int> arrayOfValues )

Дякую, що це було надзвичайно корисно після кожної іншої перестановки способів надсилання даних не вдалося!
NibblyPig

0

Якщо ви використовуєте ASP.NET Core MVC і вам потрібно обробити квадратні дужки (а не використовувати "традиційний" варіант jQuery), єдиний знайдений IEnumerableнами варіант - це вручну побудувати метод контурлера вручну .

string arrayKey = "p[]=";
var pArray = HttpContext.Request.QueryString.Value
    .Split('&')
    .Where(s => s.Contains(arrayKey))
    .Select(s => s.Substring(arrayKey.Length));

0

Я працюю з asp.net core 2.2 і jquery і маю подати складний об'єкт ("основний клас") з виду до контролера з простими полями даних та деякими масивами.
Як тільки я додав масив у визначення c # 'main class' (див. Нижче) і подав (правильно заповнений) масив через ajax (post), весь об'єкт був недійсним у контролері.
По-перше, я думав, відсутність "традиційного: правдивого" мого дзвінка в аяксі була причиною, але це не так.
У моєму випадку причиною стало визначення в c # 'main class'.
У "головному класі" у мене було:

public List<EreignisTagNeu> oEreignistageNeu { get; set; }

і EreignisTagNeu було визначено як:

public class EreignisTagNeu
{
 public int iHME_Key { get; set; } 
}

Мені довелося змінити визначення в "головному класі" на:

 public List<int> oEreignistageNeu { get; set; }

Зараз це працює.
Отже ... для мене здається, що в ядрі asp.net є проблема (з публікацією), якщо список масиву не визначений повністю в "головному класі".
Примітка. У моєму випадку це працює з або без "традиційного: істинного" для виклику Ajax


-3

Вам потрібно перетворити масив у рядок:

//arrayOfValues = [1, 2, 3];  
$.get('/controller/MyAction', { arrayOfValues: "1, 2, 3" }, function (data) {...

це працює навіть у формі int, long або string

public ActionResult MyAction(int[] arrayOfValues )

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