Cómo persistir los datos del modelo cuando se publica un formulario
Frecuentes
Visto 1,858 veces
-1
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.
1 Respuestas
0
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
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas asp.net-mvc-3 or haz tu propia pregunta.
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. - MonkeyCoderok 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