ASP.NET MVC表单提交时脚本生成的GamePlay集合为空问题求助
问题分析与解决步骤
1. 修正表单结构,确保所有输入控件在form内
你的GamePlay相关输入和表格都在form标签外部,提交时浏览器只会发送form内的控件数据,这是集合为空的核心原因之一。调整后的表单结构如下:
<form asp-action="AddNew" method="post" enctype="multipart/form-data"> <div class="row"> <div class="col-md-4"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="GameName" class="control-label"></label> <input asp-for="GameName" class="form-control" /> <span asp-validation-for="GameName" class="text-danger"></span> </div><br/> <div class="form-group"> <input type="submit" value="Create games-Play" class="btn btn-primary" /> </div> </div> <div class="col-md-6"> <!-- 输入区域 --> <div class="row"> <div class="col-md-4"> <div class="form-group"> <label for="Power">Power:</label> <input type="text" class="form-control" id="Power" /> </div> </div> <div class="col-md-2 align-self-end"> <div class="form-group"> <input type="button" value="Add GamePlay" class="btn btn-primary reset" /> </div> </div> </div> <br/> <!-- 表格区域 --> <table id="dataTable" class="table table-bordered"> <thead> <tr> <th>Power</th> <th>Actions</th> </tr> </thead> <tbody> @if (Model.GamePlays != null) { @for (int i = 0; i < Model.GamePlays.Count; i++) { <tr> <td>@Model.GamePlays[i].Power</td> <td> <a href="#" class="edit" data-index="@i">Remove</a> <input type="hidden" name="GamePlays[@i].Power" value="@Model.GamePlays[i].Power" /> </td> </tr> } } </tbody> </table> <input type="hidden" id="gamePlayCount" value="@(Model.GamePlays?.Count ?? 0)" /> </div> </div> </form>
这里做了这些修正:
- 把所有内容移入form标签内,确保提交时能收集到所有数据
- 用
for循环代替foreach渲染表格,生成符合ASP.NET Core模型绑定要求的索引命名 - 新增隐藏字段存储每个GamePlay的Power值,确保提交时能被正确绑定
- 增加
gamePlayCount隐藏字段,跟踪当前集合数量,方便新增时计算索引
2. 修正JavaScript脚本,生成正确的模型绑定字段
原脚本存在未定义变量、属性名不匹配、未生成正确绑定字段等问题,修正后的脚本:
<script> $(document).ready(function () { $(document).on("click", ".reset", function () { var powerValue = $("#Power").val(); if (!powerValue) { alert("请输入Power值"); return; } var count = parseInt($("#gamePlayCount").val()); var row = `<tr> <td>${powerValue}</td> <td> <a href="#" class="edit" data-index="${count}">Remove</a> <input type="hidden" name="GamePlays[${count}].Power" value="${powerValue}" /> </td> </tr>`; $("#dataTable tbody").append(row); $("#gamePlayCount").val(count + 1); $("#Power").val(""); }); $(document).on("click", ".edit", function (e) { e.preventDefault(); $(this).closest("tr").remove(); $("#dataTable tbody tr").each(function(index) { $(this).find("a.edit").attr("data-index", index); $(this).find("input[type='hidden']").attr("name", `GamePlays[${index}].Power`); }); $("#gamePlayCount").val($("#dataTable tbody tr").length); }); }); </script>
修正点说明:
- 移除未定义的
selection变量,只处理GamePlay的Power字段 - 新增行时生成带有连续索引的隐藏字段(
GamePlays[count].Power),符合ASP.NET Core集合绑定规则 - 增加删除行后的索引重排逻辑,避免因索引空缺导致模型绑定失败
- 增加输入验证,确保Power值不为空
3. 修正控制器方法,确保模型正确接收
控制器的AddNew方法需要正确接收Plays模型,并处理集合初始化:
[HttpPost] public IActionResult AddNew(Plays model) { model.GamePlays ??= new List<GamePlay>(); if (ModelState.IsValid) { _context.Plays.Add(model); _context.SaveChanges(); foreach (var gamePlay in model.GamePlays) { gamePlay.PlaysId = model.Id; _context.GamePlay.Add(gamePlay); } _context.SaveChanges(); return RedirectToAction(nameof(Index)); } return View(model); }
注意:如果你的DbContext中GamePlay的DbSet命名是GamePlays,请将_context.GamePlay改为_context.GamePlays。
4. 初始化视图模型
返回Create视图时,确保Plays的GamePlays集合已初始化,避免空引用:
public IActionResult Create() { return View(new Plays { GamePlays = new List<GamePlay>() }); }
关键注意点
- ASP.NET Core集合模型绑定要求元素name属性必须为
集合名[索引].属性名格式,且索引需从0开始连续 - 所有需要提交的输入控件必须放在form标签内,否则浏览器不会发送对应数据
- 动态新增/删除行后,必须保证索引连续,否则模型绑定会跳过空缺索引的元素
内容的提问来源于stack exchange,提问作者Alva Mira
相关产品推荐
相关产品推荐

