Cómo persistir los datos del modelo cuando se publica un formulario

When form is showing initially then I show question and their answer. I show multiple radio button for answer. So user can select only one answer. The problem occurs when I submit my form and action method calls. I saw when form post then answer model is getting null. So guide me how to write code as a result answer model should not be null when form will post.

Here is full code. Please go through the code and if requires changes as a result answer model will not be null when form will be posted to action method.

my ViewModels code

namespace ViewModels
{
    public class Question
    {
        public int ID { set; get; }
        public string QuestionText { set; get; }

        public List<Answer> Answers { set; get; }
        [Required]
        public string SelectedAnswer { set; get; }

        public Question()
        {
            Answers = new List<Answer>();
        }
    }

    public class Answer
    {
        public int ID { set; get; }
        public string AnswerText { set; get; }
    }

    public class Evaluation
    {
        public List<Question> Questions { set; get; }
        public Evaluation()
        {
            Questions = new List<Question>();
        }
    }
}

controller code

 public ActionResult Index()
        {
            var evalVM = new Evaluation();

            //the below is hardcoded for DEMO. you may get the data from some  
            //other place and set the questions and answers

            var q1 = new Question { ID = 1, QuestionText = "What is your favourite language" };
            q1.Answers.Add(new Answer { ID = 12, AnswerText = "PHP" });
            q1.Answers.Add(new Answer { ID = 13, AnswerText = "ASP.NET" });
            q1.Answers.Add(new Answer { ID = 14, AnswerText = "Java" });
            evalVM.Questions.Add(q1);

            var q2 = new Question { ID = 2, QuestionText = "What is your favourite DB" };
            q2.Answers.Add(new Answer { ID = 16, AnswerText = "SQL Server" });
            q2.Answers.Add(new Answer { ID = 17, AnswerText = "MySQL" });
            q2.Answers.Add(new Answer { ID = 18, AnswerText = "Oracle" });
            evalVM.Questions.Add(q2);

            return View(evalVM);           
        }

 [HttpPost]
        public ActionResult Index(Evaluation model)
        {
            if (ModelState.IsValid)
            {
                foreach (var q in model.Questions)
                {
                    if(q.Answers==null)
                    {
                        // Answers is null
                    }
                    var qId = q.ID;
                    var selectedAnswer = q.SelectedAnswer;
                    // Save the data 

                }
                return RedirectToAction("ThankYou"); //PRG Pattern
            }
            //reload questions
            return View(model);
        }

index.cshtml code

@model ViewModels.Evaluation
<h2>Quiz 24</h2>
@using (Html.BeginForm())
{
    @Html.EditorFor(x=>x.Questions)
    <input type="submit" />
}

and view code which is stored in EditorTemplates folder

@model ViewModels.Question
<div>
    @Html.HiddenFor(x=>x.ID)
    <h3> @Model.QuestionText </h3>

    @foreach (var a in Model.Answers)
    {
        <p>
            @Html.RadioButtonFor(b=>b.SelectedAnswer,a.ID)  @a.AnswerText 
        </p>

    }
</div>

el problema esta aqui

 [HttpPost]
        public ActionResult Index(Evaluation model)
        {
            if (ModelState.IsValid)
            {
                foreach (var q in model.Questions)
                {
                    if(q.Answers==null)
                    {
                        // Answers is null
                    }
                    var qId = q.ID;
                    var selectedAnswer = q.SelectedAnswer;
                    // Save the data 

                }
                return RedirectToAction("ThankYou"); //PRG Pattern
            }
            //reload questions
            return View(model);
        }

q.Answers==null is getting null when i post the form. i like to know the trick that how to write code in such a way when form will be post to action then Answers should be null. many guy told me that i need to rebuild the model manually because Answers will be always null. is there any no mechanism in MVC to persist all the data and properly De-serialize it to model when form will be posted.

preguntado el 22 de septiembre de 13 a las 09:09

1 Respuestas

AnswerText Normally I would recommend using another nested Editor Template para Answer model, but in this case it will cause issues to properly construct the radio-button group and aftwerwards retrieve the value of SelectedAnswer. As a simple solution I would adapt the Editor Template por Question model in the following way:

<div>
    @Html.HiddenFor(x=>x.ID)
    <h3> @Model.QuestionText </h3>
    <div>
        @for (int i = 0; i < Model.Answers.Count; i++)
        {
            <p>
                @Html.RadioButtonFor(model => model.SelectedAnswer, Model.Answers[i].AnswerText  @Model.Answers[i].AnswerText
                @Html.HiddenFor(model => model.Answers[i].ID)
                @Html.HiddenFor(model => model.Answers[i].AnswerText)
            </p>
        }
    </div>
</div>

This will create the following HTML (skipped not-relevant attributes):

<input type="radio" name="Questions[0].SelectedAnswer" ...>
<input type="hidden" name="Questions[0].Answers[0].ID" ...>
<input type="hidden" name="Questions[0].Answers[0].AnswerText" ...>

Output will allow MVC to properly reconstruct the Answer colección.

Noticias

In your original code you were looking for the Answer.AnswerText, so I've updated the code to include it instead of the Answer.ID.

Espero que esto ayude.

Respondido el 22 de Septiembre de 13 a las 12:09

thanks for the answer but i could not understand how to restructure my full code like (controller,view etc) the reason i am new in MVC. just started to walk. so what u r trying to say not very clear to me. it will be huge help if you write a full code form including view, controller & all other instruction in detail. thanks - Mou

I only adapted the part starting from and view code which is stored in EditorTemplates folder, just replace it with my first code-sample and everything else should stay as it is. - MonkeyCoder

ok i will try and if any problem occur then i will let u know and post the whole code again. the code u write that does solve my problem. actually my problem is that when i am submitting form then asnwer is getting null. - Mou

u render also answer id & text in hidden field also along with radio button but u did not explain why u r rendering hidden fields for answer id & text having same name or id of radio button. radio button is not capable of sending data to server when form submit. please guide me because i am NewBie......thanks - Mou

here u use for (int i = 0; i < Model.Answers.Count; i++) instead of foreach......any special reason there for which u use for ? can't i use here foreach ? - Mou

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.