我的 Ajax 与 XMLHttpRequest 调用有何不同,可以让我的服务器理解 Ajax 但不能理解 XMLHttpRequest?

问题描述 投票:0回答:1

我有一个非常简单的服务器调用,如下所示:

[HttpPost]
[AllowAnonymous]
public JsonResult Test(TestRequestModel requestModel)
{
    //do stuff
    return Json(new { result.Success });
}

我的 TestRequestModel 看起来像这样:

public class TestRequestModel
{
    public string Email { get; set; } = string.Empty;
}

我正在尝试向服务器发出 POST 请求。但由于一系列复杂的原因,我需要使用 XMLHttpRequest 而不是 $.ajax。为此,我将向您展示如何在 ajax 中完成此操作,然后如何使用 XMLHttpRequest 完成此操作。

首先这是我如何调用我的服务器:

function MyTestFunction() {
   let parameters = {
       Email: "[email protected]"
   }

    CallServer(function () {
        //Do stuff
    }, function () {
        //Do other stuff
    }, "/Home/Test", parameters)
}

阿贾克斯:

function CallServer(resolve, reject, path, parameters) {
    $.ajax({
        type: "POST",
        url: path,
        data: AddAntiForgeryToken(parameters),
        success: function (response) {
            //do stuff
        },
        error: function (xhr) {
            //do stuff
        },
        complete: function () {
            //do more stuff
        }
    });
}

XMLHttp请求方式:

function CallServer(resolve, reject, path, parameters) {
    let xhr = new XMLHttpRequest();

    xhr.open("POST", path, true);
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    xhr.setRequestHeader('RequestVerificationToken', GetMyToken());
    xhr.onreadystatechange = function (e) {
        if (xhr.readyState === XMLHttpRequest.DONE) {
            if (xhr.status === 200 || xhr.status === 201) {
                //do stuff
            }
            else {
                //do other stuff
            }
        }
    };
    
    xhr.send(JSON.stringify(parameters));
}

如果我以ajax方式运行上面的代码,那么它就可以正常工作。如果我尝试以 XMLHttpRequest 方式执行此操作,则会创建我的请求模型,但不会填充电子邮件字段。现在我发现我可以通过在请求模型上添加 [FromBody] 来解决这个问题,它确实有效,我测试了它,没有问题。

另外,正如我在网上阅读的那样,希望理解正确,但 ajax 在幕后使用 XMLHttpRequest 对吗?

那么为什么我必须在我的控制器上添加 [FromBody] 才能使其工作?有没有办法可以修改我的 XMLHttpRequest 以便不再需要它?我正在寻找的解决方案如何不必在 .net core 服务器的 json post 请求上指定 [FromBody]。

javascript c# ajax asp.net-core xmlhttprequest
1个回答
0
投票

您遇到的结果是ASP.NET 中的模型绑定的结果。

使用 Microsoft 的文档进行模型绑定,

默认情况下,模型绑定从 HTTP 请求中的以下来源获取键值对形式的数据:

  1. 表单字段
  2. 请求正文(对于具有 [ApiController] 属性的控制器。)
  3. 路线数据
  4. 查询字符串参数
  5. 已上传文件

您的问题中明确指出了这一点,但根据您的示例控制器,您的项目是 ASP.NET MVC,因此上面列表中的第 2 项不适用。

public JsonResult Test(TestRequestModel requestModel)
{
    //do stuff
    return Json(new { result.Success });
}

在模型绑定文档中的默认列表之后,声明以下内容:

如果默认源不正确,请使用以下属性之一来指定源:

  • [FromQuery]
    - 从查询字符串中获取值。
  • [FromRoute]
    - 从路线数据中获取值。
  • [FromForm]
    - 从发布的表单字段中获取值。
  • [FromBody]
    - 从请求正文中获取值。
  • [FromHeader]
    - 从 HTTP 标头获取值。

.ajax()
方法正在发布内容类型的请求:

application/x-www-form-urlencoded; charset=UTF-8

您可以在 Chrome 开发工具的“网络”选项卡中的

post
请求标头中看到这一点。

默认情况下,MVC 控制器的模型绑定会解析请求模型。

您的

XMLHttpRequest
示例正在通过
body
方法发送请求的
send
中的模型数据(包含电子邮件字段):

xhr.send(JSON.stringify(parameters));

默认情况下,MVC 控制器的模型绑定不会查看主体中的数据。这就是您看到空电子邮件字段的原因。

当您显式添加

[FromBody]
属性时,模型绑定器会在请求正文中查找数据。

© www.soinside.com 2019 - 2024. All rights reserved.