You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC 动态新增分部视图地址表单提交时模型绑定失败如何解决

问题原因和解决方案

核心问题梳理

  • 模型定义错误:CustomerInfo中的CustomerAddresses是单个对象类型,无法绑定多个地址数据,且存在地址类名与属性类型不匹配的问题
  • 表单字段命名不符合ASP.NET MVC集合绑定规则:动态生成的地址输入框name属性没有集合索引前缀,MVC无法将多个地址字段映射到集合属性
  • 提交JS逻辑错误:直接对jQuery表单对象执行JSON.parse会抛出异常,提交逻辑重复混乱
  • DOM ID重复:删除按钮使用固定ID,多次追加地址后ID重复,仅第一个删除按钮生效
  • 分部视图模型类型不匹配:分部视图声明的模型与实际使用的地址模型类不一致

修复步骤

1. 修正模型定义

将地址属性改为集合类型,统一类名:

// 地址模型统一类名
public class CustomerAddress
{
    public string Address { get; set; }
}

public class CustomerInfo
{
    public CustomerModel CUSTOMER { get; set; }
    // 改为列表类型支持绑定多个地址
    public List<CustomerAddress> CustomerAddresses { get; set; }
}

2. 调整分部视图与加载逻辑

给动态生成的表单字段加上符合绑定规则的索引前缀:
首先修改分部视图Action,接收索引参数设置前缀:

public virtual PartialViewResult RegisterAddress(int index)
{
    // 设置HTML字段前缀,生成符合绑定规则的name属性
    ViewData.TemplateInfo.HtmlFieldPrefix = $"CustomerAddresses[{index}]";
    return PartialView(MVC.Applications.Views.CustomerAddress);
}

修改追加地址的JS,传递当前地址数量作为索引:

$(document).on('click', "#addAddressItem", function (e) {
    e.preventDefault();
    // 统计当前已有地址数量作为新项的索引
    var currentCount = $("#RegisterAddressId .address-item").length;
    $.ajax({
         url: this.href + "?index=" + currentCount,
         cache: false,
         success: function (html) {
             $("#RegisterAddressId").append(html);
         }
    });  
});

修改分部视图,添加地址项标识、将删除按钮ID改为类:

@model CustomerAddress
<!-- 添加address-item类用于计数和查找 -->
<table class="address-item">
   <td class="personlistborder">
       <div class="editor-label">
          Address
       </div>
          <div class="editor-field">
              @Html.EditorFor(model => model.Address, new { @class = "CustomerAddressField" })
              @Html.ValidationMessageFor(model => model.Address) 
          </div>        
  </td>
 <td colspan="7"></td>
 <td>
    <!-- 将固定ID改为class,避免重复 -->
    <span class="deleteRegisterCustomerAddress outline ui-button ui-widget ui-state-default ui-corner-all" role="button" aria-disabled="false">
        <span class="ui-icon-minusthick ui-icon"></span>
    </span>
  </td>
</table>

3. 实现删除功能并修复索引

删除地址后重新整理所有字段的索引,避免索引断层导致绑定失败:

$(document).on('click', ".deleteRegisterCustomerAddress", function () {
    // 删除当前地址项
    $(this).closest(".address-item").remove();
    // 重排剩余地址项的索引
    $("#RegisterAddressId .address-item").each(function (index) {
        // 修改输入框name属性
        $(this).find("input[name*='Address']").attr("name", $"CustomerAddresses[{index}].Address");
        // 同步修改验证提示的关联属性,保证表单验证正常生效
        $(this).find("[data-valmsg-for*='Address']").attr("data-valmsg-for", $"CustomerAddresses[{index}].Address");
    });
});

4. 修正提交JS逻辑

删除错误的JSON解析代码,直接提交验证通过的表单:

buttons: ({
        "Save": {
            text: "save",
            id: "btnSubmitExamApp",
            click: function () {
                var form = $('form', this);
                var validator = $(form).validate();
                if (validator.form()) {
                    form.submit();
                }
            }
         }
})

5. 后端接收逻辑

提交的Action参数直接使用CustomerInfo类型即可自动绑定地址集合:

[HttpPost]
public ActionResult SaveCustomer(CustomerInfo model)
{
    // model.CustomerAddresses 即可获取所有提交的地址数据
    // 后续业务逻辑
}

内容的提问来源于stack exchange,提问作者lekiniu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 19:57:02