【问题标题】:List Model Stops Binding Correctly When Query Parameter is Added添加查询参数时列表模型停止正确绑定
【发布时间】:2019-03-10 04:39:30
【问题描述】:

我正在使用模式编辑器对话框来允许用户修改客户地址列表。当客户想要添加或删除地址时,我使用 JQuery 使用 AJAX 请求来处理它。尽管代码基本上是剪切和粘贴的,但我的 addAddr() 函数按预期工作(控制器接收地址列表),而我的 delAddr() 函数不工作(控制器接收列表一个地址,尽管模型包含多个地址。)任何人都可以看到以下代码中的错误吗?

控制器动作:

[HttpPost]
public async Task<IActionResult> AddCustomerAddress(List<CustomerAddress> Model)
{
    var newAddr = new CustomerAddress
    {
        CustomerID = Model[0].CustomerID,
        IsActive = true,
        IsPrimary = true
    };

    await _dbService.InsertCustomerAddressAsync(newAddr);

    return RedirectToAction(nameof(EditCustomerAddresses), new { Model[0].CustomerID });
}

[HttpPost]
public async Task<IActionResult> DeleteCustomerAddress(List<CustomerAddress> Model, [FromQuery]int Index)
{
    await _dbService.DeleteCustomerAddressAsync(Model[Index]);

    return RedirectToAction(nameof(EditCustomerAddresses), new { Model[0].CustomerID });
}

JQuery:

function addAddr() {
    var model = $('form#addr-editor').serialize();
    $.post('/Customer/AddCustomerAddress',
        model,
        function (data, status, jqXHR) {
            $('#modal-container').html(data);
            $.notify('New Address Activated - Save Changes After Editing', { position: "top-center" });
        }
    ).fail(function () {
        $.notify('Error adding Address.', { position: "top center" });
    });
}

function delAddr(index) {
    var model = $('form#addr-editor').serialize();
    $.post('/Customer/DeleteCustomerAddress?Index=' + index,
        model,
        function (data, status, jqXHR) {
            $('#modal-container').html(data);
            $.notify('Address Deleted Successfully', { position: "top center" });
        }
    ).fail(function () {
        $.notify('Error Deleting Address.', { position: "top center" });
    });
}

我的测试记录有六个地址。 Add 操作接收 List&lt;CustomerAddress&gt;Count = 6。 Delete 操作正确接收索引,但它接收模型为List&lt;CustomerAddress&gt;Count = 1。我知道的唯一区别是在查询字符串中包含了一个附加参数。我想要的行为是让两个控制器操作都接收 6 个地址的列表。任何帮助表示赞赏!

【问题讨论】:

  • 当您尝试删除时,您是否在网络选项卡中确认请求正在发送所有 6 个?
  • @nurdyguy - 我刚刚使用 PostMan 检查...两个 AJAX 帖子都显示所有 6 个地址都在正文 x-www-form-urlencoded 中发送。这表明 JQuery 正在按预期工作,并且控制器操作存在问题(或我不知道的模型绑定的一些细微差别)
  • 尝试使用路由属性,例如[HttpPost, Route("/Customer/DeleteCustomerAddress/{int:index}")] 并相应地调整控制器方法和ajax url。
  • @nurdyguy - 好主意,但我尝试并得到了相同的行为。我想我刚刚深入了解了 - 必须保留参数名称“索引” - 将参数名称更改为其他名称可以解决问题。在模型之前添加 [FromForm] 也可以。不过,感谢您的帮助!
  • 有趣的发现。很高兴事情对你有用!

标签: jquery asp.net-core-mvc model-binding


【解决方案1】:

我终于找到了问题所在 - 看来这是一个功能,而不是错误...将操作签名更改为这样的内容可以解决问题:

[HttpPost]
public async Task<IActionResult> DeleteCustomerAddress(List<CustomerAddress> Model, [FromQuery]int NotTheIndex)
{
    await _dbService.DeleteCustomerAddressAsync(Model[NotTheIndex]);

    return RedirectToAction(nameof(EditCustomerAddresses), new { Model[0].CustomerID });
}

这表明Index 是保留的参数名称。当我在列表中获得一个条目并且索引为 2 时,我实际上只获得了 Model[2]

Model之前添加FromForm也可以解决问题:

public async Task<IActionResult> DeleteCustomerAddress([FromForm]List<CustomerAddress> Model, [FromQuery]int Index)

【讨论】:

    猜你喜欢
    • 2011-10-26
    • 2013-12-26
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 2013-08-13
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多