2015-07-01 36 views
0

當我提交時,我的模型在帖子上是空的。模型在帖子上空

型號

public QuizModel() 
{ 
    Questions = new List<QuizQuestionModel>(); 
} 

public QuizModel(string quizName) 
{ 
    QuizName = quizName; 
    Score = 0; 
    IntranetEntities db = new IntranetEntities(); 
    Quiz quiz = db.Quizs.Where(x => x.Name.Equals(quizName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); 
    if (quiz != null) 
    { 
     IQueryable<Quiz_Question> questions = db.Quiz_Question.Where(x => x.QuizID.Equals(quiz.ID)).OrderBy(x => x.QuestionNo); 

     Questions = new List<QuizQuestionModel>(); 
     foreach (Quiz_Question question in questions) 
     { 
      QuizQuestionModel q = new QuizQuestionModel(); 
      q.ID = question.ID; 
      q.Question = question.Question; 
      q.UserAnswer = null; 
      q.SystemAnswer = question.Answer; 
      Questions.Add(q); 
     } 
    } 
} 

public string QuizName { get; set; } 
public List<QuizQuestionModel> Questions { get; set; } 
public int Score { get; set; } 

控制器

[HttpPost] 
public ActionResult OSHAQuiz(Models.QuizModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     bool passed = false; 

     model.Score = model.Questions.Where(x => x.UserAnswer.Equals(x.SystemAnswer, StringComparison.InvariantCultureIgnoreCase)).Count(); 

     if (!model.Score.Equals(0)) 
     { 
      double percent = model.Score/model.Questions.Count(); 

      if (percent >= .8) 
      { 
       passed = true; 
      } 
     } 

     if (passed) 
     { 
      return View("/Views/Quiz/Passed.cshtml"); 
     } 
     else 
     { 
      return View("/Views/Quiz/Failed.cshtml"); 
     } 
    } 
    else 
    { 
     return View("/Views/Quiz/Quiz.cshtml", model); 
    } 
} 

查看

@model PAL.Intranet.Models.QuizModel 

<script> 
    $(document).ready(function() { 
     $("input:checked").removeAttr("checked"); 
    }); 
</script> 

<div class="grid"> 

    <h2>OSHA Quiz</h2> 
    <hr /> 

    <div class="align-center"> 

     @using (Html.BeginForm("OSHAQuiz", "Quiz", FormMethod.Post, new { id = "formShowLoading" })) 
     { 
      @Html.AntiForgeryToken() 
      @Html.ValidationSummary(true) 
      <div class="row cell"> 
       <div class="example bg-grayLighter" data-text="Directions"> 
        <ul class="simple-list"> 
         <li class="align-left">When you have made your selection for all 20 statements, click on the button 'Submit.'</li> 
         <li class="align-left">Mark 'True' or 'False' for each statement.</li> 
         <li class="align-left">You must score 80% (16 correct) to pass.</li> 
         <li class="align-left">You must fill in your full name to receive credit.</li> 
        </ul> 
       </div> 
      </div> 

      <div class="row cell"> 
       <div class="row cell"> 
        <div class="panel" data-role="panel"> 
         <div class="heading"> 
          <span class="title">Questions</span> 
         </div> 
         <div class="content"> 
          <ul class="numeric-list"> 
           @foreach (var question in Model.Questions) 
           { 
            <li> 
             <table class="table hovered" style="width: 100%;"> 
              <tr> 
               <td align="left">@question</td> 
               <td align="right" width="150px"> 
                <div class="align-center"> 
                 <label class="align-right input-control radio small-check"> 
                  @Html.RadioButtonFor(model => question.UserAnswer, true, new { Name = question.GroupName }) 
                  <span class="check"></span> 
                  <span class="caption">True</span> 
                 </label> 

                 <label class="align-right input-control radio small-check"> 
                  @Html.RadioButtonFor(model => question.UserAnswer, false, new { Name = question.GroupName }) 
                  <span class="check"></span> 
                  <span class="caption">False</span> 
                 </label> 
                </div> 
               </td> 
              </tr> 
             </table> 
            </li> 
           } 
          </ul> 
         </div> 
        </div> 
       </div> 
      </div> 

      <div class="row cell"> 
       <input type="submit" value="Submit" class="button info small-button" /> 
       <input type="reset" value="Reset" class="button primary small-button" /> 
      </div> 
     } 
    </div> 
</div> 

UPDATE

如果我在QuizName上使用HiddenFor,它會在後期回來,但模型的其餘部分是空的。

回答

2

在迭代要回發到模型的集合時,不能使用foreach;您必須使用帶索引的常規for語句才能讓Razor生成正確的字段名稱。

@for (var i = 0; i < Model.Questions.Count(); i++) 
{ 
    ... 
    @Html.RadioButtonFor(m => m.Questions[i].UserAnswer) 
} 

那麼,你的領域將有名稱的Questions[0].UserAnswer形式,其中ModelBinder的將承認並正確綁定到你的模型屬性。正如您現在使用foreach那樣,字段名稱將生成爲question.UserAnswer,模型綁定者不知道該如何處理和丟棄。

此外,FWIW,從您的模型實體中訪問您的上下文是一個非常糟糕的主意,更糟的是,如果你不注入它。將該邏輯移出實體並使用實用程序類或服務。另外,考慮一下依賴注入,因爲你的上下文是你想要的東西之一,並且只有每個請求的一個實例。如果你開始實例化同一個上下文的多個實例,那麼你的會有有問題。

+0

更改爲for循環,將db項移入控制器並退出模型。在帖子上的問題計數仍然是0.檢查頁面和收音機的ID是如下,但增加'id =「Questions_0__Answer」' – Tsukasa

+0

我得到它排序。我需要刪除我添加的我的羣組名稱。 – Tsukasa

1

問題是模型綁定將試圖將您的表單值綁定到您的模型上的屬性。它不會使用模型中的構造函數接受測驗名稱,它將使用默認的構造函數來實例化QuizModel對象。

我會考慮重構這個模型來移除你的EntityFramework依賴並找到一種新的方式來填充這些值。

當您完成使用它們時,您還應該在IDisposable對象上調用Dispose()方法。

我對如何解決這個問題的建議是使用您目前所需的QuizModel來幫助呈現您的視圖(即您的測驗問題和每個問題的可能答案)。

創建測驗提交

public class QuizSubmission 
{ 
    public string QuizName { get;set; } 

    public List<QuizQuestionResponse> Responses { get;set; } 
} 

public class QuizQuestionResponse 
{ 
    public int QuestionId { get;set; } 
    public int AnswerId { get;set; } 
} 

一個單獨的視圖模型在你的控制器動作,你應該綁定到QuizSubmission模型。

[HttpPost] 
public ActionResult OSHAQuiz(Models.QuizSubmission model) 
{ 

然後,您將能夠執行任何需要測驗提交(即數據訪問,驗證)的操作。

您還需要更新您的視圖,以便您的Html輸入元素具有正確的名稱屬性,模型綁定可以將每個問題和響應對正確綁定到您的響應列表中的QuizQuestionResponse項目。

+0

有什麼建議嗎? – Tsukasa

+0

我用建議更新了答案。 – Hopdizzle

+0

對不起,我還在學習。如果我使用QuizModel填充視圖,那麼當我提交表單時,如何返回不同的模型?你能舉一個例子來看看這個視圖嗎? – Tsukasa

相關問題