2015-07-01 37 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

相关问题