none
ASP.NET MVCでのファイルアップロードについて RRS feed

  • 質問

  • お世話になっております。

    ASP.NET MVCでファイルアップロード機能を実装しましたが

    コントローラーの引数:UploadModels model内のuploadfileの値がnullになってしまいます。

    下記を試していますが、うまく動きません。

    ・enctype = "multipart/form-data"を指定

    ・バインドのためにモデル、ビューで同名の「uploadfile」を使用

    すみませんがどなたか原因に心当たりある方はご教授いただけないでしょうか。

    コントローラー:

            [HttpPost]
            public ActionResult Upload(UploadModels model)
            {
                return View();
            }

    モデル:

        public class UploadModels
        {
            public HttpPostedFileBase uploadfile { get; set; }
        }

    ビュー:

    @using (Html.BeginForm("Upload", "SbUpdateFiles", FormMethod.Post,
                    new { enctype = "multipart/form-data" }))
    {
        <input type="file" name="uploadfile" />
        <button type="submit"> UPLOAD</button>
    }


    • 編集済み ganmo1127 2018年6月19日 7:14
    2018年6月19日 7:13

回答

  • 返信ありがとうございます。

    どうやら解決できました。

    Coreでファイルアップロードする際はHttpPostedFileBaseではなく、IFormFileインターフェースを使用するのが正しかったようです。(昨日のやりとりで 本当にCoreでの実装方法になってるかな? と思い確認してみました。)

    ↓のアセンブリを使うみたいですね。。

    using Microsoft.AspNetCore.Mvc;

    ご回答いただきありがとうございました m-(_ _)-m

    以下ソースです。

    参考:https://docs.microsoft.com/ja-jp/aspnet/core/mvc/models/file-uploads?view=aspnetcore-2.1

    ※モデルは必要なし

    Views/SbUpdateFiles/Create.cshtml

    <form method="post" enctype="multipart/form-data" asp-controller="SbUpdateFiles" asp-action="Upload"> <div class="form-group"> <div class="col-md-10"> <p>Upload one or more files using this form:</p> <input type="file" name="files" multiple /> </div> </div> <div class="form-group"> <div class="col-md-10"> <input type="submit" value="Upload" /> </div> </div> </form>

    Controllers/SbUpdateFilesController.cs

    using Microsoft.AspNetCore.Http;

    public class SbUpdateFilesController : Controller { [HttpPost("SbUpdateFiles")] public async Task<IActionResult> Upload(List<IFormFile> files) { long size = files.Sum(f => f.Length); // full path to file in temp location var filePath = Path.GetTempFileName(); foreach (var formFile in files) { if (formFile.Length > 0) { using (var stream = new FileStream(filePath, FileMode.Create)) { await formFile.CopyToAsync(stream); } } } // process uploaded files // Don't rely on or trust the FileName property without validation. return Ok(new { count = files.Count, size, filePath }); } }






    • 回答としてマーク ganmo1127 2018年6月20日 6:28
    • 編集済み ganmo1127 2018年6月20日 6:36
    2018年6月20日 6:25

すべての返信

  • 開発環境(OS, .NET, MVC, IIS, Visual Studio のバージョン、ブラウザは何かなど)を書いてください。

    回答者の方でもコピペすれば問題を再現できる必要最低限かつ完全な View と Controller のコードをアップしてください。

    Fiddler などのキャプチャツールを使ってブラウザからファイルが期待通りの内容で送信されているか確認してください。

    2018年6月19日 9:56
  • 返信ありがとうございます。

    Windows10

    ASP.NET Core Webアプリケーション(.NET Framework)

    IIS Express

    Microsoft visual Studio  Community 2017

    GoogleChrome

    を使用しています。

    Fiddlerで試していませんでしたので、確認してみます。

    また、下記がコードになります。

    よろしくお願いいたします。

    コントローラー:

    Controllers/SbUpdateFilesController.cs

    using [プロジェクト名].Models;
    
    namespace [プロジェクト名].Controllers
    {
        public class SbUpdateFilesController : Controller
        {
            // GET: SbUpdateFiles/Create
            public IActionResult Create()
            {
                return View();
            }
    
            [HttpPost]
            public ActionResult Upload(UploadModels model)
            {
                return View();
            }
        }
    }

    モデル:

    Models/UploadModels.cs

    using System.Web;
    
    namespace [プロジェクト名].Models
    {
        public class UploadModels
        {
            public HttpPostedFileBase uploadfile { get; set; }
        }
    }

    ビュー:

    Views/SbUpdateFiles/Create.cshtml

    (コードは上記質問の@using~のみ)



    • 編集済み ganmo1127 2018年6月19日 10:22
    2018年6月19日 10:15
  • 追記:

    Fiddlerで確認いたしました。

    意図したデータはpostされているように見えます。

    【抜粋】

    ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

    Content-Dis-data; name="uploadfile"; filename="設定マーク.jpg"
    Content-Type: image/jpeg

    ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

    【Rawタブをコピペ】

    POST http://localhost:58087/SbUpdateFiles/Upload HTTP/1.1
    Host: localhost:58087
    Connection: keep-alive
    Content-Length: 3241
    Cache-Control: max-age=0
    Origin: http://localhost:58087
    Upgrade-Insecure-Requests: 1
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhQQ2nhR1IGJBqAxN
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    Referer: http://localhost:58087/SbUpdateFiles/Create
    Accept-Encoding: gzip, deflate, br
    Accept-Language: ja,en-US;q=0.9,en;q=0.8
    Cookie: .AspNetCore.Antiforgery.2G4y6gr2hio=CfDJ8HQaJJc7_H5Isedby44hM9w7FPRRNMKpyWnu7R-T1YxKFHk2sD_59wN2EoDTJW_M1V88fDC7DGsqFvyGRs5NYgfmEUYnjbvnMcx-2c6ZhppPA9-sFfthPUXrbCVGH6FJZYj3hJvSB67tVLDph19Mat4

    ------WebKitFormBoundaryhQQ2nhR1IGJBqAxN
    Content-Dis-data; name="uploadfile"; filename="設定マーク.jpg"
    Content-Type: image/jpeg

     PNG
    
       
    IHDR            m"H   cPLTEKKK   GGGEEEBBBbbb   QQQ   ttt        񡡡      TTT      lll  ۗ  iii  ì        yyy]]]   999    n v  
    .IDATx  邲  Ls  +     O   e
    e  1 dx X M U  X 63 b  0u%   ih F   I a  Q4J    !~n F d    N $  #ܛ  &   $ L 5 )  0 #  0Ix A  d &  
        `/  c „         C8E  '܁    B 0V9_  & o + V X  J y   >& ש  J Z 0    =n    ǾIz  '   6 j' `
     - 0  $h # 0 03M  
    1c yz  ^P hsu  $  aµ'o.K u6("Hx ɯ䣨 0 nwW#  Z 6 Q J m  {`  0   B T @(  @j  f PW / &%h   V)n*  { "     >Ѕ _  {GXr   &  0 Z i-   2  E  x }UȦ!% _Eo  B  o  
    q  7  2B`  ?  ) HH*hG   J     s\qu@  v 
    v Kz  4Ą |    sQr *  1 F+   *$ &  ~ ?  S  w )    
    8 K6
     WCkm &X Gu     ]x ݸ Zb h 
       }   ڽS c  M ~r  o >% 4   U F f c  z%4F y 
    d     VT. ` Sh 6  
    [#Eն
      J  # )  +ם4= :ܵ    w    y. < 
     0 3 )   g w   ' aB ==/ ' Q ü   % 1 g   g>J Y꬧M/w @  Z:  s í     <o
      v #x Q  {    I  w
       +m~µ   Y  n+H`   c  SE7   N %<_ t 5Qb    /dF`  3Eb    ] ~  Z♓ - B   %tA  v  J ! 1 x5 A @   o z[t  ^c  y "  z 't0Ѓ& a 1 $y \ aT Љ6s  ި n[   -E \Q  x} X    3 2   Cx   @H)e u5V 0<sIZA n  H ;" =8 % d\ .-  v[ Q  QYn       hJH } _J [ N }ȋ V     U$6\  4 '.Y  aKQ杦     a   c   %cCT\$_ & ݂   3? f E DzJ0 ݘ!  o$ޠ  (F x   j b N܎    #  @ ƽ c  #4E  Rl/1cީܫ/8 # N  _ y N   #"  0Q~ . v (#2 p
     J1       H  D L = t :E  V] 0 R ,WBiW zȥ .a y^\  J5(p%p  $ i ,˸ +  0
     0:-; v NպSP q   {   ;A ժ   ~ q :  0˛}Щ^t ; Bf    z  7b =X 풾 =F m ~',| --qP  J,K .J   _   bp     Z-Y  646 0Y  . O   ^      u ^y-  % b A j S  !WGi Ӽ  7  49Tތs!ܕ B \  z  f;   S 2  #1'   v?ęyc/
     r 2 >D /   > '8x@J8     ^ k ;֔ހP[ c  򣅇  4  _ ~g  Z   ch   
     R ?Ӽ        C     i   f   ~   -f {   PGR     ]f  
      6 b s,   4  x ^  D
    ˲ 6  M     w  ?  
    b  Ϸx      w   C sH Ӹ^   ~ \n   gXS=Q l]       - E    e} /  Y_s    3 (. U      A+    > 9 M ]b| &  &  u   6 +} B` z o X   l J c d   rۿ e w   v  k  h 7,    ߒ}    M 7 .   V }1
    fiӶI06p 5RTmۨ$P   ?T@t7 ~        u^v x     ;~ N K  ) 'MV      } O  (    L       q,#=.v  =/ |^L (  A 4  ([  X  ~HX-K  _bkb&   C  (9(^0)9$CS  w@hi ڼ= o   O\)ſ C   V - K  d~
       ث\ 
    ƵAt =' U#"
     "Y  gL`
    : 䀀   i Z  Y ɛ a0     8 } {} `?YQ q   D  Û R_ 
    > K3 "   mB   nĴ = I l-
          x  Mc#m g  f ?  m Gp  - _ɛ J m   #`  w H '   ɒ c Ǘ^m4 !!e  (  + ]|) 6 #  / y  Yp K   ӳ O  88_ \ M t 6  Iz  d  @      5   : :  } g)v R   a H1wS PI; ]E†d    ?^ )  > r. U| C8E @ ]    @g9   [ IB ౾ C2I„SK   ! " 3  J :ʞ d M   F (!x05z,5K  3  & (  rC   \gL:Y+s Z # 8  e є      IEND B` 
    ------WebKitFormBoundaryhQQ2nhR1IGJBqAxN
    Content-Dis-data; name="__RequestVerificationToken"

    CfDJ8HQaJJc7_H5Isedby44hM9y0KZTQEAhRMCbjxMBac0ujiN372olLZEovynK90vBXSZ8nfvEnn1UKBVJKe6dhwM4-vk8uujSq6zG1YJVPPnD16FncU-HN_BT_RzctUsuYHfGxs1_saZA0ZXHLCidAhe8
    ------WebKitFormBoundaryhQQ2nhR1IGJBqAxN--

    2018年6月19日 10:54
  • > ASP.NET Core Webアプリケーション(.NET Framework)

    Core でしたか・・・ Core ではお手上げです。

    自分の環境は Visual Studio Community 2015 ですので最新版 (v2.1?) は検証する手段もありません。お役に立てずすみませんが、他の方の回答をお待ちください。

    2018年6月19日 12:08
  • 最初に記載しておくべきでした、、お時間取らせてしまいすみません。

    回答いただきありがとうございます。

    ほかの方の回答を待つことにいたします。m-(_ _)-m

    2018年6月19日 15:26
  • 参考にならないかもしれませんが、VS2015 Community で作った Core ではない MVC5 アプリで、問題なく POST されたファイルを取得できるサンプルをアップしておきます。

    質問者さんのコードとの主な違いは (1) View の @model の定義、(2) アクションメソッド名を共通にして View を共有したことです(アクションメソッドに対応する View が存在しないとサーバーエラーになる。Core は不明)・・・です。

    View

    @model Mvc5App.Controllers.UploadModels
    
    @{
        ViewBag.Title = "Upload";
    }
    
    <h2>Upload</h2>
    
    @using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        <input type="file" name="uploadfile" />
        <button type="submit">UPLOAD</button>
    }

    Controller / Action Method / Model

    Model を Controller のファイルに含めたのは単に分けるのが面倒だったから。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace Mvc5App.Controllers
    {
        public class HomeController : Controller
        {        
            // ・・・中略・・・
    
            public ActionResult Upload()
            {
                return View();
            }
    
            [HttpPost]
            public ActionResult Upload(UploadModels model)
            {
                var postedFile = model.Uploadfile;
                if (postedFile.ContentLength > 0)
                {
                    var filename = Path.GetFileName(postedFile.FileName);
                }
                return View();
            }
    
        }
    
        public class UploadModels
        {
            public HttpPostedFileBase Uploadfile { get; set; }
        }
    }

    Fiddler で見た POST されたサンプル .jpg ファイル

    アクションメソッドの引数にモデルバインドされている

    2018年6月20日 1:58
  • 返信ありがとうございます。

    どうやら解決できました。

    Coreでファイルアップロードする際はHttpPostedFileBaseではなく、IFormFileインターフェースを使用するのが正しかったようです。(昨日のやりとりで 本当にCoreでの実装方法になってるかな? と思い確認してみました。)

    ↓のアセンブリを使うみたいですね。。

    using Microsoft.AspNetCore.Mvc;

    ご回答いただきありがとうございました m-(_ _)-m

    以下ソースです。

    参考:https://docs.microsoft.com/ja-jp/aspnet/core/mvc/models/file-uploads?view=aspnetcore-2.1

    ※モデルは必要なし

    Views/SbUpdateFiles/Create.cshtml

    <form method="post" enctype="multipart/form-data" asp-controller="SbUpdateFiles" asp-action="Upload"> <div class="form-group"> <div class="col-md-10"> <p>Upload one or more files using this form:</p> <input type="file" name="files" multiple /> </div> </div> <div class="form-group"> <div class="col-md-10"> <input type="submit" value="Upload" /> </div> </div> </form>

    Controllers/SbUpdateFilesController.cs

    using Microsoft.AspNetCore.Http;

    public class SbUpdateFilesController : Controller { [HttpPost("SbUpdateFiles")] public async Task<IActionResult> Upload(List<IFormFile> files) { long size = files.Sum(f => f.Length); // full path to file in temp location var filePath = Path.GetTempFileName(); foreach (var formFile in files) { if (formFile.Length > 0) { using (var stream = new FileStream(filePath, FileMode.Create)) { await formFile.CopyToAsync(stream); } } } // process uploaded files // Don't rely on or trust the FileName property without validation. return Ok(new { count = files.Count, size, filePath }); } }






    • 回答としてマーク ganmo1127 2018年6月20日 6:28
    • 編集済み ganmo1127 2018年6月20日 6:36
    2018年6月20日 6:25