Asp.net core mvc ajax post 到具有多个参数的控制器 return 错误请求
Asp.net core mvc ajax post to controller with multiple parameters return bad request
我的控制器操作方法如下,
public class UserController : BaseController<UserController>
{
[HttpGet]
public IActionResult Assignment(Guid id)
{
return View();
}
[HttpPost]
public IActionResult Assignment(Guid id, [FromBody] List<UserViewModel> assignees)
{
return View();
}
}
Assignment.cshtml
页面中的 ajax 方法
$("#btn-save").click(function () {
var url = "/User/Assignment/@Model.SelectedUser.Id";
$.ajax({
type: "POST",
url: url,
contentType: "application/json",
data: JSON.stringify({ assignees: assignmentPage.SelectedUsers })
});
});
所以这构建了一个 url 喜欢;
http://localhost:8800/User/Assignment/f474fd0c-69cf-47eb-7281-08d6536da99f
这是我Startup.cs
中唯一的路由配置。
app.UseMvc(routes =>
{
routes.MapRoute(name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
我从未点击过作业 post 操作,服务器 returns 400,我已经搜索并还没有找到,我应该如何为这样的操作配置我的路线?
您发送到服务器的数据无效。它需要一个 JSON 数组,但您向它发送一个 JSON 对象,其中包含一个 属性 本身就是一个数组。由于 JSON.NET 无法将对象解析为数组,您会收到 400 状态代码。
为了进一步说明,这是您要发送的内容:
{
"assignees": [
{ ... assignee1 ... },
{ ... assignee2 ... },
...
]
}
但是,这是预期的数组,因此它应该如下所示:
[
{ ... assignee1 ... },
{ ... assignee2 ... },
...
]
您需要做的就是将当前的 JSON.stringify
行更改为:
JSON.stringify(assignmentPage.SelectedUsers)
另一种选择是在您的 ASP.NET 核心项目中创建一个模型 class 并使用它来代替字符串列表。这是它的样子:
public class AssignmentModel
{
public List<UserViewModel> Assignees { get; set; }
}
Assignment
操作如下所示:
public IActionResult Assignment(Guid id, [FromBody] AssignmentModel thisNameDoesNotMatter)
我的问题是我正在使用 AutoValidateAntiforgeryTokenAttribute 配置
services.AddMvc(options =>{
// Automatically add antiforgery token valdaiton to all post actions.
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
}
所以,ajax post 本身没有任何请求验证令牌,缺少此令牌服务器 returns 错误请求。
为了克服这个问题,我遵循了这个 link,所以我的最终工作代码是,
Assignment.cshtml
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions
{
public string GetAntiXsrfRequestToken() => Xsrf.GetAndStoreTokens(Context).RequestToken;
}
<input type="hidden" id="RequestVerificationToken" name="RequestVerificationToken"
value="@GetAntiXsrfRequestToken()">
<script type="text/javascript">
$("#btn-saveinspectors").click(function () {
var url = "/Audit/Assignment/@Model.SelectedUser.Id";
var assignees = JSON.stringify(assignmentPage.SelectedUsers);
$.ajax({
type: "POST",
url: url,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('#RequestVerificationToken').val());
},
contentType: "application/json",
data: assignees,
});
});
</script>
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}
注意:这是我的情况,我的页面中没有任何自动生成请求验证令牌的表单。如果您的页面中有一个表单,您可以在其中提出 ajax 请求,那么您可以关注 this post
我的控制器操作方法如下,
public class UserController : BaseController<UserController>
{
[HttpGet]
public IActionResult Assignment(Guid id)
{
return View();
}
[HttpPost]
public IActionResult Assignment(Guid id, [FromBody] List<UserViewModel> assignees)
{
return View();
}
}
Assignment.cshtml
页面中的 ajax 方法
$("#btn-save").click(function () {
var url = "/User/Assignment/@Model.SelectedUser.Id";
$.ajax({
type: "POST",
url: url,
contentType: "application/json",
data: JSON.stringify({ assignees: assignmentPage.SelectedUsers })
});
});
所以这构建了一个 url 喜欢;
http://localhost:8800/User/Assignment/f474fd0c-69cf-47eb-7281-08d6536da99f
这是我Startup.cs
中唯一的路由配置。
app.UseMvc(routes =>
{
routes.MapRoute(name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
我从未点击过作业 post 操作,服务器 returns 400,我已经搜索并还没有找到,我应该如何为这样的操作配置我的路线?
您发送到服务器的数据无效。它需要一个 JSON 数组,但您向它发送一个 JSON 对象,其中包含一个 属性 本身就是一个数组。由于 JSON.NET 无法将对象解析为数组,您会收到 400 状态代码。
为了进一步说明,这是您要发送的内容:
{
"assignees": [
{ ... assignee1 ... },
{ ... assignee2 ... },
...
]
}
但是,这是预期的数组,因此它应该如下所示:
[
{ ... assignee1 ... },
{ ... assignee2 ... },
...
]
您需要做的就是将当前的 JSON.stringify
行更改为:
JSON.stringify(assignmentPage.SelectedUsers)
另一种选择是在您的 ASP.NET 核心项目中创建一个模型 class 并使用它来代替字符串列表。这是它的样子:
public class AssignmentModel
{
public List<UserViewModel> Assignees { get; set; }
}
Assignment
操作如下所示:
public IActionResult Assignment(Guid id, [FromBody] AssignmentModel thisNameDoesNotMatter)
我的问题是我正在使用 AutoValidateAntiforgeryTokenAttribute 配置
services.AddMvc(options =>{
// Automatically add antiforgery token valdaiton to all post actions.
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
}
所以,ajax post 本身没有任何请求验证令牌,缺少此令牌服务器 returns 错误请求。
为了克服这个问题,我遵循了这个 link,所以我的最终工作代码是,
Assignment.cshtml
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions
{
public string GetAntiXsrfRequestToken() => Xsrf.GetAndStoreTokens(Context).RequestToken;
}
<input type="hidden" id="RequestVerificationToken" name="RequestVerificationToken"
value="@GetAntiXsrfRequestToken()">
<script type="text/javascript">
$("#btn-saveinspectors").click(function () {
var url = "/Audit/Assignment/@Model.SelectedUser.Id";
var assignees = JSON.stringify(assignmentPage.SelectedUsers);
$.ajax({
type: "POST",
url: url,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('#RequestVerificationToken').val());
},
contentType: "application/json",
data: assignees,
});
});
</script>
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}
注意:这是我的情况,我的页面中没有任何自动生成请求验证令牌的表单。如果您的页面中有一个表单,您可以在其中提出 ajax 请求,那么您可以关注 this post