I have a @Html.BeginForm()
which is binden to a ViewModel named CreateQuestionViewModel. This ViewModel looks like this:
public class CreateQuestionModel
{
public Question Question { get; set; }
public List<int> PoliticianIds { get; set; }
public List<int> TopicIds { get; set; }
public HttpPostedFile File { get; set; }
}
When I try to submit this form and create a Question instance, a list if PoliticianIds and a list of Topicids everything works. When I try and add a file using <input type="file" name="File"/>
I get an error at a completely unrelated line in the Create.cshtml, the line where I go through a foreach to populate a <select>
list. This is how the form in my Create.cshtml looks:
@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.EditorFor(model => model.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 Politici (maximum 5):")
<select name="PoliticianIds" id="polDrop" multiple style="width: 500px">
@foreach (var par in ((List<Party>)ViewBag.Parties))
{
<optgroup label="@par.Name (@par.FullName)">
@foreach (var pol in ((List<Politician>)par.Politicians))
{
@(ViewBag.CurrPol = pol)
<option value="@pol.UserId">@pol.FirstName @pol.LastName (@pol.Party.Name)</option>
}
</optgroup>
}
</select>
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Question.Explanation, "Extra Uitleg")
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.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):")
<select name="TopicIds" id="topDrop" multiple style="width: 500px">
@foreach (var top in ((List<Topic>)ViewBag.TopIds).Where(top => top.MainTopic == null))
{
<option value="@top.TopicId" class="optionGroup">@top.Name</option>
foreach (var subTopic in top.SubTopics)
{
<option value="@subTopic.TopicId" class="optionChild">@subTopic.Name</option>
}
}
</select>
</div>
@*<div>
@Html.LabelFor(model => model.TopicIds, "Kies je thema's (maximum 2):")
@Html.ListBoxFor(model => model.TopicIds, (MultiSelectList)ViewBag.Topics, new { @id = "select2select", @style = "width: 500px"})
</div>*@
@Html.Label("Voeg bestanden toe:")
<input type="file" name="createQuestionModel.File"/>
<p>
<input type="submit" value="Post!" />
</p>
</fieldset>
}
When I use this to create a Question everything works. When I try and add an image I get the following error at the @foreach(...)
line:
The error is in Dutch but translates to: "The object reference is not set to an instance of an object".
I have no idea what could be wrong because I don't get this error when I don't add a file, and there is no link between adding a file and this select list...
Here is my Create post method in my controller:
public ActionResult Create(CreateQuestionModel createQuestionModel)
{
if (ModelState.IsValid)
{
if (createQuestionModel.File != null && createQuestionModel.File.ContentLength > 0)
{
String fileName = Path.GetFileName(createQuestionModel.File.FileName);
String path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
createQuestionModel.File.SaveAs(path);
}
int id = WebSecurity.CurrentUserId;
manager.CreateQuestion(createQuestionModel.Question, id, createQuestionModel.PoliticianIds, createQuestionModel.TopicIds);
return RedirectToAction("Index", "Question", new { page = 1});
}
return View(createQuestionModel);
}
I hope someone can help me because I am absolutely puzzled...
EDIT
My Create Get action as requested:
public ActionResult Create(int userId = -1, int topicId = -1)
{
ViewBag.polIds = manager.GetAllPoliticians();
//ViewBag.Politicians = new MultiSelectList(manager.GetAllPoliticians(), "UserId", "FirstName");
if (userId > -1)
{
ViewBag.AddressedPolitcian = manager.GetPolitician(userId);
}
ViewBag.AddressedId = userId;
ViewBag.TopIds = manager.GetAllTopics();
//ViewBag.Topics = new MultiSelectList(manager.GetAllTopics(), "TopicId", "Name");
if (topicId > -1)
{
ViewBag.AddressedTopic = manager.GetTopic(topicId);
}
ViewBag.AddressedTopicId = topicId;
ViewBag.Parties = manager.GetAllParties();
return View();
}