ASP.NET Web API - ファイルアップロード
ASP.NET Web API - ファイルアップロード
ASP.NET Web API でファイルをアップロードする方法を解説します。
以下の環境で確認しています。
- .NET Framework 4.6.2
- AspNet.WebApi 5.2.9
サンプルソース
HTML + JavaScript
<input type="file">
のデータ(ファイル)を FormData に格納して fetch() で送信します。
<input type="file" name="uploadFile" />
<input type="button" value="アップロード" />
document.addEventListener('DOMContentLoaded', function () {
// アップロードボタンにクリックイベントを追加
document.querySelector('input[type="button"]').addEventListener('click', function () {
const formData = new FormData();
const fileElem = document.querySelector('input[type="file"]');
formData.append('uploadFile', fileElem.files[0]);
upload(formData);
});
// アップロード処理
async function upload(formData) {
try {
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
if (response.ok) {
alert('アップロード成功');
} else {
alert('アップロード失敗');
}
} catch (error) {
alert('アップロード異常終了');
}
}
});
アクションメソッド
MultipartFormDataStreamProvider クラスと ReadAsMultipartAsync メソッドを使って、アップロードされたファイルを保存します。
ASP.NET MVC のように、アクションメソッドの引数に渡してはくれないので注意が必要です。
次のプログラムでは、アップロードされたファイルを App_Data フォルダに保存するようにしています。
public class UploadController : ApiController
{
public async Task<HttpResponseMessage> PostFormData()
{
// multipart/form-data 以外はサポートしない
// 415 Unsupported Media Type を返す
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
// アップロードされたファイルの保存場所を決める
var root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try
{
// アップロードされたファイルを読み取る(=保存する)
await Request.Content.ReadAsMultipartAsync(provider);
// 保存したファイルの情報をデバッグ表示する
foreach (MultipartFileData file in provider.FileData)
{
// アップロードファイル名
System.Diagnostics.Debug.WriteLine(file.Headers.ContentDisposition.FileName);
// サーバーに保存したファイルのパス
System.Diagnostics.Debug.WriteLine(file.LocalFileName);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
アクションメソッドの解説
まずはアップロードされたファイルの保存場所を設定します。
MultipartFormDataStreamProvider クラスをインスタンス化します。
Web アプリルートの App_Data フォルダを指定しています。
var root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
次に ReadAsMultipartAsync メソッドを呼び、アップロードされたファイルを保存します。
ファイルは MultipartFormDataStreamProvider に設定した場所に保存されます。
今回は App_Data フォルダに BodyPart_3a807367-9127-4377-bfdd-3f94bc24cdd0 のようなファイル名で保存されました。
await Request.Content.ReadAsMultipartAsync(provider);
保存したファイルの情報は MultipartFormDataStreamProvider の FileData に格納されます。
FileData は MultipartFileData のコレクションです。
Headers.ContentDisposition.FileName はアップロードされたファイルの元の名前です。
ダブルクォートで囲まれたファイル名が入っていました。
例)テストファイル.txt をアップロード → “テストファイル.txt”
LocalFileName は保存したファイルのサーバー上のパスです。
例)C:\path\to\WebApp\App_Data\BodyPart_3a807367-9127-4377-bfdd-3f94bc24cdd0
foreach (MultipartFileData file in provider.FileData)
{
// アップロードファイル名
System.Diagnostics.Debug.WriteLine(file.Headers.ContentDisposition.FileName);
// サーバー上のローカルファイル名
System.Diagnostics.Debug.WriteLine(file.LocalFileName);
}
413 Request Entity Too Large の対処方法
1GBのファイルをアップロードしようとしたところ、「413 Request Entity Too Large」の応答が返ってきました。
これは maxAllowedContentLength の設定に違反すると発生します。
対処するには、web.config の /configuration/system.webServer/security/requestFiltering/requestLimits@maxAllowedContentLength を見直します。
詳細は「ASP.NET - 413 Request Entity Too Large の対処方法」のとおりです。
HttpException: 要求の長さの最大値を超えました。 の対処方法
maxAllowedContentLength を見直してから再度1GBのファイルをアップロードしました。
今度は ReadAsMultipartAsync メソッドで例外が発生しました。
System.IO.IOException: MIME マルチパート ボディ部分の読み取り中にエラーが発生しました。
内部例外
HttpException: 要求の長さの最大値を超えました。
これは maxRequestLength の設定に違反すると発生します。
対処するには、web.config の /configuration/system.web/httpRuntime@maxRequestLength を見直します。
詳細は「ASP.NET - HttpException: 要求の長さの最大値を超えました。 の対処方法」のとおりです。
アカウントを作成 して、もっと沢山の記事を読みませんか?
この記事にコメントをしてみませんか?