「最大リクエスト長を超えました」をキャッチ
-
21-08-2019 - |
質問
アップロード関数を作成していますが、「System.Web.HttpException:」をキャッチする際に問題が発生します。ファイルが指定された最大サイズよりも大きい場合、「最大リクエスト長を超えました」というメッセージが表示されます。 httpRuntime
web.config 内 (最大サイズは 5120 に設定)。私はシンプルなものを使っています <input>
ファイル用。
問題は、アップロード ボタンのクリック イベントの前に例外がスローされ、コードが実行される前に例外が発生することです。では、どうすれば例外をキャッチして処理できるのでしょうか?
編集: 例外は即座にスローされるため、接続の遅さによるタイムアウトの問題ではないと確信しています。
解決
残念ながら、このような例外をキャッチする簡単な方法はありません。私が行うことは、ページレベルで OnError メソッドをオーバーライドするか、global.asax の Application_Error をオーバーライドしてから、それが Max Request の失敗だったかどうかを確認し、失敗した場合はエラー ページに転送することです。
protected override void OnError(EventArgs e) .....
private void Application_Error(object sender, EventArgs e)
{
if (GlobalHelper.IsMaxRequestExceededException(this.Server.GetLastError()))
{
this.Server.ClearError();
this.Server.Transfer("~/error/UploadTooLarge.aspx");
}
}
これはハックですが、以下のコードは私にとってはうまくいきます
const int TimedOutExceptionCode = -2147467259;
public static bool IsMaxRequestExceededException(Exception e)
{
// unhandled errors = caught at global.ascx level
// http exception = caught at page level
Exception main;
var unhandled = e as HttpUnhandledException;
if (unhandled != null && unhandled.ErrorCode == TimedOutExceptionCode)
{
main = unhandled.InnerException;
}
else
{
main = e;
}
var http = main as HttpException;
if (http != null && http.ErrorCode == TimedOutExceptionCode)
{
// hack: no real method of identifying if the error is max request exceeded as
// it is treated as a timeout exception
if (http.StackTrace.Contains("GetEntireRawContent"))
{
// MAX REQUEST HAS BEEN EXCEEDED
return true;
}
}
return false;
}
他のヒント
GateKiller が言ったように、maxRequestLength を変更する必要があります。アップロード速度が遅すぎる場合には、executionTimeout の変更が必要になる場合もあります。どちらの設定も大きすぎると、DOS 攻撃にさらされてしまうので注意してください。
実行タイムアウトのデフォルトは 360 秒または 6 分です。
maxRequestLengthとexecutionTimeoutを変更するには、 httpランタイム要素.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="102400" executionTimeout="1200" />
</system.web>
</configuration>
編集:
とにかく例外を処理したい場合は、すでに述べたように、Global.asax で例外を処理する必要があります。ここにリンクがあります コード例.
これは、web.config の最大リクエスト長を増やすことで解決できます。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="102400" />
</system.web>
</configuration>
上の例は 100Mb 制限の場合です。
Damien McGivernが言及したこんにちは解決策は、IIS6のみで動作します、
IIS7 および ASP.NET 開発サーバーでは動作しません。ページに「404 - ファイルまたはディレクトリが見つかりません」と表示されます。
何か案は?
編集:
わかった...このソリューションはまだ ASP.NET 開発サーバーでは機能しませんが、私の場合 IIS7 で機能しない理由はわかりました。
その理由は、IIS7 には、デフォルトで 30000000 バイト (30MB よりわずかに少ない) というアップロード ファイルの上限を課す組み込みの要求スキャンがあるためです。
そして、Damien McGivernが言及したソリューションをテストするために、サイズ100 MBのファイルをアップロードしようとしていました(maxRequestLength = "10240"、つまりweb.config で 10MB)。ここで、サイズが 10 MB を超え 30 MB 未満のファイルをアップロードすると、ページは指定されたエラー ページにリダイレクトされます。ただし、ファイル サイズが 30MB を超える場合は、「404 - ファイルまたはディレクトリが見つかりません」という見苦しい組み込みエラー ページが表示されます。
したがって、これを回避するには、最大値を増やす必要があります。IIS7 で Web サイトに許可されるリクエスト コンテンツの長さ。これは次のコマンドを使用して実行できます。
appcmd set config "SiteName" -section:requestFiltering -requestLimits.maxAllowedContentLength:209715200 -commitpath:apphost
最大値を設定しました。コンテンツの長さは 200MB までです。
この設定を行った後、100MBのファイルをアップロードしようとすると、ページはエラーページに正常にリダイレクトされます。
参照する、 http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx 詳細については。
例外をスローする必要性を減らすためにクライアント側の検証も必要な場合は、クライアント側のファイル サイズ検証を実装してみることができます。
注記:これは、HTML5 をサポートするブラウザでのみ機能します。http://www.html5rocks.com/en/tutorials/file/dndfiles/
<form id="FormID" action="post" name="FormID">
<input id="target" name="target" class="target" type="file" />
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
$('.target').change(function () {
if (typeof FileReader !== "undefined") {
var size = document.getElementById('target').files[0].size;
// check file size
if (size > 100000) {
$(this).val("");
}
}
});
</script>
これは、「ハック」を必要としない別の方法ですが、ASP.NET 4.0 以降が必要です。
//Global.asax
private void Application_Error(object sender, EventArgs e)
{
var ex = Server.GetLastError();
var httpException = ex as HttpException ?? ex.InnerException as HttpException;
if(httpException == null) return;
if(httpException.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge)
{
//handle the error
Response.Write("Sorry, file is too big"); //show this message for instance
}
}
これを行う 1 つの方法は、すでに上で述べたように、web.config で最大サイズを設定することです。
<system.web>
<httpRuntime maxRequestLength="102400" />
</system.web>
次に、アップロードイベントを処理したら、サイズを確認し、特定の量を超えている場合は、たとえばトラップできます。
protected void btnUploadImage_OnClick(object sender, EventArgs e)
{
if (fil.FileBytes.Length > 51200)
{
TextBoxMsg.Text = "file size must be less than 50KB";
}
}
IIS7 以降で動作するソリューション: ファイルのアップロードが ASP.NET MVC で許可されているサイズを超えた場合にカスタム エラー ページを表示する
IIS 7 以降の場合:
web.config ファイル:
<system.webServer>
<security >
<requestFiltering>
<requestLimits maxAllowedContentLength="[Size In Bytes]" />
</requestFiltering>
</security>
</system.webServer>
次に、次のようにコードビハインドをチェックインできます。
If FileUpload1.PostedFile.ContentLength > 2097152 Then ' (2097152 = 2 Mb)
' Exceeded the 2 Mb limit
' Do something
End If
web.config の [バイト単位のサイズ] がアップロードするファイルのサイズより大きいことを確認してください。そうすれば、404 エラーは発生しません。その後、ContentLength を使用してコードビハインドでファイルサイズを確認できます。これははるかに優れています
おそらくご存知のとおり、リクエストの最大長は次のように設定されます。 二 場所。
maxRequestLength
- ASP.NET アプリ レベルで制御maxAllowedContentLength
- 下<system.webServer>
, 、IIS レベルで制御される
最初のケースは、この質問に対する他の回答でカバーされています。
捕まえる 2 番目のもの これを global.asax で行う必要があります。
protected void Application_EndRequest(object sender, EventArgs e)
{
//check for the "file is too big" exception if thrown at the IIS level
if (Response.StatusCode == 404 && Response.SubStatusCode == 13)
{
Response.Write("Too big a file"); //just an example
Response.End();
}
}
タグ付け後
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4500000" />
</requestFiltering>
</security>
次のタグを追加します
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="13" />
<error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="http://localhost/ErrorPage.aspx" responseMode="Redirect" />
</httpErrors>
エラーページに URL を追加できます...
これは、web.config でリクエストの最大長と実行タイムアウトを増やすことで解決できます。
- 1200以降の最大実行タイムアウトを明確にしてください
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" executionTimeout="1200" /> </system.web> </configuration>
EndRequestイベントでキャッチしてみてはいかがでしょうか?
protected void Application_EndRequest(object sender, EventArgs e)
{
HttpRequest request = HttpContext.Current.Request;
HttpResponse response = HttpContext.Current.Response;
if ((request.HttpMethod == "POST") &&
(response.StatusCode == 404 && response.SubStatusCode == 13))
{
// Clear the response header but do not clear errors and
// transfer back to requesting page to handle error
response.ClearHeaders();
HttpContext.Current.Server.Transfer(request.AppRelativeCurrentExecutionFilePath);
}
}
次の方法で確認できます。
var httpException = ex as HttpException;
if (httpException != null)
{
if (httpException.WebEventCode == System.Web.Management.WebEventCodes.RuntimeErrorPostTooLarge)
{
// Request too large
return;
}
}