Q:

With MVC how can I bind a list of selected radio buttons?

I have some nested view models used to display a questionnaire driven from a database. Displaying the questions is straightforward but I don't know how to bind to the model or parse the selected answers on submit.  
My objects look like (pseudo): 
public class QuestionSheetViewModel(){
    public list<QuestionViewModel> Questions;
    public string UserName;
}

public class QuestionViewModel(){
    public int QuestionId;
    public string QuestionText;
    public dictionary<int, string> answers;
}

In my view I iterate over the questions, displaying each question text and then rendering each answer as a radio button:
    @Html.RadioButton(question.QuestionID, answer.Key());

By using question.questionId as the radio button name they are grouped together, limiting the user to one answer per question. 
When I submit, the model's list of questions is empty. Is it possible to automatically bind this to my view model? If not, what would I need to do to write something to parse the submitted form to find the selected answer for each question?
Thank you

A:

You could adapt your models a little bit to match your requirements:
public class QuestionSheetViewModel
{
    public List<QuestionViewModel> Questions { get; set; }
    public int QuestionId { get; set; }
}

public class QuestionViewModel
{
    public string QuestionText { get; set; }
    public int SelectedAnswerId { get; set; }
    public List<AnswerViewModel> Answers { get; set; }
}

public class AnswerViewModel
{
    public int AnswerId { get; set; }
    public string Text { get; set; }
}

and then have a controller:
public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new QuestionSheetViewModel
        {
            QuestionId = 1,
            Questions = new[] 
            { 
                new QuestionViewModel
                {
                    QuestionText = "question 1",
                    SelectedAnswerId = 2,
                    Answers = new[] 
                    {
                        new AnswerViewModel { AnswerId = 1, Text = "answer 1" },
                        new AnswerViewModel { AnswerId = 2, Text = "answer 2" },
                    }.ToList()
                },
                new QuestionViewModel
                {
                    QuestionText = "question 2",
                    SelectedAnswerId = 3,
                    Answers = new[] 
                    {
                        new AnswerViewModel { AnswerId = 3, Text = "answer 3" },
                        new AnswerViewModel { AnswerId = 4, Text = "answer 4" },
                    }.ToList()
                },
            }.ToList()
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(QuestionSheetViewModel model)
    {
        // When the form is submitted the model will be properly bound
        return View(model);
    }
}

with a corresponding view (~/Views/Home/Index.cshtml):
@model QuestionSheetViewModel

@using (Html.BeginForm())
{ 
    @Html.HiddenFor(x => x.QuestionId)
    <ul>
        @Html.EditorFor(x => x.Questions)
    </ul>
    <button type="submit">OK</button>
}

and a corresponding editor template which will automatically be rendered by convention for each question (~/Views/Shared/EditorTemplates/QuestionViewModel.cshtml):
@model QuestionViewModel

<li>
    @Html.DisplayFor(x => x.QuestionText)
    @Html.HiddenFor(x => x.QuestionText)
    <ul>
        @for (int i = 0; i < Model.Answers.Count; i++)
        {
            <li>
                @Html.HiddenFor(x => x.Answers[i].AnswerId)
                @Html.HiddenFor(x => x.Answers[i].Text)
                @Html.RadioButtonFor(x => x.SelectedAnswerId, Model.Answers[i].AnswerId)
                @Html.DisplayFor(x => x.Answers[i].Text)
            </li>
        }
    </ul>
</li>

