带模型的mvc上传文件 – 第二个参数发布文件为空
我有一个带有1个字符串属性的简单模型,我在一个简单的视图上渲染。
视图如下所示:
@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { encType="multipart/form-data" })) { @Html.TextBoxFor(m => m.FirstName)
}
控制器是这样的:
[HttpPost] public ActionResult UploadFile(UploadFileModel model, HttpPostedFileBase file) { // DO Stuff return View(model); }
现在,当我提交时,模型DOES被填充但第二个参数是HttpPostedFileBase是null。 但是在执行Request.Files时 – 它似乎表明发布的请求中有一个文件。 我怎么能真正得到第二个参数绑定?
为什么不将上传的文件添加到模型中,如下所示:
public class UploadFileModel { public UploadFileModel() { Files = new List(); } public List Files { get; set; } public string FirstName { get; set; } // Rest of model details }
然后将您的视图更改为:
@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { encType="multipart/form-data" })) { @Html.TextBoxFor(m => m.FirstName)
@Html.TextBoxFor(m => m.Files, new { type = "file", name = "Files" })
}
然后您的文件将被回发如下:
public ActionResult UploadFile(UploadFileModel model) { var file = model.Files[0]; return View(model); }
将您的名称file
更改为fileUpload
并输入它的工作
@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype="multipart/form-data" })) { @Html.TextBoxFor(m => m.FirstName)
} [HttpPost] public ActionResult UploadFile(UploadFileModel model, HttpPostedFileBase fileUpload) { // DO Stuff return View(model); }
要处理单个文件输入,您可以在ViewModel中定义HttpPostedFileBase
属性:
public class SomeModel() { public SomeModel() { } public HttpPostedFileBase SomeFile { get; set; } }
然后按以下方式实现它:
视图:
@model SomeModel
@using (Html.BeginForm( "Submit", "Home", FormMethod.Post, new { enctype="multipart/form-data" })) { @Html.TextBoxFor(m => m.SomeFile, new { type = "file" }) }
控制器:
[HttpPost] public ActionResult Submit(SomeModel model) { // do something with model.SomeFile return View(); }
如果您需要处理多个文件,您可以:
- 创建多个属性并单独实现它们,就像上面那样;
- 将
public HttpPostedFileBase SomeFile
属性改为public List
,然后跨多个SomeFiles @Html.TextBoxFor(m => m.SomeFile, new { type = "file" })
控件将它们全部放在该列表中。
如果您需要其他信息,请查看我在该主题上撰写的博文 。
或者,(如果可接受)从模型中删除文件的[Required]validation注释,并在Controller操作中检查文件,如果找不到则添加错误:
[HttpPost] [ValidateAntiForgeryToken] public async Task ActionWithFileUpload(ViewModel viewModel) { if (ModelState.IsValid) { if (Request.Files.Count > 0) { var postedFile = Request.Files[0]; if (postedFile != null && postedFile.ContentLength > 0) { string imagesPath = HttpContext.Server.MapPath("~/Content/Images"); // Or file save folder, etc. string extension = Path.GetExtension(postedFile.FileName); string newFileName = $"NewFile{extension}"; string saveToPath = Path.Combine(imagesPath, newFileName); postedFile.SaveAs(saveToPath); } } else { ModelState.AddModelError(string.Empty, "File not selected."); } } return RedirectToAction("Index"); // Or return view, etc. }