Asp.net-mvc – @html razor radio buttons mvc5

asp.net-mvcasp.net-mvc-5razor

here's my viewmodel

public class UserResponseModel
    {
        public string QuestionId { get; set;} 

        public string QuestionText { get; set; }

        public bool IsChecked { get; set; }


    }

so, for checkboxes this works beautifully

for (var i = 0; i < Model.UserResponses.Count; i++)
    {
        <div class="row">
            <div class="col-md-4">
                <div class="form-group">

                    @Html.HiddenFor(x => x.UserResponses[i].QuestionId)
                    @Html.CheckBoxFor(x => x.UserResponses[i].IsChecked) 

but for radio buttons this does not

 for (var i = 0; i < Model.UserResponses.Count; i++)
    {
        <div class="row">
            <div class="col-md-4">
                <div class="form-group">

                    @Html.HiddenFor(x => x.UserResponses[i].QuestionId)
                    @Html.RadioButtonFor(x => x.UserResponses[i].IsChecked, new { Name = "grp1" })
                    @Html.DisplayTextFor(x => x.UserResponses[i].QuestionText)

when i submit the form then IsChecked is always false – why – what am i missing – as I mentioned for checkboxes it works just fine. I did look at this question here but i'm not sure why radiobuttons require extra properties in the view model to hold the correct answer when checkboxes work transparently.

Edit: my question model is now as so

public class QuestionModel
    {
        public string WhichQuestion { get; set; }

        public int PointsObtained { get; set; }

        public bool CorrectAnswer { get; set; }

        private List<UserResponseModel> _userResponse;
        public List<UserResponseModel> UserResponses 
        {
            get { return _userResponse ?? (_userResponse = new List<UserResponseModel>()); }
            set { _userResponse = value; }
        }
    }

notice i have just added public bool CorrectAnswer { get; set; }

and in my view here's the code

for (var i = 0; i < Model.UserResponses.Count; i++)
    {
        <div class="row">
            <div class="col-md-4">
                <div class="form-group">

                    @Html.HiddenFor(x => x.UserResponses[i].QuestionId)
                    @Html.HiddenFor(x => x.CorrectAnswer)
                    @Html.HiddenFor(x => x.UserResponses[i].IsChecked)
                    @Html.RadioButtonFor(x => x.UserResponses[i].IsChecked, Model.CorrectAnswer, new { Name = "grp1" })

EDIT 2:

 @Html.HiddenFor(x => x.UserResponses[i].QuestionId)
                    @Html.HiddenFor(x => x.SelectedAnswerId)
                    @Html.HiddenFor(x => x.UserResponses[i].IsChecked)
                    @Html.RadioButtonFor(x => x.UserResponses[i].IsChecked,    Model.SelectedAnswerId, new { Name = "grp1" })

EDIT3:

public class QuestionModel
    {
        public string WhichQuestion { get; set; }

        public int PointsObtained { get; set; }



        private List<UserResponseModel> _userResponse;
        public List<UserResponseModel> UserResponses 
        {
            get { return _userResponse ?? (_userResponse = new List<UserResponseModel>()); }
            set { _userResponse = value; }
        }
    }

public class UserResponseModel
    {
        public string QuestionId { get; set;} 

        public string QuestionText { get; set; }



        public string SelectedQuestionId { get; set; }

    }

finally, my view

for (var i = 0; i < Model.UserResponses.Count; i++)
    {
        <div class="row">
            <div class="col-md-4">
                <div class="form-group">

                    @Html.HiddenFor(x => x.UserResponses[i].QuestionId)
                    @Html.RadioButtonFor(x => x.UserResponses[i].SelectedQuestionId, Model.UserResponses[i].QuestionId, new { Name = "grp1" })
                    @*@Html.CheckBoxFor(x => x.UserResponses[i].IsChecked)*@
                    @Html.DisplayTextFor(x => x.UserResponses[i].QuestionText)

EDIT4:so finally I'm getting some where
this works!!!

@Html.RadioButtonFor(x => x.UserResponses[i].SelectedQuestionId, Model.UserResponses[i].QuestionId)

I can now see the selectedquestionid populated in my httppost method but if I do this

@Html.RadioButtonFor(x => x.UserResponses[i].SelectedQuestionId, Model.UserResponses[i].QuestionId, new {Name="grp"}) 

then though i am able to select only one radiobutton the selectedquestionid is null on httppost – wierd

Best Answer

Radio buttons are not checkboxes. Radio buttons are grouped. This means that you should have a single property on your view model to hold the selected radio button value (as shown in the answer you linked to). With check boxes you could have multiple checkboxes selected, that's thy you are binding them to a collection of boolean values in your view model. Radio buttons on the other hand have only one possible selected value because they are mutually exclusive. That's why they should all be bound to a single property on your view model that will hold the selected radio button value.

So in your example of questions and answers, you have a question view model that will contain the question id and text as well as a list of possible answers. Each answer will be represented by an id and text. Your question view model will also have an answer property that will hold the selected answer radio button from the user. It is this property that you are going to bind all your radio button to. But with a different value.