bam*_*mbi 23 c# asp.net asp.net-mvc
我正在开始我的第一个ASP.NET MVC项目,所以我有一个简单的问题.我有以下代码:
foreach(var question in Model.GeneralQuestions)
{
<div class = "well">
<h3>
<strong>@question.QuestionString</strong>
</h3>
@foreach (var answer in question.PossibleAnswers)
{
@Html.RadioButtonFor(model => question.QuestionString, answer.Answer)
@Html.Label(answer.Answer)
<br />
}
</div>
}
Run Code Online (Sandbox Code Playgroud)
Model.GeneralQuestions中的所有问题都是唯一的,因此单选按钮应按名称属性分组(对于每个问题,一组单选按钮).但是这段代码只生成一个组,所以当我回答第二个问题时,首先会取消选择.我需要改变什么?
编辑
我的模型看起来像:
public class StudentViewModel
{
public Student Student { get; set; }
public List<Question> GeneralQuestions { get; set; }
public List<SubjectQuestions> SubjectQuestions { get; set; }
}
public class Student
{
public int StudentID { get; set; }
public string Index { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public virtual ICollection<Subject> Subjects { get; set; }
}
public class Question
{
public int QuestionID { get; set; }
public string QuestionString { get; set; }
public bool IsAssociatedWithSubject { get; set; }
public virtual ICollection<PossibleAnswer> PossibleAnswers { get; set; }
public virtual ICollection<Results> Results { get; set; }
}
public class SubjectQuestions
{
public Subject Subject { get; set; }
public List<Question> Questions { get; set; }
}
public class Results
{
public int ResultsID { get; set; }
public int QuestionID { get; set; }
public int? SubjectID { get; set; }
public int PossibleAnswerID { get; set; }
public virtual Question Question { get; set; }
public virtual PossibleAnswer PossibleAnswer { get; set; }
public virtual Subject Subject { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在StudentViewModel的一个实例中,我保存了一个学生和他应该回答的所有问题(一般和他正在研究的科目相关)并将其传递给查看.在视图中,我将所有问题都以单一形式提出,它们都是无线电的类型.那么,任何人都可以帮我分组单选按钮并正确回发此表单吗?
小智 29
您的代码存在许多问题,包括生成重复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; }
}
Run Code Online (Sandbox Code Playgroud)
视图
@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" />
}
Run Code Online (Sandbox Code Playgroud)
调节器
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
}
Run Code Online (Sandbox Code Playgroud)
注意我对模型隐含的数据库结构感到有些困惑(例如,为什么需要单独的模型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
}
}
};
Run Code Online (Sandbox Code Playgroud)
发布时,模型将填充每个主题中每个问题的所选答案的ID.请注意DisplayFor()某些属性的用法.这些不会回发,因此如果您返回视图(例如ModelState无效),则需要重新填充这些属性.或者,您可以生成只读文本框或为这些属性添加隐藏输入.我还建议你检查生成的HTML,特别是看起来像的名称属性
<input type="radio" name="Subjects[0].Questions[0].SelectedAnswer" ...
Run Code Online (Sandbox Code Playgroud)
让您了解集合如何在回发后绑定到您的模型
诀窍是使用一个表达式(Html.RadioButtonFor的第一个参数),它包含一组每个单选按钮更改的值.在您的情况下,它将是问题列表中的索引.
以下是一些示例代码:
@for (int i = 0; i < Model.GeneralQuestions.Count; i++)
{
var question = Model.GeneralQuestions[i];
@Html.Label(question.QuestionString)
<br />
foreach (var answer in question.PossibleAnswers)
{
@Html.RadioButtonFor(model =>
Model.GeneralQuestions[i].SelectedAnswerId, answer.Id)
@Html.Label(answer.Answer)
<br />
}
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下HTML:
<label for="Q1">Q1</label>
<br />
<input id="GeneralQuestions_0__SelectedAnswerId"
name="GeneralQuestions[0].SelectedAnswerId" type="radio" value="1" />
<label for="A01">A01</label>
<br />
<input id="GeneralQuestions_0__SelectedAnswerId"
name="GeneralQuestions[0].SelectedAnswerId" type="radio" value="2" />
<label for="A02">A02</label>
<br />
<label for="Q2">Q2</label>
<br />
<input id="GeneralQuestions_1__SelectedAnswerId"
name="GeneralQuestions[1].SelectedAnswerId" type="radio" value="11" />
<label for="A11">A11</label>
<br />
<input id="GeneralQuestions_1__SelectedAnswerId"
name="GeneralQuestions[1].SelectedAnswerId" type="radio" value="12" />
<label for="A12">A12</label>
<br />
Run Code Online (Sandbox Code Playgroud)
为了完整起见,这里是使用的模型的简化版本:
public class StudentViewModel
{
public List<Question> GeneralQuestions { get; set; }
}
public class Question
{
public int QuestionId { get; set; }
public string QuestionString { get; set; }
public ICollection<PossibleAnswer> PossibleAnswers { get; set; }
public int SelectedAnswerId { get; set; }
}
public class PossibleAnswer
{
public int Id { get; set; }
public string Answer { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是动作方法的代码:
return View(new StudentViewModel
{
GeneralQuestions =
new List<Question>
{
new Question
{
QuestionString = "Q1",
PossibleAnswers =
new[]
{
new PossibleAnswer {Id = 1, Answer = "A01"},
new PossibleAnswer {Id = 2, Answer = "A02"}
}
},
new Question
{
QuestionString = "Q2",
PossibleAnswers =
new[]
{
new PossibleAnswer {Id = 11, Answer = "A11"},
new PossibleAnswer {Id = 12, Answer = "A12"}
}
},
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
56215 次 |
| 最近记录: |