通过AJAX将数组传递给mvc Action


123

我正在尝试通过AJAX将整数数组(或IEnumerable)传递给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中,以便控制器可以识别它是什么?

非常感谢您的帮助

戴夫

Answers:


149

在进行get调用之前,将传统属性设置为true。即:

jQuery.ajaxSettings.traditional = true

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

3
谢谢!您能概述一下传统和非传统Ajax的区别吗?我想更好地了解我对其余应用程序正在做什么。
Tom Beech 2013年

5
您还可以将传统设置添加到单个通话中。然后,它将不会影响其余部分
Gluip

1
这个答案是正确的,但是如果您希望为单个呼叫设置“传统”,请检查@RionWilliams答案。都投票。谢谢!
kzfabi 2013年

@Tom Beech从jQuery 1.4开始,$ .param()方法以递归方式序列化深层对象,以适应现代脚本语言和框架,例如PHP和Ruby on Rails。您可以通过设置jQuery.ajaxSettings.traditional = true全局禁用此功能。
Alexey Shevelyov 2015年

这些答案都不对我
有用

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,它将在ActionResult内部调用代码吗?例如,如果有一些代码可以将arrayofvalues插入数据库,那么该代码可以运行吗?
萨拉巴

这完全解决了我所需要的。我的数组在我的控制器中一直保持为空,直到我将其添加到控制器中,如:IEnumerable <string> array
SeanMC '17

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
}

简写POST

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
}


笔记:


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
}

对于您来说,看起来您只需要对值进行字符串化。MVC中的JSONValueProvider将为您将其转换回IEnumerable。


感谢您的回答,但我认为我需要将传统设置为true。我认为这也行得通。
戴夫

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-answershttp://haacked.com/archive /2008/10/23/model-binding-to-a-list.aspx

高温超导


2

如果所有其他失败...

这里没有其他答案可以解决我的问题。我试图从JavaScript到MVC Web API控制器进行GET方法调用,并在该请求中发送整数数组作为参数。我在这里尝试了所有解决方案,但是控制器上的参数仍然为NULL(或者对于您的VB用户而言什么也没有)。

最终,我在一篇SO文章中找到了我的解决方案,它实际上非常简单:只需[FromUri]在控制器中的array参数之前添加注释(我还必须使用“传统” AJAX设置进行调用以避免括号注释)。有关我在应用程序中使用的实际代码,请参见下文。


控制器签名:

控制器签名 注意:C#中的注释为 [FromUri]


JavaScript:

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

实际网址字符串:

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

2

这里有点晚,但是我可以在$ .ajax()中进一步使用SNag的解决方案。如果可以帮助任何人,请参见以下代码:

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

如果像我以前那样从.Net Framework MVC迁移到ASP.NET Core MVC,则情况会稍有变化。ajax调用必须在使用stringify的原始对象上进行,而不是传递其数据{ vals: arrayOfValues }JSON.stringify(arrayOfValues)如下所示:

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

在ASP.NET Core中进行的另一项更改是防止跨站点请求伪造,因此对于从ajax方法调用MVC操作的行为,[FromBody]必须将属性应用到action参数,如下所示:

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

谢谢您,在发送数据的所有其他方式失败之后,这非常有用!
NibblyPig

0

如果您使用的是ASP.NET Core MVC,并且需要处理方括号(而不是使用jQuery的“ traditional”选项),那么我发现的唯一选择是IEnumerable在contoller方法中手动构建。

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(发布)提交了(正确填充的)数组,则整个对象在控制器中为null。
首先,我想,我的ajax调用缺少“ traditional:true”是原因,但事实并非如此。
在我的情况下,原因是c#“主类”中的定义。
在“主班”中,我有:

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调用是否使用“ traditional:true”,这种方法都有效


-3

您需要将Array转换为string:

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

即使以int,long或string的形式工作

public ActionResult MyAction(int[] arrayOfValues )

这甚至不是将数组发送到服务器的正确语法。您只是传递一个对象并假定它是一个数组,而您提供的对象(STRING)将永远不会这样。
Twister1002
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.