如何借助模型将前端动态表格数据传回Controller
批量提交动态表格数据到ASP.NET Core Controller的解决方案
看起来你已经抓准了核心思路——把动态生成的表格数据转换成和ViewModel中ComputerImportModel结构匹配的数组,再通过AJAX一次性提交到Controller,这确实是处理这类动态数据批量提交的最优方案,比循环提交单个对象高效太多。下面我把你的代码完善成可直接运行的完整示例:
1. 先确保Model和ViewModel结构正确
首先得把基础的数据模型和视图模型定义清楚,这样后台才能正确绑定数据:
// 单条电脑数据的模型 public class ComputerImportModel { public string Hostname { get; set; } public string MacAddress { get; set; } public string GUID { get; set; } } // 用于视图批量提交的视图模型 public class ComputerImportViewModel { public IEnumerable<ComputerImportModel> TableComputerImport { get; set; } }
2. 优化View的动态表格逻辑
你的现有JS需要补充从下拉框取数据的逻辑,同时要保证后续能顺利提取表格里的每条数据。这里我给你完善了完整的视图结构和JS代码:
@model ViewModels.ComputerImportViewModel <div class="container mt-3"> <!-- 预设的下拉框,用于选择要插入的数据 --> <div class="row mb-3"> <div class="col-md-4"> <label>主机名</label> <select id="sel_hostname" class="form-control"> <option value="PC-Office-001">PC-Office-001</option> <option value="PC-Office-002">PC-Office-002</option> <option value="PC-Lab-001">PC-Lab-001</option> </select> </div> <div class="col-md-4"> <label>MAC地址</label> <select id="sel_mac" class="form-control"> <option value="AA:BB:CC:00:00:01">AA:BB:CC:00:00:01</option> <option value="AA:BB:CC:00:00:02">AA:BB:CC:00:00:02</option> </select> </div> <div class="col-md-4"> <label>GUID</label> <select id="sel_guid" class="form-control"> <option value="3F2504E0-4F89-11D3-9A0C-0305E82C3301">3F2504E0-4F89-11D3-9A0C-0305E82C3301</option> <option value="3F2504E0-4F89-11D3-9A0C-0305E82C3302">3F2504E0-4F89-11D3-9A0C-0305E82C3302</option> </select> </div> </div> <button type="button" id="btn_insert" class="btn btn-primary mb-3">添加到表格</button> <div class="card"> <table class="table table-bordered" id="table_computerimport"> <thead class="table-light"> <tr> <th>Hostname</th> <th>MacAddress</th> <th>GUID</th> <th>操作</th> </tr> </thead> <tbody> <!-- 动态生成的行将插入到这里 --> </tbody> </table> </div> <button type="button" id="btn_submit" class="btn btn-success mt-3">批量提交数据</button> </div> @section Scripts { <script> $(document).ready(function () { // 插入新行到表格 $('#btn_insert').on('click', function () { // 从下拉框获取选中值 const hostname = $('#sel_hostname').val(); const macAddress = $('#sel_mac').val(); const guid = $('#sel_guid').val(); const rowId = $('#table_computerimport tbody tr').length + 1; // 构造新行HTML const newRow = ` <tr id="row-${rowId}"> <td>${hostname}</td> <td>${macAddress}</td> <td>${guid}</td> <td><button class="btn btn-sm btn-danger delete-btn" data-row-id="${rowId}">删除</button></td> </tr> `; // 追加到表格tbody $('#table_computerimport tbody').append(newRow); }); // 删除行事件(用事件委托处理动态生成的按钮) $('#table_computerimport').on('click', '.delete-btn', function () { const rowId = $(this).data('row-id'); $(`#row-${rowId}`).remove(); }); // 批量提交数据到Controller $('#btn_submit').on('click', function () { // 遍历表格行,组装成和ComputerImportModel匹配的数组 const computerData = []; $('#table_computerimport tbody tr').each(function () { const $row = $(this); computerData.push({ Hostname: $row.find('td:eq(0)').text().trim(), MacAddress: $row.find('td:eq(1)').text().trim(), GUID: $row.find('td:eq(2)').text().trim() }); }); // 检查是否有数据 if (computerData.length === 0) { alert('请先添加数据到表格!'); return; } // 发送AJAX请求 $.ajax({ url: '@Url.Action("BatchImport", "Computer")', // 替换成你的Controller和Action名称 type: 'POST', contentType: 'application/json', data: JSON.stringify({ TableComputerImport: computerData }), success: function (response) { if (response.success) { alert('批量提交成功!'); // 清空表格 $('#table_computerimport tbody').empty(); } else { alert('提交失败:' + response.message); } }, error: function (xhr, status, error) { alert('请求出错:' + error); } }); }); }); </script> }
3. 编写Controller接收批量数据
在对应的Controller里添加处理批量提交的Action:
public class ComputerController : Controller { [HttpPost] public IActionResult BatchImport(ComputerImportViewModel model) { // 验证数据有效性 if (!ModelState.IsValid || model.TableComputerImport == null || !model.TableComputerImport.Any()) { return Json(new { success = false, message = "无效的提交数据,请检查表格内容" }); } // 这里编写你的业务逻辑,比如保存到数据库 foreach (var computer in model.TableComputerImport) { // 示例:打印每条数据 Console.WriteLine($"主机名:{computer.Hostname},MAC:{computer.MacAddress},GUID:{computer.GUID}"); } return Json(new { success = true, message = "批量数据处理完成" }); } }
关键细节说明
- 为什么不用
input asp-for循环绑定?因为动态生成的DOM元素是JS创建的,ASP.NET Core的Tag Helper无法自动生成对应的绑定属性;手动维护name="TableComputerImport[0].Hostname"这类命名也可行,但不如转成JSON数组提交简洁直观。 - 确保AJAX提交的JSON结构和ViewModel完全匹配:外层字段名要和ViewModel的
TableComputerImport一致,数组内每个对象的属性名要和ComputerImportModel的属性名匹配(C#的帕斯卡命名和JS的驼峰命名在ASP.NET Core默认配置下是可以自动映射的,不过示例里用一致的命名更稳妥)。 - 用事件委托处理删除按钮的点击事件,避免动态生成的按钮无法触发事件的问题。
内容的提问来源于stack exchange,提问作者Stephan
相关产品推荐
相关产品推荐

