ファイルアップロードでのサイズ制限を考える
世の中のサイトはどのように実現しているのだろうか?最適なのは、リクエストのヘッダのサイズだけでジャッジだけど、それをASP.NETでどうやるのかあちこち調べて(ファイルのアップロードなんてずっとやってたはずなのに、自分が担当で書いたことなかったんだろうなー、きっと)、大体下記の感じで落ち着いた。
今回はファイルのサイズ指定は、個別に設定したいということでWeb.configは使えないのでXMLファイルに定義してあります。Web.configの設定値をA、個別の設定値をB、ファイルサイズをCとした場合はこういう感じになります。
- C < B < A :正常にアップロード
- B < C < A :Application_BeginRequest内で処理
- B < A < C :Application_Error内で処理
そこで問題なのがIIS5.1で、IIS5.1だとApplication_Error時にうまいこと処理できません。そもそもは、WindowsXPで開発中に、この問題に引っかかったのがはじまりでした。
IIS 5.1 に fileupload コントロールを使用すると、 ASP.NET Web ページでファイルをアップロードしようとすると、エラー メッセージを表示します。
結局、下記の通りにやってもIIS 5.1である以上、Redirectはうまくできませんでした。そもそもHttpContextがうまくとれない。さらにRequestが大きいサイズのままを保持していて上書きもできないし。今回は、結合環境以降はIISが7.5なのでこのまま行くことに決定。そもそも5.1でいまだに開発していることが間違いなのかなー?どなたかいい解決方法あったら教えてください。
Global.asax.cs
/// <summary> /// Application_BeginRequest時 /// </summary> void Application_BeginRequest(object sender, EventArgs e) { RedirectFileSizeOver(null); } /// <summary> /// Application_Error時 /// </summary> void Application_Error(object sender, EventArgs e) { Exception exc = Server.GetLastError(); if (exc.GetType() == typeof(HttpException)) { HttpException httpEx = (HttpException)exc; if (httpEx.GetHttpCode() == 500 && httpEx.ErrorCode == -2147467259) { Server.ClearError(); RedirectFileSizeOver(httpEx); return; } } } /// <summary> /// サイズオーバー時の処理 /// </summary> private void RedirectFileSizeOver(HttpException ex) { //設定のXMLを取得 Dictionary<string, int> pathList = GetSettingFiles(); //設定されているページで、その設定値よりRequestが大きい場合 if(pathList.ContainsKey(thisPath)) { if (Request.Files.Count > 0 && Request.Files[0].ContentLength > pathList[thisPath] * 1000) { OperationLogger operationLogger = new OperationLogger(""); if (ex != null) { operationLogger.PutError("Web.ConfigのhttpRuntime maxRequestLengthより大きいサイズのファイルをUploadしました", ex); } else { operationLogger.PutError("FileSizeSetting.xmlのmaxSizeより大きいサイズのファイルをUploadしました"); } PathManager.Redirect(thisPath + "?size"); } } }
Web.config
<system.web> <!-- Requestが受け付けるMaxLengthとタイムアウト値 --> <httpRuntime maxRequestLength="30000" executionTimeout="120"/> </system.web>