2014-09-13 83 views
0

我有一個動態填充的問題和答案列表。動態MVC RadioButton組選擇的答案

兩個問題:

  1. 的問題和答案回發後不顯示
  2. 所選擇的答案是缺少

視圖模型

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() ; 
      } 
     } 
    } 
} 

所選答案WER

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.你的財產'SelectedAnswer'沒有一個setter。 2.你試圖綁定到一個複雜的屬性('Answer'),但單選按鈕組只回發一個單一的值。你應該有'public int SelectedAnswer {get;組; }'。 – 2014-09-13 04:01:58

+0

這個問題呢?我是否需要在錯誤捕獲中創建另一個數據庫調用GetQuestions(),或者是否應該在發佈後將其保留填充? – User970008 2014-09-14 12:09:49

+0

很多你在這裏做的事情都令人困惑,例如你有一個'SelectedAnswers'集合 - 每個問題可以有多個答案嗎?你也應該有簡單的getter和setter來查看模型屬性並將它們填充到控制器中,而不是在getter中。由於您似乎沒有爲這些問題渲染任何輸入控件,因此他們不會被回發,並且您將需要再次獲取它們(但是,這可能會更好地表現出明智的效果,而不是回饋大量額外的輸入,以防萬一 – 2014-09-14 12:44:06

回答

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 

請注意,您可以爲問題和答案文本值添加隱藏輸入,以便回發,但一般而言,其更好的性能可以重新加載到控制器中(如果包含正確的數據註釋幷包含客戶端驗證,模型應該反正總是有效的)

+0

謝謝,我不得不修改一些東西,因爲SelectedAnswers和Questions是從自動生成的EF實體填充的。但我得到了它的工作。 – User970008 2014-09-15 02:21:41