web-dev-qa-db-ja.com

モデル付きのmvcアップロードファイル-2番目のパラメーターのポストされたファイルがnullです

単純なビューでレンダリングする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番目のパラメーターを実際に取得するにはどうすればよいですか?

19
Ahmed ilyas

アップロードしたファイルを次のようにモデルに追加してみてください:

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);
}
38
hutchonoid

単一のファイル入力を処理するには、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" })コントロールにまたがってそれらをすべてそのリスト内に含めます。

追加情報が必要な場合は、このトピックで書いた このブログ投稿 をご覧ください。

9
Darkseal

名前をfileからfileUploadenctypeに変更します

@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);
}
6
Jaimin

または、(許容される場合)ファイルから[必須]検証アノテーションをモデルから削除し、コントローラーアクションでファイルを確認し、見つからない場合はエラーを追加します。

[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.
}
0
Tim Tyler