Передать массив в действие MVC через AJAX
Я пытаюсь передать массив (или 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
Так что я почти на месте, если я сниму квадратные скобки, я получу правильный ответ. Как мне передать этот массив в мой get, чтобы контроллер мог распознать, что это такое?
Большое спасибо за вашу помощь
Дейв
12 ответов
Установите для традиционного свойства значение true перед выполнением вызова get. то есть:
jQuery.ajaxSettings.traditional = true
$.get('/controller/MyAction', { vals: arrayOfValues }, function (data) {...
У меня были проблемы в прошлом, когда я пытался выполнить POST (не уверен, что это именно то, что вы делаете, но я вспоминаю, что при передаче массива для традиционных должен быть задано значение true.
var arrayOfValues = new Array();
//Populate arrayOfValues
$.ajax({
type: "POST",
url: "<%= Url.Action("MyAction","Controller")%>",
traditional: true,
data: { 'arrayOfValues': arrayOfValues }
});
Довольно поздно, но другой ответ на те, которые уже присутствуют здесь:
Если вместо $.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
чтобы это работало.
Вы должны быть в состоянии сделать это очень хорошо:
$.ajax({
url: 'controller/myaction',
data: JSON.stringify({
myKey: myArray
}),
success: function(data) { /* Whatever */ }
});
Тогда ваш метод действия будет выглядеть так:
public ActionResult(List<int> myKey)
{
// Do Stuff
}
Для вас это выглядит так, как будто вам просто нужно привести в порядок ваши значения. JSONValueProvider в MVC преобразует это обратно в IEnumerable для вас.
Ответ на использование "традиционного" варианта правильный. Я просто предоставляю дополнительную справочную информацию для тех, кто хочет узнать больше.
Из документации по 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
НТН
Немного поздно здесь, но я мог бы использовать решение 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
}
Если вы переходите на 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 )
ЕСЛИ ВСЕ ОСТАЛЬНОЕ ТЕРПИТ НЕУДАЧУ...
Ни один из ответов здесь не решил мою проблему. Я пытался сделать вызов метода GET из JavaScript на контроллер веб-API MVC и отправить массив целых чисел в качестве параметра в этом запросе. Я попробовал все решения здесь, но все равно параметр на моем контроллере показывал NULL (или Nothing для вас, пользователей 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
Если вам нужно передать больше параметров, где par1 это массив, JSON должен содержать каждый параметр, я использовал этот код:
$.ajax({
type: "POST",
url: URL,
data: JSON.stringify({ par1: val1, par2: val2 }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {},
error: function (result) {}
});
Если вы используете 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));
Я работаю с asp.net core 2.2 и jquery, и мне нужно отправить сложный объект ("основной класс") из представления в контроллер с простыми полями данных и некоторыми массивами.
Как только я добавил массив в определение основного класса С # (см. Ниже) и отправил (правильно заполненный) массив через ajax (сообщение), весь объект в контроллере стал нулевым.
Во-первых, я подумал, что причиной моего вызова ajax было отсутствие "традиционного: истинного", но это не так.
В моем случае причиной было определение в "основном классе" С #.
В "основном классе" у меня было:
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.
Вам необходимо преобразовать массив в строку:
//arrayOfValues = [1, 2, 3];
$.get('/controller/MyAction', { arrayOfValues: "1, 2, 3" }, function (data) {...
это работает даже в виде int, long или string
public ActionResult MyAction(int[] arrayOfValues )