ASP .Net MVC 4 WebAPI のPOSTでマルチパートのファイルを送受信する


.Net で複数ファイルの送受信を行う WebAPI を作りたかったので調べてみた。

HttpClient を使ってPOSTでマルチパートのファイルを送受信するのWebAPI側の実装です。

これで WebAPI を使って複数のファイルの送受信が簡単にできる!

やりたいこと

POSTリクエスト
 クライアントからのPOSTで送信された MurtiPart の Content からファイルを読み込んでサーバサイドに保存する

レスポンス
 レスポンスにサーバ上のファイルを MultiPart の Content に含めて送信する

POSTリクエストの MurtiPart の Content からファイルを読み込む

MurtiPart からファイルを読み出すには MultipartFormDataStreamProvider を使う。

// ファイルの保存先は一時フォルダ
var rootPath = Path.GetTempPath();
var provider = new MultipartFormDataStreamProvider(rootPath);

provider から ReadAsMultipartAsync() を用いて MultiPart Content の中身を読み込むと、ファイルは一時フォルダに一時ファイル名で保存される。

// コンテントの中身を読み込む
MultipartFormDataStreamProvider readedProvider = await requestContent.ReadAsMultipartAsync(provider);

あとは provider.FileData を foreach で回して一つずつアクセスし、一時ファイルパスとオリジナルのファイル名を取得して任意の場所にコピーしたりする。

// ファイルデータを読む
foreach (var file in provider.FileData)
{
    // ファイル情報を取得
    var localFileName = file.LocalFileName;
    var originalFileName = file.Headers.ContentDisposition.FileName;

    // あとは任意のフォルダに保存するなりする
}

レスポンスに MultiPart の Content に複数ファイルを含める

MultipartFormDataContent のインスタンスに複数のファイル Content を生成して Add() する流れ。

var content = new MultipartFormDataContent();

var fileName = "送りたいファイル名";
var fileContent = new StreamContent(File.OpenRead(fileName));

fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = Path.GetFileName(fileName)
};

content.Add(fileContent);  // 送りたいファイル数分繰り返す

あとはレスポンスを生成して Content を設定すればOK。
この時、Request.CreateResponse()の第2引数に content を渡すのではなく、生成した response インスタンスの Content プロパティに直接代入することに注意。設定次第かもしれないが、MultiPart の Content として登録されないことがあった。

// レスポンスを作成
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = content; // ここ重要

return response;

こちらも書いてみればたったこれだけのこと、、という感じだが、とりあえずこれで複数のファイルをやりとりする WebAPI を作成することができた。ただIISなどのWebサーバには一度に送信できるファイル容量の上限があるので利用に合わせて設定を変えたりしないといけないので注意。