ASP.NET Core中如何将List<T>模型从视图表单传递到控制器
问题根源
你遇到的绑定失败是两个原因导致的:
asp-forTagHelper 生成的默认name属性和你手动设置的name="@Model[i].Id"冲突,不符合ASP.NET Core集合模型的绑定规则- 列表类型的模型绑定要求表单字段名必须符合
[索引].属性名的格式,你手动设置的name为问题Id,和后端接收的List<EvaluationQuestionModel>结构不匹配,框架无法把提交的值映射到对应对象上。
修复方案
你提到的两处修改是正确的,修改后的完整视图代码如下:
@model List<EvaluationQuestionModel> <form asp-controller="EvaluationQuestions" asp-action="SubmitSurvey"> @for (int i = 0; i < Model.Count; i++) { <!-- 保留问题id的隐藏字段,方便提交后关联问题 --> <input type="hidden" name="[@i].Id" value="@Model[i].Id" /> <div class="row"> <div class="col-lg-12 col-md-12 col-sm-12 col-12"> <label>@Model[i].Title</label> </div> <div class="col-lg-12 col-md-12 col-sm-12 col-12"> @for (int j = 0; j < Model[i].Answers.Count; j++) { <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="[@i].SelectedAnswer" value="@Model[i].Answers[j].Grade" checked="@(Model[i].SelectedAnswer == Model[i].Answers[j].Grade)"> <label class="form-check-label">@Model[i].Answers[j].Title</label> </div> } </div> </div> <hr /> } <div class="row no-block d-flex justify-content-center"> <input type="submit" value="Submit"> </div> </form>
对应后端的接收方法写法如下:
public IActionResult SubmitSurvey(List<EvaluationQuestionModel> surveyResult) { // 遍历surveyResult即可拿到每个问题的Id和用户选择的SelectedAnswer分值 foreach(var question in surveyResult) { int questionId = question.Id; int userSelectedGrade = question.SelectedAnswer; // 后续业务逻辑 } return Ok(); }
原理解释
- ASP.NET Core处理
List<T>类型的模型绑定时,会自动匹配格式为[索引].属性名的表单字段,索引从0开始连续递增即可自动映射到对应位置的对象属性 - 同一问题的所有单选框使用同一个
[@i].SelectedAnswer作为name,既保证了单选互斥的特性,又完全符合绑定规则,提交后的值会自动填充到对应问题的SelectedAnswer属性中 - 额外加的隐藏字段
[@i].Id用于提交问题的Id,方便后续业务逻辑关联对应问题,不需要的话可以删除
内容的提问来源于stack exchange,提问作者Sed Sajad
相关产品推荐
相关产品推荐

