【问题标题】:JQuery JSON POST request to ASP.NET MVC controller does not hit end-point, but manual use of route works correctly对 ASP.NET MVC 控制器的 JQuery JSON POST 请求未达到终点,但手动使用路由可以正常工作
【发布时间】:2019-03-07 09:26:55
【问题描述】:

我有一个 ASP.NET 应用程序,它由一个前端组成,该前端包含一个表单,我希望将其数据传递到我的 C# 后端。为此,我使用 JQuery 发布请求来序列化表单数据并使用 JSON 将其发送到控制器。下面是我调用控制器路由的 Javascript 代码;

$(".data-submit").on("click",
        function(event) {
            var formArray = $("#amend-form").serializeArray();
            var json = JSON.stringify(formArray);

            $.post(windowLocationOrigin() +
                "/Instruction/AmendData", 
                json, 
                function (data) {
                    alert("api endpoint called");
                });

        });

这里是被调用的控制器端点

        [Route("[controller]/AmendData")]
        public IActionResult AmendPortingData([FromBody] string json)
        {
            return Ok(json);
        }

当我通过前端提交此表单时,会调用 onClick JS 事件并发送发布请求,但控制器端点永远不会被命中。我在return Ok(json) 行有一个断点,在提交表单后永远不会触发。

如果我签入开发人员工具,我会收到 500 错误消息:POST https://localhost:44358/Instruction/AmendData 500

但是,如果我随后向此 url https://localhost:44358/Instruction/AmendData?json=123 提交请求,则端点被正确命中,我可以在调试器中看到值 123

但是我希望能够通过 post 请求正文而不是通过 url 发送我的数据,因为要提交的表单很大并且包含太多需要通过 GET 发送的数据。

我尝试将 [HttpPost] 属性添加到控制器端点,但这会产生完全相同的行为,只是它不允许 GET url 工作。

【问题讨论】:

  • 尝试更改为:var json = { json: JSON.stringify(formArray) };
  • @freedomn-m 这解决了我的问题,谢谢!你能解释一下为什么不这样做会导致问题吗?我想确切地知道为什么这会导致问题。

标签: javascript jquery asp.net asp.net-mvc


【解决方案1】:

您的控制器操作:

public IActionResult AmendPortingData(string json)

需要一个名为 json 的参数。

当你调用它时:

 $.ajax({ url: url, data: "string" });

传递的数据没有参数名称,因此默认模型绑定器无法确定将数据的哪一部分应用于该参数。

这适用于:

http://url?json=string

当您指定参数名称?json=,如果您调用了您的操作

http://url/string

那么它将再次无法将“字符串”识别为参数“json”并且不起作用(尽管可能会给您一个更有用的“找不到参数的数据”错误)(当然假设没有额外的路由)。

通过给字符串参数命名,默认模型绑定器将能够将字符串与参数名称匹配:

$.ajax({ url: url, data: { json: "string" }});

另一种方法是添加一个模型绑定器,该模型绑定器将采用任何 POST 字符串并将其传递给单个参数 - 但上述方法通常更简洁且更易于维护。


添加 [HttpPost] 会将操作限制为仅该动词(因此,顺便说一句,添加 [HttpPost][HttpGet] 使其无法使用,因为它必须是 POST 并且必须是 GET)。


如果您是从视图模型构建表单,那么您可以直接在操作中使用该视图模型:

public ActionResult MyAction(MyViewModel viewmodel)

直接通过:

$.ajax({ url: url, data: $("form").serialize() });

默认的模型绑定器会将输入的名称映射到视图模型上的属性。

【讨论】:

  • 非常棒的答案。感谢您花时间写下来。我认为我的主要问题是认为活页夹能够将 JS 变量名称映射到 C# 参数名称。因此,为什么我认为您不需要在 JS 中为 POST 正文数据指定名称。
  • 令人困惑的是,这在某些情况下确实有效,特别是如果你这样做 $.ajax({url:url, data: { json }}) 也应该在 Chrome 中工作......它是特定于浏览器的,所以总是值得添加 data: { json: json } 否则你将很难找到对你有用但对其他人有用的错误,直到几个小时后你发现他们正在使用不同的浏览器......(第一手体验!)
猜你喜欢
  • 2012-06-20
  • 2019-09-07
  • 1970-01-01
  • 2019-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-17
  • 1970-01-01
相关资源
最近更新 更多