У меня есть @Html.BeginForm()
который привязан к ViewModel с именем CreateQuestionViewModel. Этот ViewModel выглядит так:
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; }
}
Когда я пытаюсь представить эту форму и создать экземпляр "Вопрос", список, если "Политики" и список "Темами" все работает. Когда я пытаюсь добавить файл с помощью <input type="file" name="File"/>
Я получаю сообщение об ошибке в полностью несвязанной строке в Create.cshtml, в строке, где я просматриваю foreach, чтобы заполнить <select>
список. Вот как выглядит форма в моем Create.cshtml:
@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 (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 (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>
}
Когда я использую это для создания Вопроса, все работает. Когда я пытаюсь добавить изображение, я получаю следующую ошибку на @foreach(...)
:
Ошибка на голландском языке, но переводит на: "Ссылка на объект не установлена на экземпляр объекта".
Я понятия не имею, что может быть неправильным, потому что я не получаю эту ошибку, когда я не добавляю файл, и нет никакой связи между добавлением файла и этим списком выбора...
Вот мой метод Create post в моем контроллере:
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);
}
Надеюсь, кто-то может мне помочь, потому что я совершенно озадачен...
РЕДАКТИРОВАТЬ
My Create Получить действие по запросу:
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();
}
Нашел мой ответ в этом потоке stackoverflow, который я раньше не нашел: ASP MVC Fail Upload HttpPostedFileBase - Null. в основном я ввел максимальный размер в web.config и использовал HttpPostedFileBase вместо HttpPostedFile. И, видимо, вы не можете использовать файл в ViewModel, поэтому вам нужно ввести его в качестве отдельного параметра в свой метод Create POST!