【问题标题】:Pass array to mvc Action via AJAX通过 AJAX 将数组传递给 mvc Action
【发布时间】:2011-07-26 06:10:59
【问题描述】:

我正在尝试通过 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 以便控制器可以识别它是什么?

非常感谢您的帮助

戴夫

【问题讨论】:

    标签: c# asp.net-mvc jquery


    【解决方案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 array
    【解决方案3】:

    很晚了,但不同回答这里已经存在的那些:

    如果您想使用速记函数 $.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-answershttp://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 )
                

                【讨论】:

                • 这甚至不是向服务器发送数组的正确语法。您只是传递一个对象并假设它是一个数组,而您提供的内容永远不会是这样,它是一个字符串。
                猜你喜欢
                • 2021-04-14
                • 1970-01-01
                • 1970-01-01
                • 2019-04-13
                • 2011-12-21
                • 1970-01-01
                • 2014-09-27
                • 2020-04-01
                • 1970-01-01
                相关资源
                最近更新 更多