hi guys i am having trouble with my mvc app. its a simple quiz app and i am stuck at creating create view for question model.
I have Question and Option model with appropriate view models(in my case they are QustionDTO and OptionDTO) and i want to make cshtml create view for Question with list of Options.like this but when i submit form, my list of options is null. this is my Question and Option model
public class Question
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string QuestionText { get; set; }
public virtual ICollection<Option> Options { get; set; }
}
public class Option
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[Display(Name ="Answer text")]
public string OptionText { get; set; }
[Required]
public bool IsCorrect { get; set; }
}
this is my DTO models
public class QuestionDTO
{
public int Id { get; set; }
public string QuestionText { get; set; }
public List<OptionDTO> Options { get; set; }
}
public class OptionDTO
{
public int Id { get; set; }
public string OptionText { get; set; }
public bool IsCorrect { get; set; }
}
and this is my view with editor template located in "~/views/shared/editortemplate/OptionDTO.cshtml"
@model Quiz.BusinessEntites.QuestionDTO
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>QuestionDTO</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.QuestionText, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.QuestionText, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuestionText, "", new { @class = "text-danger" })
</div>
</div>
<table class="table" style="width:50%">
@for (int i = 0; i < 3; i++)
{
@Html.EditorFor(model=>model.Options[i])
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
this is OptionDTO editor template
@using Quiz.BusinessEntites
@model Quiz.BusinessEntites.OptionDTO
<tr>
<th class="col-md-2">
@Html.DisplayNameFor(m => m.OptionText)
</th>
<th class="col-md-2">
@Html.DisplayNameFor(m => m.IsCorrect)
</th>
</tr>
<tr>
<td class="col-md-2">
@Html.EditorFor(m => m.OptionText)
</td>
<td class="col-md-2">
@Html.EditorFor(m => m.IsCorrect)
</td>
</tr>
from the image above u can see that options list is null. if u have any suggestion it will be appreciated.
In your http post action method, the Bind
attribute with Include
list is telling the Model binder to bind only "Id","QuestionText" and "IsCorrect" properties of QuestionDto
object from the posted form data. So the model binder will not bind the Options
property value.
Remove the Bind
attribute from your Http post action method.
There is no need to use the Bind attribute if your view model is specific to your view, means you have only properties needed for your view (In your case it looks like so)
public ActionResult Create(QuestionDTO model)
{
// to do :return something
}
If you want to use a non view specific view model, but still want to use Bind
attribute to specify only subset of properties, Include just those properties. In your case, your code will be like
public ActionResult Create([Bind(Include="Id,QuestionText",Options"] QuestionDTO model)
{
// to do :return something
}
Also you should editer template view should be in a directory called EditorTemplates , not EditorTemplate