0

I have the following class

public class QuestionAnswerPair
{
    public int QuestionID { get; set; }
    public int AnswerID { get; set; }
    public List<SelectListItem> Items { get; set; }
    public string Key => "A" + QuestionID;
}

And in my View I have the following inside my View

var answerPair = @Model.SelectedAnswers.First(x => x.QuestionID == item.ID);
<input type="hidden" name="SelectedAnswers.Index" value="@answerPair.Key">
@Html.Hidden("SelectedAnswers[" + answerPair.Key + "].QuestionID", answerPair.QuestionID, new { id = "SelectedAnswers_" + answerPair.Key + "__QuestionID" })
@Html.Hidden("SelectedAnswers[" + answerPair.Key + "].AnswerID", answerPair.AnswerID, new { id = "SelectedAnswers_" + answerPair.Key + "__QuestionID" })
@Html.DropDownList("SelectedAnswers[" + answerPair.Key + "].AnswerID", answerPair.Items, new { @class = "form-control", id = "SelectedAnswers_" + answerPair.Key + "__QuestionID" });

To my View I pass a List of QuestionAnswerPair and then I foreach through them and do the above piece of code, in the property Items I have the answers that come from the database, but I also have one line that is always 0 with the text No Sellection as the default if AnswerID is 0 but in the case where I have a value that is selected the DropDownList never Binds to that answer where if I had used DropDownListFor it did Bind But when I post back the selected answer is null, with the above code the selected answer posts back to the server and I can use it

I pass through the following Model which contains SelectedAnswers

public class GroupViewModel
{
    public List<InspectionQuestion> Questions { get; set; }
    public List<QuestionAnswerPair> SelectedAnswers { get; set; }

    public GroupViewModel(int groupId)
    {
        //DB Stuff to build SelectedAnswers
    }

    //For postback
    public GroupViewModel()
    {

    }
}

EDIT:

The following is what I tried with EditorTemplate

@for (int index = 0; index < Model.SelectedAnswers.Count; index++)
{
    var answer = Model.SelectedAnswers[index];
    if (answer.QuestionID == item.ID)
    {
        @Html.EditorFor(x => answer, "SelectedAnswers")
    }
}

Editor Template I have

@model InspectManagement.Models.QuestionAnswerPair


<td>
    @Html.HiddenFor(x => x.QuestionID)
    @Html.DropDownListFor(x => x.AnswerID, Model.Items, new {@class = "form-control"})
</td>

So my question is what is wrong with my View

Donald Jansen
  • 1,937
  • 4
  • 22
  • 41
  • What is your question? –  Jan 30 '16 at 11:03
  • What is wrong with my View – Donald Jansen Jan 30 '16 at 11:06
  • Lots :) Using a `foreach` loops is not the correct approach for generating form controls in a collection despite your hacks to try and make it work. Use a `for` loop (`SelectedAnswers` needs to be `IList`) or better, use a `EditorTemplate` for `QuestionAnswerPair` –  Jan 30 '16 at 11:09
  • And I suggest your look at the html your currently generating and then remove all the `new { id = "SelectedAnswers_" + answerPair.Key + "__xxxxx" }` code and inspect the html that generates :) –  Jan 30 '16 at 11:11
  • I have checked that, it generates exactly the same id which I specified – Donald Jansen Jan 30 '16 at 11:18
  • I know :) (so what is the point of you doing it all manually) –  Jan 30 '16 at 11:19
  • Also using `DropDownListFor` (Inside EditorTemplate ofcource) (As I stated in the question, works but then the postback is `null`) Hence why I use the above code then the postback is not null – Donald Jansen Jan 30 '16 at 11:28
  • It will not be null if you have generated it correctly. Show what you tried so we can fix it. –  Jan 30 '16 at 11:30
  • That's not an `EditorTemplate`. I will add an answer a bit later, but I suspect another problem you have is your `GroupViewModel` and the relationship between `InspectionQuestion`and `QuestionAnswerPair` –  Jan 30 '16 at 11:44
  • In fact I wont add an answer - the more I look at your code the more convinced your view model is wrong - especially the fact that you need to use `if (answer.QuestionID == item.ID)` in your view. You need a collection of `QuestionVM` where each `QuestionVM` contains a collection of `PossibleAnswers`. I suggest you start by looking at [this answer](http://stackoverflow.com/questions/28055287/asp-net-mvc-5-group-of-radio-buttons/28057533#28057533) –  Jan 30 '16 at 12:02

1 Answers1

0

Because the EditorFor worked with the binding I decided to go with that solution again and find a way to make the postback to work again (By not posting null) The first thing I noticed I had to change

@Html.EditorFor(x => answer, "SelectedAnswers")

To

@Html.EditorFor(x => answer, "SelectedAnswers", "SelectedAnswers[" + answer.Key + "]")

Then the Editor View I changed from

<td>
@Html.HiddenFor(x => x.QuestionID)
@Html.DropDownListFor(x => x.AnswerID, Model.Items, new {@class = "form-control"})
</td>

To

<td>
<input type="hidden" name="SelectedAnswers.Index" value="@Model.Key">
@Html.HiddenFor(x => x.QuestionID)
@Html.DropDownListFor(x => x.AnswerID, Model.Items, new {@class = "form-control"})
</td>

The folloing piece of code @Html.EditorFor(x => answer1, "SelectedAnswers", "SelectedAnswers[" + answer.Key + "]") generated my names correctly in the EditorView but it still posted null So I compared and noticed that <input type="hidden" name="SelectedAnswers.Index" value="xxx"> was missing so I added the line <input type="hidden" name="SelectedAnswers.Index" value="@Model.Key"> Now my post is working and my binding is working

Donald Jansen
  • 1,937
  • 4
  • 22
  • 41