

ASP.NET MVC C#  
apiControllerを継承して、WebAPIを作成しています。

以前開発時は、1種類のバイナリデータをリクエストのボディに含めてPOSTしておりました。  
curl --data-binary @"ファイル名"  
controller post(byte[] data)

2種類のバイナリデータ（pemファイルとdatファイル）をPOSTしたいです。  
curlとControllerはどのように実装したらよろしいでしょうか。  
（RESTAPIとして使用）


CC BY-SA 4.0
2020-03-21T04:03:27.150
64008
2022-11-04T02:01:50.183
38311
question
c# asp.net curl
ASP.NET　CURL　バイナリデータを複数アップロード


> 2種類のバイナリデータ（pemファイルとdatファイル）をPOSTしたいです。  
>  curlとControllerはどのように実装したらよろしいでしょうか。

以前自分の Windows 10 の開発マシンに作った ASP.NET MVC5 アプリの試験用コードを使って試してみました。

**まずは curl 側:**

Windows 10 搭載の curl ですが、以下のコマンド（-x 127.0.0.1:8888 は Fiddler
で要求・応答をキャプチャするため追加、-k は SSL 検証を無効にするため追加したものです）で、

[code]

    curl -x 127.0.0.1:8888 -k -F "postedfiles=@image1.jpg" -F "postedfiles=@image2.jpg" https://localhost:44365/File/MultipleUpload
    
[/code]

以下の要求が送信されます。

[code]

    POST https://localhost:44365/File/MultipleUpload HTTP/1.1
    Host: localhost:44365
    User-Agent: curl/7.55.1
    Accept: */*
    Content-Length: 112670
    Expect: 100-continue
    Content-Type: multipart/form-data; boundary=------------------------12dea397e7140308
    
    --------------------------12dea397e7140308
    Content-Disposition: form-data; name="postedfiles"; filename="image1.jpg"
    Content-Type: image/jpeg
    
    ・・・ファイルの中身（省略）・・・
    --------------------------12dea397e7140308
    Content-Disposition: form-data; name="postedfiles"; filename="image2.jpg"
    Content-Type: image/jpeg
    
    ・・・ファイルの中身（省略）・・・
    --------------------------12dea397e7140308--
    
[/code]

**そして、ASP.NET MVC アプリ側:**

Web サーバーが上の要求を受け取ると、MVC アプリは curl コマンドの URL に指定されたコントローラー/アクションメソッド（上の例では
File/MultipleUpload）の `IList<HttpPostedFileBase>` 型の引数 postedfiles
に送信されてきたファイルをモデルバインドします。以下の画像を見てください。

[![画像の説明をここに入力](https://i.stack.imgur.com/w3w7T.jpg)](https://i.stack.imgur.com/w3w7T.jpg)

参考に検証に使ったサンプルコードを以下にアップしておきます。今回のスレッドの話とは関係ないものも入ってますが、そのあたりの見分けはつきますよね？ curl
では AntiForgeryToken は送れないので [ValidateAntiForgeryToken]
をコメントアウトしているところに注意してください。

**Model**

[code]

    public class MultipleUploadModels
    {
        public string CustomField { get; set; }
        public IList<HttpPostedFileBase> PostedFiles { get; set; }
    }
    
[/code]

**Action Method**

[code]

    public ActionResult MultipleUpload()
    {
        return View();
    }
    
    [HttpPost]
    //[ValidateAntiForgeryToken]
    public ActionResult MultipleUpload(MultipleUploadModels model)
    {
        string result = "";
        string customFiled = model.CustomField;
        IList<HttpPostedFileBase> postedFiles = model.PostedFiles;
    
        // input type="file" でファイルが選択されてない場合でも postedFiles は null にならないし、
        // postedFiles.Count は 0 にならない（1 になる）。従い、以下のコードでは制御が else に飛ぶことはない
        if (postedFiles != null && postedFiles.Count > 0)
        {
            foreach (HttpPostedFileBase postedFile in postedFiles)
            {
                if (postedFile != null && postedFile.ContentLength > 0)
                {
                    // アップロードされたファイル名を取得。ブラウザが IE の
                    // 場合 postedFile.FileName はクライアント側でのフル
                    // パスになることがあるので Path.GetFileName を使う
                    string filename = Path.GetFileName(postedFile.FileName);
    
                    // 保存ホルダの物理パス\ファイル名
                    string path = Server.MapPath("~/UploadedFiles") + "\\" + filename;
    
                    // アップロードされたファイルを保存
                    postedFile.SaveAs(path);
    
                    result += filename + " (" + postedFile.ContentType + ") - " +
                                      postedFile.ContentLength.ToString() +
                                      " bytes アップロード完了<br />";
                }                    
            }
            result += "送信された CustomField: " + customFiled;
        }
        else
        {
            result = "ファイルアップロードに失敗しました";
        }
    
        if (Request.IsAjaxRequest())
        {
            return Content(result);
        }
        else
        {
            ViewBag.Result = result;
            return View();
        }
    }
    
[/code]


CC BY-SA 4.0
2021-01-05T02:46:53.977
73082
2021-01-05T02:46:53.977
43387
64008
answer