通过 AJAX 将数组传递给 mvc Action
Posted
技术标签:
【中文标题】通过 AJAX 将数组传递给 mvc Action【英文标题】:Pass array to mvc Action via AJAX 【发布时间】:2011-07-26 06:10:59 【问题描述】:我正在尝试通过 AJAX 将整数数组(或 IEnumerable)传递给 MVC 操作,我需要一些帮助。
$.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 以便控制器可以识别它是什么?
非常感谢您的帮助
戴夫
【问题讨论】:
【参考方案1】:在调用 get 之前将传统属性设置为 true。 即:
jQuery.ajaxSettings.traditional = true
$.get('/controller/MyAction', vals: arrayOfValues , function (data) ...
【讨论】:
谢谢!您能否概述一下传统和非传统 ajax 之间的区别?我想更好地了解我对我的应用程序的其余部分做了什么。 您还可以将传统设置添加到单个呼叫中。那么就不会影响其余的了 这个答案是正确的,但如果您更喜欢为单个呼叫设置“传统”,请检查@RionWilliams 答案。投票赞成。谢谢! @Tom Beech 从 jQuery 1.4 开始,$.param() 方法递归地序列化深层对象以适应现代脚本语言和框架,例如 php 和 Ruby on Rails。您可以通过设置 jQuery.ajaxSettings.traditional = true; 来全局禁用此功能; 没关系。我找到了答案。它与深度序列化没有任何关系。 php 接受数组的原始方式是这样的:“arrayOfValues=1&arrayOfValues=2”。编码事物的新方法是这样的“arrayOfValues[]=1&arrayOfValues[]=2”。第二种方式更好,因为它不那么模棱两可。 .net MVC 对不解析第二种方式非常失望。【参考方案2】:我过去在尝试执行 POST 时遇到过问题(不确定这是否正是您正在做的,但我记得传入数组时,traditional 必须设置为 true .
var arrayOfValues = new Array();
//Populate arrayOfValues
$.ajax(
type: "POST",
url: "<%= Url.Action("MyAction","Controller")%>",
traditional: true,
data: 'arrayOfValues': arrayOfValues
);
【讨论】:
这比像某些人建议的那样在 web.config 文件中盲目地全局设置要好得多。另一个有自己的一套好的场合,但你的应该是默认的解决方案。 这只是将数据作为参数发送给 ActionResult ,它会调用 ActionResult 内部的代码吗?例如,如果有一些代码将 arrayofvalues 插入数据库,该代码会运行吗? 这正是我所需要的。我的数组在我的控制器中一直返回为空,直到我添加它并将它们放入我的控制器中,例如:IEnumerable很晚了,但不同回答这里已经存在的那些:
如果您想使用速记函数 $.get
或 $.post
而不是 $.ajax
,则可以这样传递数组:
速记 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
备注:
$.param
中的布尔参数用于
traditional
属性,哪个
必须是 true
才能正常工作。
【讨论】:
感谢您提供有关传统属性的提示。我无法弄清楚为什么我的 C# 参数为空。我发现类型“int[]”也可以在 C# Action 方法中使用。【参考方案4】:你应该可以做到这一点:
$.ajax(
url: 'controller/myaction',
data: JSON.stringify(
myKey: myArray
),
success: function(data) /* Whatever */
);
那么你的动作方法会是这样的:
public ActionResult(List<int> myKey)
// Do Stuff
对你来说,看起来你只需要对你的价值观进行字符串化。 MVC 中的 JSONValueProvider 将为您将其转换回 IEnumerable。
【讨论】:
感谢您的回答,但我认为我需要将传统设置为 true。已投票,因为我认为这也可以。【参考方案5】:使用“传统”选项的答案是正确的。我只是为希望了解更多信息的人提供更多背景信息。
来自 jQuery 文档:
从 jQuery 1.8 开始,$.param() 方法不再使用 jQuery.ajaxSettings.traditional 作为其默认设置并将 默认为假。
您还可以在此处阅读更多内容: 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
【讨论】:
【参考方案6】:这里有点晚了,但我可以在 $.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
【讨论】:
【参考方案7】:如果所有其他方法都失败...
这里的其他答案都没有解决我的问题。我试图从 JavaScript 对 MVC Web API 控制器进行 GET 方法调用,并在该请求中发送整数数组作为参数。我在这里尝试了所有解决方案,但我的控制器上的参数仍然为 NULL(或者对于您的 VB 用户来说没有)。
我最终在different SO post 中找到了我的解决方案,它实际上非常简单:只需在控制器中的数组参数之前添加[FromUri]
注释(我还必须使用“传统" 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
【讨论】:
【参考方案8】:如果您像我一样从 .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]
属性应用于操作参数,如下所示:
public ActionResult MyAction([FromBody] IEnumerable<int> arrayOfValues )
【讨论】:
谢谢,在所有其他发送数据的方式都失败后,这非常有用!【参考方案9】:如果您使用 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));
【讨论】:
【参考方案10】:我使用 asp.net core 2.2 和 jquery 并且必须将复杂对象(“主类”)从视图提交到具有简单数据字段和一些数组的控制器。 一旦我在 c# 'main class' 定义中添加了数组(见下文)并通过 ajax(post)提交了(正确填充的)数组,整个对象在控制器中为空。 首先,我认为,我的 ajax 调用中缺少“traditional: true”是原因,但事实并非如此。 就我而言,原因是 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 核心似乎有问题(有帖子)。 笔记: 在我的情况下,无论是否使用“传统:true”,都适用于 ajax 调用
【讨论】:
【参考方案11】:如果您需要传递更多参数,其中 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)
);
【讨论】:
【参考方案12】:您需要将数组转换为字符串:
//arrayOfValues = [1, 2, 3];
$.get('/controller/MyAction', arrayOfValues: "1, 2, 3" , function (data) ...
即使是 int、long 或 string 形式也可以使用
public ActionResult MyAction(int[] arrayOfValues )
【讨论】:
这甚至不是向服务器发送数组的正确语法。您只是传递一个对象并假设它是一个数组,而您提供的内容永远不会是这样,它是一个字符串。以上是关于通过 AJAX 将数组传递给 mvc Action的主要内容,如果未能解决你的问题,请参考以下文章
使用 jQuery Ajax 将对象列表传递给 MVC 控制器方法