【问题标题】:.NET Core MVC - AJAX POST Request with prefix binding.NET Core MVC - 带有前缀绑定的 AJAX POST 请求
【发布时间】: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 无论如何都可以解析它。

标签: javascript c# json .net-core asp.net-core-mvc


【解决方案1】:

对于Asp.Net Core,绑定模型有两种方式,ModelBindingJsonInputFormatter。对于使用 json 发送请求,它将使用 JsonInputFormatterBind 不适用于 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,绑定模型有两种方式,ModelBindingJsonInputFormatter。对于使用 json 发送请求,它将使用JsonInputFormatter Bind 不能与 JsonInputFormatter 一起使用。
  • @rena,请将您的最后一条评论添加到您当前答案的顶部,它完美地回答了这个问题,将它放在那里对有同样问题的人会非常有帮助
  • 嗨@jalsh。好的,我做到了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多