如何在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
相关产品推荐
相关产品推荐

