.NET Core MVC - 带有前缀绑定的 AJAX POST 请求
Posted
技术标签:
【中文标题】.NET Core MVC - 带有前缀绑定的 AJAX POST 请求【英文标题】:.NET Core MVC - AJAX POST Request with prefix binding 【发布时间】:2020-05-26 14:52:05 【问题描述】:我想通过 AJAX 将请求发布到带有模型前缀的控制器。我需要一个前缀,因为我在一个页面上有两个具有类似模型属性的表单(“asp-for”正在生成类似的 ID 和名称)。我正在使用 .NET Core 3.1。
请求帖子无需前缀即可正常工作。当我使用下面示例中的前缀时,控制器中传递的模型为空:
带前缀的控制器
[HttpPost]
public async Task<IActionResult> Save([Bind(Prefix="ShipmentAddress"), FromBody]ShipToAddressViewModel model)
// model is null
...
return PartialView(ShipmentAdressFormView, model);
带前缀查看
在我的视图中,我也设置了 htmlFieldPrefix:
@model ShipToAddressViewModel
@
ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "ShipmentAddress";
...
$("body").on('submit','#formShipmentAddress', function (e)
// Getting the data (see passed JSON below)
var formData = new FormData(<HTMLFormElement>document.getElementById('formShipmentAddress'));
var object = ;
formData.forEach(function (value, key)
object[key] = value;
);
var data = object;
$.ajax(
type: "POST",
url: url,
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
success: (data) =>
success(data);
);
);
传递带有前缀的 JSON 负载
"ShipmentAddress.ID":"3","ShipmentAddress.Name":"Eddard Stark","ShipmentAddress.Name2":"c/o Ned",..."
型号
public class ShipToAddressViewModel
public int ID get; set;
[Display(Name="Name")]
public string Name get; set;
[Display(Name = "Name 2")]
public string Name2 get; set;
...
更新
如果我从对象的键中删除前缀,那么它就可以工作,尽管更像是一种变通方法(模型绑定首先查看键 ShipmentAddress.ID 的源。如果找不到,它会寻找没有前缀的ID。):
// Getting the data (see passed JSON below)
var formData = new FormData(<HTMLFormElement>document.getElementById('formShipmentAddress'));
var object = ;
formData.forEach(function (value, key)
object[key.replace("ShipmentAddress.","")] = value;
);
var data = object;
【问题讨论】:
艾德·史塔克 :'( 我通过遍历表单数据来获取数据,当我将前缀替换为“nothing”时,即使在您的示例中也可以使用。数据类型没有影响,.NET 无论如何都可以解析它。 【参考方案1】:对于Asp.Net Core,绑定模型有两种方式,ModelBinding
和JsonInputFormatter
。对于使用 json 发送请求,它将使用 JsonInputFormatter
。 Bind
不适用于 JsonInputFormatter
。
这是一个如下所示的工作演示:
1.查看:
@
ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = "ShipmentAddress";
@model ShipToAddressViewModel
<form id="formShipmentAddress">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="ID" class="control-label"></label>
<input class="form-control" asp-for="ID">
<span asp-validation-for="ID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input class="form-control" asp-for="Name">
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Name2" class="control-label"></label>
<input class="form-control" asp-for="Name2">
<span asp-validation-for="Name2" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
@section Scripts
<script>
$("body").on('submit', '#formShipmentAddress', function (e)
e.preventDefault();
var id = parseInt($("#ShipmentAddress_ID").val());
var name = $("#ShipmentAddress_Name").val();
var name2 = $("#ShipmentAddress_Name2").val();
var data =
ID: id,
Name: name,
Name2: name2
;
$.ajax(
type: "POST",
url: "/Home/Save",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
success: (data) =>
success(data);
);
);
</script>
2.控制器:
public async Task<IActionResult> Save([FromBody]ShipToAddressViewModel model)
//do your stuff...
3.结果:
【讨论】:
嗨,感谢您的详细说明和说明性回答,但存在一些混淆:在您的示例中,您传递了以下 json:"ID":3,"Name":"Eddard Stark"..,
而不是 "ShipmentAddress.ID":3,"Name":"ShipmentAddress.Eddard Stark"..,
。这就是它起作用的原因。 .NET Core 有一个后备方案:模型绑定首先查看关键 AddressShipoment.ID 的源。如果没有找到,它会查找不带前缀的 ID。所以我在发回之前手动删除了 javascript 中的前缀,然后它就可以工作了。虽然它实际上更多的是一种解决方法。你知道我的意思吗?
是的,我知道你的意思。我无法通过使用你的代码获得像你这样的带后缀的 json。你能分享你如何获取数据吗?你是否尝试将 ShipToAddressViewModel model
更改为 @ 987654333@在你的行动?
对于Asp.Net Core,绑定模型有两种方式,ModelBinding
和JsonInputFormatter
。对于使用 json 发送请求,它将使用JsonInputFormatter
。 Bind
不能与 JsonInputFormatter
一起使用。
@rena,请将您的最后一条评论添加到您当前答案的顶部,它完美地回答了这个问题,将它放在那里对有同样问题的人会非常有帮助
嗨@jalsh。好的,我做到了。以上是关于.NET Core MVC - 带有前缀绑定的 AJAX POST 请求的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core MVC 混合路由/FromBody 模型绑定和验证
带有实体框架的 ASP.NET MVC Core 项目中的种子角色
在 ASP.NET MVC Core 2 中使用 MetadataPropertyHandling 模型绑定 JSON 数据
NET Core 3.1 MVC 授权/身份验证,带有在单独的 Net Core 3.1 Web Api 中从外部获取的令牌 (JWT)