単純なビューでレンダリングする1つの文字列プロパティを持つ単純なモデルがあります。
ビューは次のようになります。
@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { encType="multipart/form-data" }))
{
@Html.TextBoxFor(m => m.FirstName)
<br /><br />
<input type="file" name="fileUpload" /><br /><br />
<input type="submit" value="submit me" name="submitme" id="submitme" />
}
コントローラはこれです:
[HttpPost]
public ActionResult UploadFile(UploadFileModel model, HttpPostedFileBase file)
{
// DO Stuff
return View(model);
}
さて、私が提出すると、モデルは読み込まれますが、HttpPostedFileBaseである2番目のパラメーターはnullです。ただし、Request.Filesを実行しているとき-投稿されているリクエストにファイルがあることを示しているようです。バインドする2番目のパラメーターを実際に取得するにはどうすればよいですか?
アップロードしたファイルを次のようにモデルに追加してみてください:
public class UploadFileModel
{
public UploadFileModel()
{
Files = new List<HttpPostedFileBase>();
}
public List<HttpPostedFileBase> 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)
<br /><br />
@Html.TextBoxFor(m => m.Files, new { type = "file", name = "Files" })<br /><br />
<input type="submit" value="submit me" name="submitme" id="submitme" />
}
その後、ファイルは次のようにポストバックされます。
public ActionResult UploadFile(UploadFileModel model)
{
var file = model.Files[0];
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" })
<input type="submit" value="Upload"
name="UploadButton" id="UploadButton" />
}
_
コントローラー:
_[HttpPost]
public ActionResult Submit(SomeModel model)
{
// do something with model.SomeFile
return View();
}
_
複数のファイルを処理する必要がある場合は、次のいずれかを実行できます。
public HttpPostedFileBase SomeFile
_プロパティを_public List<HttpPostedFileBase> SomeFiles
_のようなものに変更し、複数の@Html.TextBoxFor(m => m.SomeFile, new { type = "file" })
コントロールにまたがってそれらをすべてそのリスト内に含めます。追加情報が必要な場合は、このトピックで書いた このブログ投稿 をご覧ください。
名前をfile
からfileUpload
とenctype
に変更します
@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype="multipart/form-data" }))
{
@Html.TextBoxFor(m => m.FirstName)
<br /><br />
<input type="file" name="fileUpload" /><br /><br />
<input type="submit" value="submit me" name="submitme" id="submitme" />
}
[HttpPost]
public ActionResult UploadFile(UploadFileModel model, HttpPostedFileBase fileUpload)
{
// DO Stuff
return View(model);
}
または、(許容される場合)ファイルから[必須]検証アノテーションをモデルから削除し、コントローラーアクションでファイルを確認し、見つからない場合はエラーを追加します。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> 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.
}