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

如何在ASP.NET Core 2与Razor中创建多组单选按钮并获取选中值

解决ASP.NET Core表单提交时Answers模型为空的问题

你遇到的核心问题是ASP.NET Core的模型绑定无法正确识别循环生成的集合项——因为你用foreach遍历Model.Answers时,生成的表单控件名称没有带上集合索引,导致提交时无法将选中值映射回SafetyObservationCardForm的Answers集合。下面一步步帮你修正:

1. 先修正模型的集合类型(可选但推荐)

把SafetyObservationCardForm里的IEnumerable<Answer>改成List<Answer>,因为List支持索引访问,后续视图循环更方便:

public class SafetyObservationCardForm {
    // 其他属性保持不变
    public List<Answer> Answers { get; set; } 
}

对应控制器里的赋值也同步调整:

// 原代码里rb是List<Answer>,直接赋值即可
form.Answers = rb;

2. 重写视图的表单渲染逻辑

放弃foreach,改用for循环生成带索引的控件名称,让模型绑定能识别集合项:

@model DBI.Safety.Models.SafetyObservationCardForm

<form asp-action="CreateTest">
    @* 循环每个问题对应的Answer项 *@
    @for (int i = 0; i < Model.Answers.Count; i++)
    {
        <div class="question-group">
            <!-- 显示问题文本(假设你的QuestionsViewModel有QuestionText属性,按需调整) -->
            <h4>@Model.Questions[i].QuestionText</h4>
            
            <!-- 循环渲染当前问题的3个单选选项 -->
            @foreach (var obsType in Model.Answers[i].ObservationTypes)
            {
                <label style="margin-right: 15px;">
                    <input asp-for="@Model.Answers[i].SelectedObservation" type="radio" value="@obsType.Id" />
                    @obsType.Name
                </label>
            }
        </div>
    }

    <!-- 其他表单字段(Comments/Location等)按常规方式添加 -->
    <div class="form-group">
        <label asp-for="Comments"></label>
        <textarea asp-for="Comments" class="form-control"></textarea>
    </div>

    <button type="submit" class="btn btn-primary">提交表单</button>
</form>

关键修正点说明:

  • 用for循环替代foreach:这样生成的控件名称会是Answers[0].SelectedObservation、Answers[1].SelectedObservation这种格式,ASP.NET Core的模型绑定器能直接识别并映射到集合中。
  • 修正单选按钮的value值:原视图里的value="@answer.Id"是错误的,应该绑定ObservationType.Id,这样选中后提交的是对应的选项ID,会自动赋值给Answer.SelectedObservation。

3. 确保提交控制器能正确接收模型

你的CreateTest方法要直接接收SafetyObservationCardForm作为参数,验证通过后就能拿到完整的选中值:

[HttpPost]
public IActionResult CreateTest(SafetyObservationCardForm form)
{
    if (ModelState.IsValid)
    {
        // 这里form.Answers已经包含每个问题的SelectedObservation选中值了
        // 执行你的保存逻辑...
        return RedirectToAction("Test");
    }

    // 如果验证失败,重新填充视图所需的问题和选项数据
    using (IDbConnection dbConnection = Connection)
    {
        dbConnection.Open();
        var questions = dbConnection.Query<QuestionsViewModel>("SELECT * FROM SOCQuestions ORDER BY soc_order_id");
        var observationType = new List<ObservationType> { 
            new ObservationType { Id = 1, Name = "Safe" }, 
            new ObservationType { Id = 2, Name = "At Risk" }, 
            new ObservationType { Id = 3, Name = "N/A" } 
        };
        
        foreach (var answer in form.Answers)
        {
            answer.ObservationTypes = observationType;
        }
        form.Questions = questions.ToList();
        return View(form);
    }
}

核心原理总结

ASP.NET Core的模型绑定对集合类型有特定的格式要求:控件名称必须包含索引(如CollectionName[index].PropertyName),foreach循环无法生成这种格式,而for循环可以通过索引明确标识每个集合项,让绑定器正确映射提交的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:03:26