Emberfire
Emberfire

Reputation: 132

Unable to pass model from a post form to a controller

I have a problem (or I don't understand how forms work) with passing a model to a controller from a form. I have a model called EmptySurveyViewModel, that has a list consisting of EmptyQuestionViewModel. This question model has a property Answer that is empty, and is to be filled by the form. However, one survey has many questions, and at the end i want to pass a model to the controller that is a EmptySurveyViewModel, containing a list of EmptyQuestionViewModel, that each has the Answer property. That property can be filled in different ways, depending on the type of the question. My problem is that if I don't have the if statement (see below), all questions are displayed as radio style questions, and the model passed to the controller has only questions that have the Answer property filled. However, when i add the if (i intend to add other ifs, to catch all possible types), only some questions are listed, and when i submit the form, the model is completely empty (it's not null, but its property Questions is null. I think the first situation (without the if) can be dealt with by other logic later on, but returning an empty list can't. Why is that happening?

The Models:

public class EmptySurveyViewModel {
    //Something else here
    public List<EmptyQuestionViewModel> Questions { get; set; }
}

public class EmptyQuestionViewModel {
    //Something else here
    public string Answer { get; set; }
}

The View:

@model cq.Models.EmptySurveyViewModel

@using (Html.BeginForm("New", "Client", FormMethod.Post, new { role = "form" })) {
    for (int i = 0; i < Model.Count(); i++) {
        if (Model.Questions[i].Type == "Single choice") {
            @Html.RadioButtonFor(m => m.Questions[i].Answer, "foo")
            @Html.RadioButtonFor(m => m.Questions[i].Answer, "bar")
        }
        <br />
    }

    <input type="submit" value="submit" />
}

And the Action in the controller:

[HttpPost]
public ActionResult New(EmptySurveyViewModel survey) {
    //Do something with the survey here
}

Upvotes: 1

Views: 376

Answers (1)

Andrei
Andrei

Reputation: 56688

I believe this happens because you are skipping some of the indices. So when the data is posted back, you maybe post objects with indices 0, 1, 3, while 2 is missing because it happened to be filtered out by if. That breaks the continuity of the collection, something model binding cannot deal with. More details can be found in this Haacked post.

There are few possible solutions:

  1. Add other if's to cover all question types. That will make sure there are no skips.
  2. As Phil suggests in the post, add a hidden Index field to each question (also see this post). Note that this will cause only rendered questions to be posted back.
  3. Render filtered out questions as hidden inputs entirely, again avoiding skipping any of them.

Upvotes: 1

Related Questions