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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:40:57