【问题标题】:Ajax call in Razor View sends null data in controller method?Razor View 中的 Ajax 调用在控制器方法中发送空数据?
【发布时间】:2020-04-20 08:12:19
【问题描述】:

我正在尝试使用来自剃刀视图的 ajax 调用在控制器方法中进行简单的 post 调用。ajax 调用确实调用了控制器方法,但它不会发送我试图发送的对象。我尝试了 Stackoverflow 的多种解决方案但均未成功,包括使用 Json.stringify() 方法和在控制器方法中使用 [HttpPost] 属性。我也将 View 中的对象名称与控制器方法参数的名称相同。这是脚本我在哪里进行 Ajax 调用:

    <script>

        $(document).ready(function () {

            
              $('.send-all').on('click', function() {
                    var data = $('#verticalScroll tr').map(function () {

                          var $row = $(this);
                          return {
                            id: $row.find('.id').text().trim(),
                            companyName: $row.find('.companyname').text().trim(),
                            price: $row.find('.price').text().trim(),
                            quantity: $row.find('.quantity').text().trim(),
                          }

                    }).get();

                      var BID = [];
                      for (var i = 0; i < data.length; i++) {
                          if (data[i].id != null && data[i].id != "") {                       
                              BID.push(data[i]);
                          }
                      }

                        $.ajax(
                        {

                            type: "POST",
                            url: "/User/UpdateBID",
                            data: BID,
                            cache: false,
                            async: true,
                            dataType: "json",
                            success: function (data) {
                                alert(data);
                      
                            },

                            });

              });

  
        });

    </script>

这是来自控制器的方法:

   public ActionResult UpdateBID(object BID)
    {
        string c = JsonConvert.SerializeObject(BID);
        //Context.UpdateBID(b);
        return RedirectToAction("SesionIndividual", TempData["LoginModel"]);
    }

调用了控制器方法,但是对象为null。我也确定了JavaScript对象不为null。我也尝试发送其他对象只是为了测试它,我有同样的结果,控制器中的参数方法为空。

【问题讨论】:

  • data: BID, -> data: { BID: BID }

标签: javascript jquery ajax asp.net-mvc


【解决方案1】:

我从 View 中获得的对象名称与控制器方法参数的名称相同。

对象的名称无关紧要,因为它只是一个变量名。这无论如何都会转换为名称data - 即data:BID = data=BID 所以通过ajax 传递的“变量名”是“数据”。该变量中的 properties 需要匹配。

简短的回答是您的“数据”变量需要一个与操作参数名称匹配的属性,即:

data: { BID: BID },

长(错误)的答案是 MVC 模型绑定器将尝试将属性名称与您的参数名称匹配。在这种情况下,您使用object BID 而不是实际模型让您自己感到困难,因此没有要匹配的属性,因此只能匹配参数本身。

如果您创建了与传递的数据匹配的模型:

public class BIDModel {
    public string companyName { get;set; }
    public string price { get;set; }
    public string quantity { get;set; }
}

并在你的行动中使用它

public ActionResult UpdateBID(BIDModel BID) 

然后传递data: BID 将起作用,因为data 的属性将与BIDModel 的属性相匹配-您仍然可以使用data: { BID: BID },并且MVC 模型绑定器会将data.BID 属性与您的参数相匹配直接命名(然后将映射每个内部的属性)。


覆盖:

控制器方法中的[HttpPost]属性。

[HttpPost] 属性不会使它成为一个 post 方法 - 而不是 restricts http 动词到 POST。你一般不需要这个。如果您有两个具有相同名称但重载不同的方法,一个用于具有等效 POST 的 GET 方法(其中 GET 参数只是一个 id 但 POST 是完整模型),这很有用。它也可以用作额外的安全措施。

在您的情况下,您正在进入操作(仅使用 null 参数),因此该部分显然工作正常。

【讨论】:

  • 我尝试了这两种解决方案。我创建了一个映射到 javascript 对象的对象,并将它作为参数添加到控制器方法 (UpdateOrder[] BID)。我还尝试了数据:{BID: BID作为控制器方法(对象 BID)的签名,我有相同的结果,对象 BID 为空。我在 javascript 代码中添加了验证以确保 BID 对象不为空,并且我在控制台中记录了数据,所以 Javascript对象不为空。
  • 我从中发送数据的视图是部分视图,我不知道这是否会成为将对象发送到控制器时出现的问题。
  • 我尝试用提琴手调试它,在 TextView 中我收到“undefined=&undefined=",在 JSON 视图中我有 JSON=undefined。这是否意味着数据没有发送到控制器方法?
  • 值得一试:将traditional:true, 添加到您的ajax 参数中
  • 我发现了问题,我发布了一个答案。你知道为什么它会这样工作,而不是我在原帖中的尝试吗?
【解决方案2】:

MVC 将尝试从模型属性绑定,因此应该有一个名为 BID 的属性

data: { BID: BID }

【讨论】:

    【解决方案3】:

    对于任何感兴趣的人,我都知道问题出在哪里。我试图将 JavaScript 对象数组发送到理论上接受这些对象数组的方法。好吧,显然这不起作用。我所做的是创建一个C# 中的新对象,其属性类型为 UpdateOrder[],类似于:

    public class UpdateOrder
    {
        public int id { get; set; }
        public string companyName { get; set; }
        public string price { get; set; }
        public int quantity { get; set; }
    }
    
    public class Term
    {
        public UpdateOrder[] Terminal { get; set; }
    }
    

    我在 Javascript 中创建了一个类似的 Term 对象,并在控制器方法中通过 AJAX 发送它,它工作了。所以,我没有直接发送一个数组,而是创建了一个具有保存该数组的属性的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多