ASP.NET MVC中Ajax提交表单时序列化嵌套子组数据的实现方法
你遇到的问题核心是动态添加的配件输入框name属性不符合ASP.NET MVC的集合模型绑定规则。
当你用独立页面加载表单时,@Html.EditorFor(model => Model.Parts[p])会自动生成Parts[0].PartNumber、Parts[1].Description格式的name属性,表单序列化后MVC可以自动识别绑定到Note.Parts集合。但你通过JS动态添加的配件输入框,直接使用了编辑器模板的原始name(仅为PartNumber、Description,无集合前缀和索引),序列化后的数据无法被MVC识别为集合属性,因此后台接收不到配件数据。
以下是两种可用的解决方案:
方案1:修改动态添加配件的逻辑,生成符合规范的name属性
1. 维护配件索引变量
在JS全局作用域或者模态框加载的回调函数中定义索引计数器:
let partIndex = 0;
2. 重写添加配件的点击事件
动态生成带正确name属性的配件输入框:
// 绑定添加配件按钮事件 $(document).on("click", "#btnAddPart", function () { const partTpl = ` <div class="part-info"> <input type="text" class="part-number" name="Parts[${partIndex}].PartNumber"> <input type="text" class="description" name="Parts[${partIndex}].Description"> <input type="button" value="删除" class="btn btn-default delete-button"> <br> </div>`; $(".parts-container.create").append(partTpl); partIndex++; });
3. 处理删除配件后的索引重置
如果用户删除了中间的配件,需要重置所有配件的索引保证连续:
// 绑定删除配件按钮事件 $(document).on("click", ".delete-button", function () { $(this).closest(".part-info").remove(); // 重排所有配件的索引 $(".parts-container.create .part-info").each(function (idx) { $(this).find(".part-number").attr("name", `Parts[${idx}].PartNumber`); $(this).find(".description").attr("name", `Parts[${idx}].Description`); }); partIndex = $(".parts-container.create .part-info").length; });
修改完成后原有提交逻辑不需要改动,serialize()方法会自动获取符合格式的表单数据。
方案2:手动组装FormData提交(无需修改现有新增/删除逻辑)
如果不想调整现有动态添加配件的代码,可直接修改提交逻辑,手动遍历配件数据组装到FormData中:
function bindForm(dialog) { $("form", dialog).submit(function () { // 用FormData承载所有提交数据 const formData = new FormData(this); // 遍历所有配件,手动添加到FormData $(".parts-container.create .part-info").each(function (idx) { const partNumber = $(this).find(".part-number").val(); const description = $(this).find(".description").val(); formData.append(`Parts[${idx}].PartNumber`, partNumber); formData.append(`Parts[${idx}].Description`, description); }); $.ajax({ url: this.action, type: this.method, data: formData, // 必须添加这两个配置,禁止jQuery自动处理FormData processData: false, contentType: false, complete: function (xhr, status) { if (status == "success") { $(".modal").modal("hide"); location.reload(); } else { alert("提交失败: " + xhr.status + " " + xhr.statusText); } } }); return false; }); }
内容的提问来源于stack exchange,提问作者cytek04
相关产品推荐
相关产品推荐

