0

I am using Razor with MVC 5,C# and a Model(ClassTestQuestion) that is related with another Model(ClassTestQuestionMc).

I Check some checkboxes and when I press submit button (finish) in controller I am getting back null object. How I can get back the the results?

In View:

   @model IEnumerable<OnlineLearningMVC.Models.ClassTestQuestion>

    @using (Html.BeginForm("FinishTest", "ClassTestQuestions", FormMethod.Post))
    {
        @Html.AntiForgeryToken()




        foreach (var item in Model)
        {
        @Html.DisplayFor(model => item.QuestionTx)
            @Html.HiddenFor(model => item.Id)
            @Html.HiddenFor(model => item.QuestionTx)
        <br/>
        <br />
        foreach (var Question in item.ClassTestQuestionMc)
            {
            @Html.DisplayFor(model => Question.AnswerTx)
                @Html.HiddenFor(model => Question.AnswerTx)
            @Html.CheckBoxFor(model => Question.IsChecked)
                @Html.HiddenFor(model => Question.IsChecked)


            }

     }


        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="FinishTest" class="btn btn-default" />
            </div>
        </div>

In controller:

 public ActionResult ClassCourseTest(int IdCourse)
        {
            var classTestQuestions = db.ClassTestQuestions.Include(c=>c.ClassTestQuestionMc).Include(c => c.ClassTest).Where(i=>i.ClassTestId== IdCourse);
            return View("ClassCourseTest", classTestQuestions.ToList());
        }

  [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult FinishTest(ClassTestQuestion classTestQuestion)
        {
 return View(classTestQuestion);
        }

My ClassTestQuestion Model:

namespace OnlineLearningMVC.Models
{
    public class ClassTestQuestion
    {
        public int Id { set; get; }


        public int ClassTestId { set; get; }

        public virtual ClassTest ClassTest { set; get; }

        [Required]
        [DisplayName("Question")]
        public string QuestionTx { set; get; }
        [Required]
        [DisplayName("Order")]
        public int OrderInt { get; set; }



        [DisplayName("Disabled")]
        public bool IsDeleted { set; get; }

        public string CreatedFrom { set; get; }

        public DateTime CreatedDate { set; get; }

        public string UpdatedFrom { set; get; }

        public DateTime UpdatedDate { set; get; }

      public virtual ICollection<ClassTestQuestionMc> ClassTestQuestionMc { set; get; }
    }

My ClassTestQuestionMc Model:

namespace OnlineLearningMVC.Models
{
    public class ClassTestQuestionMc
    {

        public int Id { set; get; }

        public int ClassTestQuestionId { set; get; }

        public virtual ClassTestQuestion ClassTestQuestion { set; get; }

        [Required]
        public string AnswerTx { set; get; }

        [DisplayName("Is Correct Answer?")]
        public bool IsCorrectAnswer { set; get; }

        public bool IsChecked { set; get; }

        [DisplayName("Disabled")]
        public bool IsDeleted { set; get; }

        public string CreatedFrom { set; get; }

        public DateTime CreatedDate { set; get; }

        public string UpdatedFrom { set; get; }

        public DateTime UpdatedDate { set; get; }
    }

enter image description here

What I see in Browser: enter image description here

Edit

I have try to change to IEnumerable : enter image description here

marios
  • 261
  • 8
  • 26
  • Your model in view is @model IEnumerable but you are expecting ClassTestQuestion in post action? It does not make sense. – wannadream Apr 25 '17 at 19:08
  • So what fix you propose ? – marios Apr 25 '17 at 19:15
  • If model in view is IEnumerable, then action should also expect it, 'FinishTest(IEnumerable)'. MVC will handle the list for you. – wannadream Apr 25 '17 at 19:17
  • I updated the question with image. Please have a look. – marios Apr 25 '17 at 19:24
  • I see. IEnumerable may not work in this scenario. Can you change it to List or IList? And I found another issue with your name convention. You need to see this article http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ and this stackoverflow thread http://stackoverflow.com/questions/17037858/how-to-pass-ienumerable-list-to-controller-in-mvc-including-checkbox-state. – wannadream Apr 25 '17 at 19:30
  • I have change the code to try the links you told me but still the same(getting null). I dont know what i am doing wrong... – marios Apr 25 '17 at 19:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/142660/discussion-between-wannadream-and-marios). – wannadream Apr 25 '17 at 19:52

1 Answers1

0

Change ICollection to IList for ClassTestQuestionMc. Then you need to follow array name convention here to make MVC work to handle the view model.

foreach (int i = 0; i < Model.Count; i++)
{
    @Html.DisplayFor(model => Model[i].QuestionTx)
    @Html.HiddenFor(model => Model[i].Id)
    @Html.HiddenFor(model => Model[i].QuestionTx)
    <br/>
    <br/>
    foreach (int j = 0; j < Model[i].ClassTestQuestionMc; j++)
    {
        @Html.DisplayFor(model => Model[i].ClassTestQuestionMc[j].AnswerTx)
        @Html.HiddenFor(model => Model[i].ClassTestQuestionMc[j].AnswerTx)
        @Html.CheckBoxFor(model => Model[i].ClassTestQuestionMc[j].IsChecked)
        @Html.HiddenFor(model => Model[i].ClassTestQuestionMc[j].IsChecked)
    }
}
wannadream
  • 1,669
  • 1
  • 12
  • 14