この記事ではVisual Studio 2015のASP.NET 4.5.2 Webアプリケーションプロジェクトを使いました。
非同期ashxでストリーミングSaveAs
// System.Web.HttpTaskAsyncHandler
public override async Task ProcessRequestAsync(HttpContext context)
{
using (var fs = File.OpenWrite("filename")) {
await context.Request.GetBufferlessInputStream(disableMaxRequestLength:true).CopyToAsync(fs);
}
}
ストリーミング受信
ASP.NETのパイプライン処理はヘッダーの受信が完了すれば始まる。しかしHttpRequest.InputStream
はリクエストBody全体が読み込まれるまでブロックする(このとき、一定の大きさ以上であれば一時ファイルにバッファリングされる)。
WebFormの場合はPageクラスがInputStream
へアクセスするのでユーザーコードが実行されるのはリクエスト全体の受信が完了した後になる。
HttpRequest.SaveAs
は上記の仕組みによりいったんリクエスト全体が一時ファイルに保存されてそのファイルを読み出して再度ファイルに保存される。
.NET4からHttpRequest.GetBufferlessStreamメソッドが用意された。リクエスト全体の受信完了を待たずに処理をすることができる。
受信サイズの制限
アップロードのサイズ制限
requestFiltering/requestLimits@maxAllowContentLength
1
IISの機能。web.configのlocation
要素を使って特定のパスにだけ適用することができる。httpRuntime@maxRequestLength
2
ASP.NETの機能。アプリケーションルートでのみ指定でき、アプリケーション全体で有効になる。
v4.5で追加されたHttpRequest.GetBufferlessInputStream(disableMaxRequestLength:true)
3はHttpRuntime@maxRequestLength
の制限を受けない。
アップロードされたファイルの一時保存先
ASP .NET Ajax File Upload
数GBのファイルをHTTPでPOSTできるか- (2) サーバー編 - @jsakamoto
数GBのファイルをHTTPでPOSTできるか? (3) 完結