razor - binding issue with radio button

2019-03-04 04:33发布

问题:

I am struggling to bind ans for radio button i am doing a small project. I have two model Question and Answer. What i want to achive for pull a list of question and base on setting the user will have multiple choice or type the answer in a text box. with the radio button i cant seem to bind the ans it geting a null object can someone please point me in the right direction.

@model List<Question.Models.Questionnaire>


@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Question List</h2>

@using(Html.BeginForm("GetAnswer","Home")) {


for(int i = 0;i < Model.Count;i++) {

    <text>@Model[i].Questions</text> <br />

    @Html.HiddenFor(M => M[i].QuestionID)

    if (@Model[i].MultipleChoice == false){

        @Html.TextBoxFor(M => M[i].Response) <br />

    } else {

          for(int j = 0;j < Model[i].GetAns.Count;j++) {
               <div>
              <text>@Model[i].GetAns[j].AnsText</text>
              @Html.RadioButtonFor(M => Model[i].QuestionID, Model[i].GetAns[j].AnswerId) <br />
               </div>
        }

        /*
        foreach(var ansOption in PossibleAns) {
          <div>
           @Html.RadioButtonFor(model => Model[i].QuestionID, ansOption.AnswerId)
           @Html.Label(ansOption.AnsText)
          </div>  
        }
         * */
        <br />
    }
}
<br />

  <input type="submit" name="submit" />

}

public class Questionnaire
{
    public Questionnaire() {
    }

    public int QuestionID  { get; set;}
    public string Title    { get; set;}
    public string Questions{ get; set;}
    public string Response { get; set;}
    public bool MultipleChoice { get; set;}

    public List<Answer> GetAns { set; get;}

}

 public class Answer  
 {
    public int AnswerId { get; set; }
    public string AnsText { get;set;}
    public Questionnaire Ques { get; set;}
 }


public class QuestionRepository
{

    public List<Questionnaire>
         GetQuestionnaire() {
             List<Questionnaire> q = new List<Questionnaire>();
             q.Add(new Questionnaire() {
                 QuestionID = 11, Title = "Geo", Questions = "Capital of England?", GetAns = GetAns(), MultipleChoice = true
             });
             q.Add(new Questionnaire() {
                 QuestionID = 22, Title = "Geo", Questions = "Capital of France", GetAns = GetAns()
             });
             q.Add(new Questionnaire() {
                 QuestionID = 33, Title = "Geo", Questions = "Capital of Cuba", GetAns = GetAns()
             });
             return q;
    }

    public List<Answer> GetAns() {

        List<Answer> ans = new List<Answer>();
        ans.Add(new Answer() {
            AnswerId = 1, AnsText = "london", Ques = new Questionnaire() {
                QuestionID = 11
            }
        });
        ans.Add(new Answer() {
            AnswerId = 2, AnsText = "paris", Ques = new Questionnaire() {
                QuestionID = 22
            }
        });
        ans.Add(new Answer() {
            AnswerId = 3, AnsText = "Havana", Ques = new Questionnaire() {
                QuestionID = 33
            }
        });

        return ans;
    }



}

回答1:

Your radio buttons are binding to property QuestionID (and your overwriting the value of QuestionID with the selected AnswerID so nothing would make sense when you post back. Your class and property naming makes it a difficult to understand, but if your wanting to select one answer from a group of possible answers, then property GetAns just needs to be List<string> and then bind the selected answer to property Response. For example, for the first question ("Capital of England?") where you seem to be wanting the choices to be "london", "paris" or "Havana", then the question should have a property

public List<string> PossibleAnswers { get; set; }

and in the controller

model.Questions[0].PossibleAnswers = new List<string>() { "london", "paris", "Havana" }

and in the view

for(int i = 0; i < Model.Count; i++) {
{

  if (@Model[i].MultipleChoice)
  {
    // Radio buttons for multiple choice
    foreach(string option in Model[i].PossibleAnswers)
    {
      <label>   
        @Html.RadioButtonFor(m => m[i].Response, option})
        <span>@option</span>
      </label>
    }
  }
  else
  {
    // Textbox for answer
    @Html.TextBoxFor(m => m[i].Response)
  }
}

When you post back, the Response property will contain the text of the answer, either what been entered in the text box, or one of the possible answers if its a multiple choice question.

However, I suggest you need to rethink most of what your doing here, especially if your wanting to bind to an ID property of a multiple choice answer.