In my MVC.NET project I used scaffolding templates. Initially ther were binded to one DTO model. Now I decided I wanted to link it to a ViewModel, because I have two multiselects I need to use to pass values. This is how my ViewModel looks:
public class CreateQuestionModel
{
public Question Question { get; set; }
public List<int> PoliticianIds { get; set; }
public List<int> TopicIds { get; set; }
}
My Create POST method that is getting a ViewModel from the View:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Regular")]
public ActionResult Create(CreateQuestionModel question)
{
if (ModelState.IsValid)
{
int id = WebSecurity.CurrentUserId;
manager.CreateQuestion(question.Question, id, question.PoliticianIds, question.TopicIds);
return RedirectToAction("Index");
}
return View(question);
}
And my Create.cshtml looks like this:
@model PoliticiOnline.Models.CreateQuestionModel
@{
ViewBag.Title = "Stel een vraag!";
}
<head>
<link rel="stylesheet" href="~/Content/Questions.css" type="text/css" />
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
<script src="@Url.Content("~/Scripts/Extra/Chosen/chosen.jquery.min.js")" type="text/javascript"></script>
<link rel="stylesheet" href="@Url.Content("~/Scripts/Extra/Chosen/chosen.min.css")" type="text/css">
<script src="@Url.Content("~/Scripts/Extra/select2-3.4.6/select2.min.js")" type="text/javascript"></script>
<link rel="stylesheet" href="@Url.Content("~/Scripts/Extra/select2-3.4.6/select2.css")" type="text/css">
</head>
<h2>Stel een vraag!</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Vraag</legend>
<div class="general-question">
<div class="editor-label">
@Html.LabelFor(model => model.Question.GeneralQuestion, "Algemene Vraag")
</div>
<div class="editor-field">
@Html.TextBox("Question.GeneralQuestion", new { @class = "general-question-edit" })
@Html.ValidationMessageFor(model => model.Question.GeneralQuestion)
</div>
</div>
<div id="geadresseerde-politici">
@Html.LabelFor(model => model.PoliticianIds, "Geadresseerde Politicians:")
@Html.ListBox("PoliticianIds", (MultiSelectList)ViewBag.Politicians, new { @id = "polDrop" })
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Question.Explanation, "Extra Uitleg")
</div>
<div class="editor-field">
@Html.TextArea("Question.Explanation", new { @class = "explanation-textarea-edit" })
@Html.ValidationMessageFor(model => model.Question.Explanation)
</div>
<div>
@Html.LabelFor(model => model.TopicIds, "Kies je thema's (maximum 2):")
@Html.ListBox("TopicIds", (MultiSelectList)ViewBag.Topics, new { @id = "select2select", @style = "width: 500px"})
</div>
<p>
<input type="submit" value="Indienen!" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript">
function format(topic) {
if (topic.css == 'optionGroup') {
return "<b>" + topic.text + "</b>";
} else {
return "<i> " + topic.text + "<i>";
}
}
$("#select2select").select2({
placeholder: "Selecteer een thema...",
maximumSelectionSize: 2,
formatResult: format,
escapeMarkup: function(m) {
return m;
}
});
</script>
The <script> section at the bottom doesn't really matter but I pasted it anyway, I'm using the jQuery plugin select2 for the ListBox.
This is a way of binding the textboxes and such to ViewModel properties, I found this on Stackoverflow. I also tried the classic way using @Html.EditorFor and @HtmlListBoxFor but the ViewModel's properties are always null.
What am I doing wrong/ what am I overlooking?
EDIT: I put a constructor in the ViewModel, now the ViewModel (CreateQuestionModel) is not null anymore, but the values are still default values (not the ones from the form). My ViewModel now looks like:
public class CreateQuestionModel
{
public Question Question { get; set; }
public List<int> PoliticianIds { get; set; }
public List<int> TopicIds { get; set; }
public CreateQuestionModel()
{
Question = new Question();
PoliticianIds = new List<int>();
TopicIds = new List<int>();
}
}
SOLUTION Commenter Yoeri provided the solution, you can see it below in my answer on this question!
{get; set;}for each property, e.g.TopicId,PoliticianId,Question