您的代码存在许多问题,包括生成重复
id的(无效的html),生成重复的
name属性(这就是为什么您仅创建一组的原因,但更重要的是,这将阻止您在回发时绑定到模型),那么您实际上并没有绑定到有效的属性。
您将需要创建视图模型来表示要显示和编辑的视图,并在
for循环中(或使用
EditorTemplate)生成单选按钮,以便使用索引器正确命名它们。
查看模型
public class QuestionVM{ public int ID { get; set; } // for binding public string Text { get; set; } [Required] public int? SelectedAnswer { get; set; } // for binding public IEnumerable<AnswerVM> PossibleAnswers { get; set; }}public class SubjectVM{ public int? ID { get; set; } [DisplayFormat(NullDisplayText = "General")] public string Name { get; set; } public List<QuestionVM> Questions { get; set; }}public class AnswerVM{ public int ID { get; set; } public string Text { get; set; }}public class StudentVM{ public int ID { get; set; } public string Name { get; set; } // plus any other properties of student that you want to display in the view public List<SubjectVM> Subjects { get; set; }}视图
@model YourAssembly.StudentVM@using(Html.BeginForm()){ @Html.HiddenFor(m => m.ID) @Html.DisplayFor(m => m.Name) for(int i = 0; i < Model.Subjects.Count; i++) { @Html.HiddenFor(m => m.Subjects[i].ID) @Html.DisplayFor(m => m.Subjects[i].Name) // will display "General" if no name for (int j = 0; j < Model.Subjects[i].Questions.Count; j++) { @Html.HiddenFor(m => m.Subjects[i].Questions[j].ID) @Html.DisplayFor(m => m.Subjects[i].Questions[j].Text) foreach(var answer in Model.Subjects[i].Questions[j].PossibleAnswers ) { <div> @Html.RadioButtonFor(m => m.Subjects[i].Questions[j].SelectedAnswer, answer.ID, new { id = answer.ID}) <label for="@answer.ID">@answer.Text</label> </div> } @Html.ValidationMessageFor(m => m.Subjects[i].Questions[j].SelectedAnswer) } } <input type="submit" value="save" />}控制者
public ActionResult Edit(int ID){ StudentVM model = new StudentVM(); // populate your view model with values from the database return View(model);}[HttpPost]public ActionResult Edit(StudentVM model){ // save and redirect}请注意,我通过你的模型所隐含的数据库结构混淆了一点(比如你为什么需要有单独的模型
Question,并
SubjectQuestion当
null了数值
SubjectID将其标识为“一般”的问题)。我建议您首先在GET方法中对一些值进行硬编码,以了解其工作原理并回发。
StudentVM model = new StudentVM();model.ID = 1;model.Name = "bambiinela";model.Subjects = new List<SubjectVM>(){ new SubjectVM() { Questions = new List<QuestionVM>() { new QuestionVM() { ID = 1, Text = "Question 1", SelectedAnswer = ?, // set this if you want to preselect an option PossibleAnswers = new List<AnswerVM>() { new AnswerVM() { ID = 1, Text = "Answer A" }, new AnswerVM() { ID = 1, Text = "Answer B" } } }, new QuestionVM() { ID = 2, Text = "Question 2", PossibleAnswers = new List<AnswerVM>() { // similar to above } } } }, new SubjectVM() { ID = 1, Name = "Math", Questions = new List<QuestionVM>() { // similar to above } }};发布时,将为模型填充每个主题中每个问题的所选答案的ID。注意
DisplayFor()某些属性的使用。这些不会回发,因此如果您返回视图(例如
ModelState,无效),则需要重新填充这些属性。或者,您可以生成一个只读文本框或为这些属性添加隐藏的输入。我还建议您检查生成的HTML,尤其是看起来像这样的name属性
<input type="radio" name="Subjects[0].Questions[0].SelectedAnswer" ...
让您了解回发后集合如何绑定到模型



