我有一个动态填充的问题和答案列表。
两个问题:
视图模型
public class RegistrationViewModel : RegisterExternalLoginModel
{
//...etc...
public Question Question { get; set; }
public Answer Answer { get; set; }
public List<Question> Questions { get; set; }
public IList<Answer> PossibleAnswers { get; set; }
public List<SelectedAnswer> SelectedAnswers { get; set; }
public IList<SelectedAnswer> PreviousAnswers
{
set
{
foreach(Question q in Questions)
{
q.SelectedAnswers = value.Where(t => t.questionId == q.objectId).ToList() ;
}
}
}
}
选择的答案
public Answer SelectedAnswer
{
get
{
if (SelectedAnswers != null && SelectedAnswers.Count > 0)
{
var answers = SelectedAnswers.Where(t => t.questionId == objectId);
if (answers.Count() == 1)
{
var result = Answers.Where(t => t.objectId == answers.First().answerId).First();
return result;
}
}
return null;
}
}
的ActionResult
public ActionResult CreateQuestions()
{
RegistrationViewModel vm = new RegistrationViewModel();
IQFacade facade = new QFacade(CreateUserContext(true));
//Questions and Answers
vm.Questions = facade.GetQuestions().ToList();
vm.PossibleAnswers = facade.GetPossibleAnswers();
return View(vm);
}
发表
[HttpPost]
public ActionResult CreateQuestions(RegistrationViewModel vm)
{
var context = CreateUserContext(true);
try{
IQFacade f = new QFacade(context);
f.CreateSomething(vm.User.name, vm.etc, vm.SelectedAnswers);//Need all the answers here, but null
}
catch (Exception ex)
{
//error stuff, etc...
return View(vm);//the questions do not appear after this point. Do I need to bind them again from GetQuestions or shouldn't they still be a part of the vm object that I am returning?
}
}
return RedirectToAction("Index");
}
在视图中,我使用的是编辑模板
@Html.EditorFor(x => x.Questions)
模板
@foreach (var possibleAnswer in Model.Answers)
{
<div class="radio">
@Html.RadioButtonFor(question => question.SelectedAnswer, possibleAnswer.objectId, new { id = possibleAnswer.objectId })
<label for="@possibleAnswer.objectId">@possibleAnswer.text <span>@possibleAnswer.value</span></label> <p>@possibleAnswer.description</p>
</div>
}
一切都是第一次有效,但不是在回发之后。我已经阅读了几十篇类似的SO帖子。我错过了什么?
答案 0 :(得分:1)
基于评论,你的模型应该是这样的(不确定你所有的模型属性,所以我在这里做了一些假设)
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<Answer> PossibleAnswers { get; set; }
}
public class RegistrationViewModel : RegisterExternalLoginModel
{
public RegistrationViewModel()
{
Questions = new List<QuestionVM>();
}
//...etc...
public List<QuestionVM> Questions { get; set; }
}
GET方法
public ActionResult CreateQuestions()
{
RegistrationViewModel vm = new RegistrationViewModel();
.....
// Populate the questions and answers
var questions = facade.GetQuestions().ToList();
var answers = facade.GetPossibleAnswers();
foreach (var question in questions)
{
QuestionVM qvm = new QuestionVM();
qvm.ID = question.ID;
qvm.Test = question.Text;
// Add possible answers for the question
qvm.PossibleAnswers = answers.Where(a => a.QuestionID == question.ID);
// If loading existing questions/answers for existing user, also set value of current SelectedAnswer so its selected by default in the view
vm.Questions.Add(qvm);
}
return View(vm);
}
查看
@model YourAssembly.RegistrationViewModel
....
@for(int i = 0; i < Model.Questions.Count; i++)
{
@Html.HiddenFor(m > m.Questions[i].ID) // for binding
@Html.DisplayFor(m > m.Questions[i].Text)
foreach(var answer in Model.Questions[i].PossibleAnswers)
{
@Html.RadioButtonFor(m => m.Questions[i].SelectedAnswer, answer.ID, new { id = answer.ID})
<label for="@answer.ID">answer.Text</label>
}
}
POST方法
[HttpPost]
public ActionResult CreateQuestions(RegistrationViewModel vm)
{
if (!ModelState.IsValid)
{
// You need to rebuild the question text and possible answers because these are not posted back
return View(vm);
}
// Your model is now populated with the ID of each question and the selected answer which can be saved to the database
请注意,您可以为问题和答案文本值添加隐藏的输入,以便他们回发,但通常在控制器中重新加载的性能会更好(如果您包含正确的数据注释并包括客户端验证,则模型应始终为无论如何都有效回传)