У меня есть базовое приложение asp.net C#, в котором есть форма для отправки некоторых данных в базу данных. В этой форме есть кнопка загрузки для загрузки файла.
Первоначально возникла проблема, заключающаяся в том, что: я не мог отправить форму без загрузки файла, это давало ошибку, поскольку [ссылка на объект не установлена на экземпляр объекта], что означает, что загрузка файла была обязательной перед отправкой форма, поэтому, чтобы решить эту проблему, я внес некоторые изменения в свой контроллер.
Теперь он отправляет форму, даже если я ничего не загружаю, но новая проблема заключается в том, что когда я загружаю файл и отправляю, он все равно успешно отправляет форму, но не загружает фактический файл.
Это модель:
public class Events
{
public int Id { get; set; }
public string title { get; set; }
public string amount { get; set; }
public string Finance_Approval { get; set; }
public DateTime date_time { get; set; }
public string file_one { get; set; }
[NotMapped]
public HttpPostedFileBase file1 { get; set; }
}
Это контроллер:
public ActionResult Index()
{
return View();
}
public ActionResult Request(Events e)
{
if (e.file_one==null)
{
_context.evt.Add(e);
_context.SaveChanges();
return Content("Added");
}
else
{
string filename = Path.GetFileNameWithoutExtension(e.file1.FileName);
string extension = Path.GetExtension(e.file1.FileName);
filename = filename + DateTime.Now.ToString("yymmssfff") + extension;
e.file_one = "PM_Files/" + filename;
filename = Path.Combine(Server.MapPath("~/PM_Files/"), filename);
e.file1.SaveAs(filename);
_context.evt.Add(e);
_context.SaveChanges();
return Content("Added");
}
}
А это вид бритвы:
@using (Html.BeginForm("Request", "Requester", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class = "form-group">
@Html.LabelFor(a => a.title)
@Html.TextBoxFor(a => a.title, new { @class = "form-control" })
</div>
<div class = "form-group">
@Html.LabelFor(a => a.amount)
@Html.TextBoxFor(a => a.amount, new { @class = "form-control" })
</div>
<div class = "form-group">
<label>Select the file word or pdf etc</label>
<input type = "file" name = "file1" />
</div>
<button class = "btn btn-primary">Request</button>
}
Вам понадобится этот: @Html.TextBoxFor(a => a.file_one, new { @class = "form-control", @readonly = "readonly" }) для хранения имени файла. В вашем текущем коде этого текстового поля не существует, поэтому имя файла никогда не сохраняется.
@StephenMuecke, вы хотите сказать, что мне нужно добавить класс управления формой в кнопку загрузки, и это решит проблему
Нет. У вас нет элемента <input> для file_one (да и не должно быть). Вам нужно проверить, является ли e.file1null, а не e.file_one` (и вы также проверяете ContentLength)
if (e.file_one==null) => это ваша проблема, потому что вы проверяете строку file_one. Вы должны проверить наличие файла, то есть HttpPostedFileBase.
if (e.file1 != null && e.file1.ContentLength > 0) { // save the file and set the value of file_one }; //add to context and save changesНо вы не должны использовать модели данных в своем представлении - обратитесь к Что такое ViewModel в MVC? (и удалите это свойство [NotMapped] из своей модели данных)
@TetsuyaYamamoto, спасибо, но когда я удаляю [Not Mapped] из модели, а затем добавляю миграцию, она генерирует ошибку как: Значение не может быть нулевым. Имя параметра: entitySet, и когда я пишу [Not Mapped] и добавляю миграцию, все работает нормально. Итак, каковы будут долгосрочные последствия, если я не удалю [Not Mapped], поскольку на данный момент все работает нормально. Но поскольку это приложение будет расти, мне нужно его удалить и как-то исправить ошибки?
Следует отметить, что модель данных и модель представления должны быть разделены, т.е. вы не должны использовать HttpPostedFileBase внутри класса сущности (в случае использования Code First / CF), а внутри класса модели представления. Процесс миграции CF влияет только на модель данных, но не на модель представления.
@TetsuyaYamamoto хммм верно, и поскольку на данный момент у меня нет модели просмотра, но, принимая во внимание ваши комментарии, я буду использовать модели просмотра для бритвенных представлений (файлы cshtml) позже. Итак, в целом ли я на правильном пути, или вы все еще чувствуете, что чего-то не хватает в более широкой картине? Итак, учитывая подход codefirst, мой код в порядке или вы все еще чувствуете, что мне нужно что-то из него переделать?





Точная проблема заключается в том, что вы проверяете нулевое значение для строкового свойства file_one, которое всегда имеет нулевое значение, потому что на странице просмотра с ним не связан элемент управления формой. Вместо этого вы должны проверить по HttpPostedFileBase:
[HttpPost]
public ActionResult Request(Events e)
{
if (e.file1 != null && e.file1.ContentLength > 0)
{
// save the file
return Content("Added");
}
else
{
// do something else
return Content("Added");
}
}
Если стандартная проверка HttpPostedFileBase, описанная выше, не работает, попробуйте Request.Files, чтобы получить информацию о файле:
[HttpPost]
public ActionResult Request(Events e)
{
if (Request.Files.Count > 0)
{
foreach (string files in Request.Files)
{
if (!string.IsNullOrEmpty(files))
{
// save the file
}
}
return Content("Added");
}
else
{
// do something else
return Content("Added");
}
}
Примечания:
1) Форма использует FormMethod.Post, поэтому действие контроллера должно использовать атрибут [HttpPost].
2) Атрибут [NotMapped] используется только для моделей данных, чтобы исключить отображение объекта на столбец в базе данных - он не используется в моделях просмотра, просто удалите его.
Ваш файл загружается, но у вас нет элемента управления формой для
file_one, поэтому он всегдаnull- ваш блокelseникогда не будет выполнен