【问题标题】:Null values when invoking MVC controller from Javascript从 Javascript 调用 MVC 控制器时的空值
【发布时间】:2013-04-24 22:06:22
【问题描述】:

在我的 MVC 视图模型中,我有一个表格,里面有一个表格。

从我的 javascript 中,我按如下方式调用我的控制器:

$.ajax(
    {
        type: "POST",
        url: "@Url.Action("ReorderClues", "Clues", Model)",
        data: JSON.stringify(positions),
        contentType:'application/json'
    });

而我的控制器签名如下:

public ActionResult ReorderClues(TreasureHuntDetails treasureHuntDetails, int[] ids)

我发现当 javascript 以这种方式调用控制器时,数据模型(TreasureHuntDetails 对象)仅填充了 TreasureHuntId,其他所有内容均为空。第二个参数,ids 数组填充成功 - 这是我在 ajax 函数中使用 JSON.stringify() 的参数。

我无法弄清楚为什么除了 TreasureHuntId 之外的其他所有内容都是空的。在表单中,对象的每个属性都有一个 HiddenFor 行,如下所示:

        @Html.HiddenFor(m => m.CompletionMessage)
        @Html.HiddenFor(m => m.Description)
        @Html.HiddenFor(m => m.Clues)
        @Html.HiddenFor(m => m.Leaderboard)
        @Html.HiddenFor(m => m.TreasureHuntId)
        etc.

我看不出 TreasureHuntId 变量有什么特别之处,因为它是唯一一个其值是到达控制器的对象上唯一填充的变量。有任何想法吗?我可能做错了什么?

当我仅使用数据模型 (TreasureHuntDetails) 以正常方式调用控制器时,所有内容都会正确填充,因此它仅在我还添加到 Ids 数组的 javascript 中(javascript 中的 'positions' 变量代码 sn-p 是一个整数数组)。

【问题讨论】:

标签: c# jquery asp.net-mvc razor asp.net-mvc-4


【解决方案1】:

你实际上并没有把你的模型传回去。 ID 存在的原因可能是因为它已经在 HttpGet 请求的 url 中。

首先,将您的网址更改为没有模型:

url: "@Url.Action("ReorderClues", "Clues")",

然后更改您的 ajax 方法以将模型也传回:

data: { treasureHuntDetails: $("form").serialize(), ids: JSON.stringify(positions) }

【讨论】:

  • 这似乎是要走的路。看起来我的代码可能有其他问题,尽管当 javascript 发送 POST 请求时它会引发错误(“加载资源失败:服务器响应状态为 500”)。
  • 我认为这行不通。 TreasureHuntDetails 将是一个序列化字符串,适合用作 GET 或 POST 内容的一部分。使用 fiddler 进行检查,您可能会看到如下内容: { TreasureHuntDetails: "CompletionMessage=msg&Description=desc&Clues=clue", ids: [1,2,3] } 这将无法解析,这就是您看到 500 的原因。
  • @CiaranG Ahhh,在您的 Url.Action 上,删除您的 Model 参数。它应该工作。将其更改为 `Url.Action("ReorderClues", "Clues")
  • @CodeMonkeyKing 使用序列化几乎是使用 jQuery ajax 将模型传递给操作的标准方法。
  • 我删除了 Model 参数并按照您对两个参数的建议进行了设置,但由于某种原因,我仍然遇到错误,并且在检查数据时,它似乎正在发送 TreasureHuntDetails 对象,但我在它的末尾看不到 ID 数组。不知道为什么没有发送,我会多玩一点,看看我能不能把它弄好。
【解决方案2】:

这对我有用,我在下面留下了原始帖子:

$.ajax({
  type: 'POST',
  contentType: 'application/json',
  url: '@Url.Action("Contact", "Home")',
  data: JSON.stringify({
    completionMessage: $("#CompletionMessage").val(),
    description: $("#Description").val(),
    clues: $("#Clues").val(),
    leaderboard: $("#Leaderboard").val(),
    treasureHuntId: $("#TreasureHuntId").val(),
    ids: positions
  })
});

您需要从 Url.Action() 中删除“模型”,当然还需要将示例中的值更改为您正在使用的操作和控制器名称。为了清楚起见,我包含了“位置”变量,您的值将来自此闭包之外。

--- 原始答案---

您需要在为 AJAX 调用传递的数据中包含所有隐藏值。您所写的内容与您所写的一样有效,但不会包含您页面中的其他表单值。如果我不得不猜测,如果 TreasureHuntId 是一个整数,那么它将填充数组中来自位置变量的第一个值。您可能想要做的是将 Fiddler 放入并查看发布的内容。

在浏览器中查看您的 URL 的来源。与您的预期相比,这可能会让您感到惊讶。您是否依赖于默认路由?检查您是否在控制器中为此操作制定了任何特殊路线。

我认为最好的方法是手动创建对象:AJAX 上的 jQuery 文档指定数据设置是序列化查询字符串或对象。如果您使用对象,那么您可能希望将 dataType 更改为“json”,您不需要 contentType。

data: {
  CompletionMessage: $('#CompletionMessage').val(),
  Description:  $('#Description').val(),
  // other fields here...
  ids: JSON.stringify(positions)
}

请注意,如果无法识别方法,您可能需要/想要更改控制器上的签名以接受单个参数而不是 TreasureHuntDetails 类。

另外,查看 jQuery 中的 serialize() 函数 - $.post() 上的文档将帮助您找到解决方案。请记住,如果您走这条路线,那么您需要远程处理 contentType,因为它默认为正确的表单 MIME 类型。

【讨论】:

  • @CiaranG 乐于提供帮助。这对我来说也是一次学习经历。
【解决方案3】:

我在今年早些时候遇到过这种情况,因为我的 jQuery 变量名称与我的 actionresult 参数名称不同。不要问为什么,但这就是我的问题。

【讨论】:

    猜你喜欢
    • 2011-02-12
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多