ASP.NET Core 5.0中如何从视图新增元素到Model并提交至控制器
ASP.NET Core 5.0 动态新增集合元素并提交至控制器的通用实现方法
核心问题在于ASP.NET Core的模型绑定需要集合元素的命名遵循特定格式,原有代码中PartialView的name属性未符合集合名[索引].属性名的规则,导致新增元素无法被控制器正确绑定到List<AppealModel>。以下是通用实现方案:
一、修正原有集合元素的渲染逻辑
将主视图中遍历集合的foreach改为带索引的for循环,确保原有元素的表单命名符合模型绑定要求:
@model RequestModel <!-- 容器用于存放所有申诉元素 --> <div id="foivappeals"> @for (int i = 0; i < Model.Appeals.Count; i++) { @await Html.PartialAsync("/Views/Data/Modal/Partial/_FoivAppealPartial.cshtml", Model.Appeals[i], new ViewDataDictionary(ViewData) { { "Index", i } }) } </div>
二、修改PartialView的表单命名
更新PartialView,基于传入的索引生成正确的name属性,确保模型绑定能识别每个元素:
@model AppealModel @{ // 获取传入的索引值,新增元素时由控制器传入当前集合长度 var index = ViewData["Index"] ?? 0; } <div class="container appeal-row"> <div class="row"> <div class="col-5"> <label for="inp" class="inp"> <input class="fields" type="date" asp-for="@Model.Date" name="Appeals[@index].Date" /> <span class="label">日期</span> <span class="focus-bg"></span> </label> </div> <div class="col-5"> <label for="inp" class="inp"> <input class="fields" asp-for="@Model.Number" placeholder="&nbsp;" required name="Appeals[@index].Number" /> <span class="label">编号</span> <span class="focus-bg"></span> </label> </div> <div class="col-2 appealdeletediv"> <a style="cursor: pointer;" class="deleteFoivRow"> <i class="fas fa-minus-circle appealdeletebutton"></i> </a> </div> </div> </div>
三、调整新增元素的控制器方法
新增控制器方法接收当前集合的长度作为索引,返回带正确命名的PartialView:
public IActionResult DisplayNewFoivApeal(int currentCount) { // 创建空的申诉模型 var newAppeal = new AppealModel(); // 传入当前集合长度作为新元素的索引 return PartialView("/Views/Data/Modal/Partial/_FoivAppealPartial.cshtml", newAppeal, new ViewDataDictionary(ViewData) { { "Index", currentCount } }); }
四、优化前端AJAX与删除逻辑
1. 新增元素的AJAX请求
点击添加按钮时,先统计当前已有的元素数量,传给控制器作为新元素的索引:
<button class="appealaddbutton" id="addfoivappeal"><i class="fas fa-plus"></i></button> <script> $("#addfoivappeal").click(function () { // 获取当前已有的申诉元素数量 var currentCount = $(".appeal-row").length; $.ajax({ type: "GET", url: '@Url.Action("DisplayNewFoivApeal","Data")', data: { currentCount: currentCount }, success: function (html) { $("#foivappeals").append(html); } }); return false; }); </script>
2. 删除元素并整理索引(可选)
删除元素后重新整理剩余元素的索引,避免命名断层(ASP.NET Core允许断层,但整理后更规范):
<script> $(document).on("click", ".deleteFoivRow", function () { // 删除当前行 $(this).closest(".appeal-row").remove(); // 重新更新所有元素的索引命名 $(".appeal-row").each(function(index) { $(this).find("input[name^='Appeals[']").each(function() { var oldName = $(this).attr("name"); var newName = oldName.replace(/Appeals\[\d+\]/, `Appeals[${index}]`); $(this).attr("name", newName); }); }); }); </script>
五、控制器接收提交数据
确保控制器的POST方法参数为RequestModel,此时model.Appeals会包含原有和新增的所有元素:
[HttpPost] public IActionResult SubmitRequest(RequestModel model) { // 处理提交的RequestModel,model.Appeals包含所有申诉元素 // 例如保存到数据库等逻辑 return RedirectToAction("Index"); }
原理说明
ASP.NET Core的模型绑定系统会识别符合集合名[索引].属性名格式的表单字段,并自动将其绑定到对应的List<T>集合中。只要确保新增、删除操作后,所有元素的name属性都遵循该格式,控制器就能正确接收完整的集合数据。
内容的提问来源于stack exchange,提问作者Anulyev
相关产品推荐
相关产品推荐

