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

ASP.NET Core Razor Pages列表模型绑定Post提交失效求助

问题原因及解决方案

核心原因

你用@foreach遍历Model.Notions生成下拉框时,Razor生成的表单元素name属性格式是EvalComp_Notion.Note,而ASP.NET Core的模型绑定需要带索引的命名格式(比如Notions[0].Note、Notions[1].Note)才能正确识别并绑定到List<VM_Notion>集合。这种命名不匹配导致POST时Notions列表为空,进而触发ModelState验证失败。

解决方案

1. 修改视图代码:用for循环替代foreach

因为List<T>支持索引访问,用for循环可以让Razor生成符合模型绑定要求的name属性:

@for (int i = 0; i < Model.Notions.Count; i++)
{
    <tr>
        <td>
            <select class="form-control" asp-for="Notions[i].Note">
                @foreach (var choix in Model.Notions[i].NotePossibles)
                {
                    <option value="@choix.Key">@choix.Value</option>
                }
            </select>
        </td>
        <!-- 若有其他字段如Commentaire,同样要使用Notions[i].Commentaire的格式 -->
        <td>
            <input asp-for="Notions[i].Commentaire" class="form-control" />
        </td>
    </tr>
}

2. 优化下拉框生成(可选)

可以用asp-items TagHelper替代手动循环生成option,代码更简洁:

@for (int i = 0; i < Model.Notions.Count; i++)
{
    <tr>
        <td>
            <select class="form-control" 
                    asp-for="Notions[i].Note"
                    asp-items="@(new SelectList(Model.Notions[i].NotePossibles, "Key", "Value"))">
            </select>
        </td>
    </tr>
}

3. 完善OnPostAsync方法

如果ModelState验证失败需要返回页面,必须重新填充Notions的NotePossibles(POST请求不会自动保留这些数据),否则下拉框会为空:

public async Task<IActionResult> OnPostAsync(int id) // 需要接收id重新加载数据
{
    if (!ModelState.IsValid)
    {
        // 重新加载Notions数据并填充NotePossibles
        var EC = await _context.EvaluationCompetences.Include(e => e.EvaluationCompetenceNotions)
                                                      .ThenInclude(ecn => ecn.Notion)
                                                      .ThenInclude(n => n.NotionEvalChoixes)
                                                      .ThenInclude(nec => nec.EvaluationChoix)
                                                      .FirstOrDefaultAsync(e => e.Id == id);
        if (EC == null) return NotFound();
        
        Notions.Clear();
        foreach(var ECN in EC.EvaluationCompetenceNotions)
        {
            Notions.Add(new VM_Notion()
            {
                Nom = ECN.Notion.Nom,
                Note = ECN.Note,
                Commentaire = ECN.Commentaire,
                NotePossibles = ECN.Notion.NotionEvalChoixes.Select(nec => new { Rg = nec.Rang, ch = nec.EvaluationChoix.Descr })
                                                            .OrderBy(x => x.Rg)
                                                            .ToDictionary(ec => ec.Rg, ec => ec.ch)
            });
        }
        return Page();
    }

    // 处理表单提交逻辑,比如更新数据库实体
    foreach (var notion in Notions)
    {
        // 根据notion信息找到对应数据库记录并更新
    }

    try
    {
        await _context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        // 补充并发异常处理逻辑
    }

    return RedirectToPage("./Index"); // 提交成功后建议重定向,避免重复提交
}

额外注意点

  • 确保VM_Notion的Note字段类型和下拉框选项的value类型一致(当前都是int,无需调整)。
  • 若担心用户篡改列表数量,可添加索引范围验证逻辑防止越界。

内容的提问来源于stack exchange,提问作者Gabriel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:23:32