我有一个非常简单的服务器调用,如下所示:
[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]。
您遇到的结果是ASP.NET 中的模型绑定的结果。
使用 Microsoft 的源文档进行模型绑定,
默认情况下,模型绑定从 HTTP 请求中的以下来源获取键值对形式的数据:
您的问题中明确指出了这一点,但根据您的示例控制器,您的项目是 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]
属性时,模型绑定器会在请求正文中查找数据。