「最大リクエスト長を超えました」をキャッチ


112

アップロード関数を書いていてhttpRuntime、web.config で指定された最大サイズ(最大サイズが5120に設定されている)より大きいファイルで「System.Web.HttpException:最大リクエスト長を超えました」のキャッチに問題があります。<input>ファイルにはシンプルを使用しています。

問題は、アップロードボタンのクリックイベントの前に例外がスローされ、コードが実行される前に例外が発生することです。では、どうすれば例外をキャッチして処理できますか?

編集:例外はすぐにスローされるので、接続が遅いためにタイムアウトの問題ではないことは間違いありません。


5
誰かがMVCでこれを試しましたか?私は例外を正しい方法でキャッチできるようですが、それを止めることはできません。エラーページをレンダリングしようとするたびに、同じ例外が発生します。
アンディ

このエラーメッセージは、コントローラーに到達する前にIISによってスローされます。ファイルが最大アップロード制限(web-configで設定)を超えていることをユーザーに通知するには、onchangeイベントでJSを介してファイルサイズを直接検証できます。たとえば<input type="file" id="upload" name="upload" onchange="showFileSize();" />InsideのshowFileSize()場合、ファイルサイズに基づいてエラーメッセージを表示しvar input = document.getElementById("upload"); var file = input.files[0];、htmlタグを追加できます。
アルフレッドウォレス

回答:


97

残念ながら、そのような例外を簡単にキャッチする方法はありません。ページレベルでOnErrorメソッドをオーバーライドするか、global.asaxのApplication_Errorをオーバーライドしてから、それが最大リクエストの失敗かどうかを確認し、失敗した場合はエラーページに転送します。

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;
}

2
ありがとう。OnErrorは機能しませんでしたが、Application_Errorは機能しました。実際にはこれのためのハンドラーがありますが、誰かがコードでそれをオフにしています。
マーカスL

2年前でも、これが今までうまくいったかどうか尋ねたいのですか?'GetEntireRawContent'の文字列比較は正常に機能しますか?これはタイムアウトの問題ではないと思います。これに関してどこか曇りを指摘してくれた人がいますか?
Elaine、

@Elaineええ、この手法はASP.Net 4.0でも機能します。リクエストの最大長を超えるリクエストをアップロードしようとすると、ASP.NetはタイムアウトコードとともにHttpExceptionをスローします。リフレクターを使用してSystem.Web.HttpRequest.GetEntireRawContent()を見てください。
Damien McGivern、

12
@ sam-ruebyローカリゼーションによって変更される可能性のある文字列エラーメッセージに返信したくありませんでした。
Damien McGivern

4
.NET 4.0以降の場合、最大リクエストサイズを超えたかどうかを特定するためのより良い方法があります。この状態でHttpExceptionを確認できます。httpException.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge-System.Web.Management.WebEventCodesを使用
mco

58

GateKillerが言ったように、maxRequestLengthを変更する必要があります。アップロード速度が遅すぎる場合は、executionTimeoutを変更する必要がある場合もあります。これらの設定を大きくしすぎないようにしてください。そうしないと、DOS攻撃を受けやすくなります。

executionTimeoutのデフォルトは360秒または6分です。

maxRequestLengthとexecutionTimeoutはhttpRuntime Elementで変更できます。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" executionTimeout="1200" />
    </system.web>
</configuration>

編集:

それでも例外を処理したい場合は、すでに述べたように、Global.asaxで処理する必要があります。これは、コード例へのリンクです。


2
お返事ありがとうございます。ただし、GKの回答に対するコメントで述べたように、これで実際に問題が解決するわけではありません。例外はすぐにスローされるため、タイムアウトの問題でもありません。それをより明確にするために質問を編集します。
マーカスL

4
コード例のurlは利用できないページを指しています...誰かがこれを修正できますか?
2010年

20

これを解決するには、web.configでリクエストの最大長を増やします。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" />
    </system.web>
</configuration>

上記の例は100Mbの制限です。


18
はいといいえ。限界をさらに押し上げますが、実際には例外を処理しません。誰かが101 MB以上をアップロードしようとした場合でも、同じ問題が発生します。制限は本当に5 Mbである必要があります。
マーカスL

10

例外をスローする必要性が少なくなるようにクライアント側の検証も必要な場合は、クライアント側のファイルサイズ検証を実装してみてください。

注:これは、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>


9

Damien McGivernが言及したこんにちはソリューションは、IIS6でのみ動作し、

IIS7およびASP.NET開発サーバーでは機能しません。「404-ファイルまたはディレクトリが見つかりません。」と表示されたページが表示されます。

何か案は?

編集:

了解しました...このソリューションはASP.NET開発サーバーではまだ機能しませんが、私の場合、IIS7で機能しない理由がわかりました。

その理由は、IIS7に組み込みのリクエストスキャンがあり、アップロードファイルの上限がデフォルトで30000000バイト(30MBをわずかに下回る)になっているためです。

そして、Damien McGivernによって言及されたソリューションをテストするために、サイズが100 MBのファイルをアップロードしようとしました(maxRequestLength = "10240"、つまりweb.configで10MB)。ここで、サイズが10MBを超え30MB未満のファイルをアップロードすると、ページは指定されたエラーページにリダイレクトされます。ただし、ファイルサイズが30 MBを超える場合は、「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を参照してください。


ごめんなさい!クエリを回答として追加しましたが、既存の投稿にコメントを追加する方法がわかりません。
Vinod T. Patil、2010

1
もっと担当者が必要です。投稿にコメントする。現在の担当者でできること、できないことの詳細については、よくある質問をご覧ください。
slaphappy 2010

7

これは別の方法です。「ハッキング」は含まれませんが、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
    }
}

4

これを行う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";
    }
}

1
これは機能しません。クリックイベントはトリガーされません。例外は以前に発生します。
ロンバス2017


3

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を使用してコードビハインドでファイルサイズを確認できます。


2

ご存知のように、リクエストの最大長は2か所に設定されています。

  1. maxRequestLength -ASP.NETアプリレベルで制御
  2. 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();
    }
}

1

タグの後

<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を追加することができます...


0

これは、web.configでリクエストの最大長と実行タイムアウトを増やすことで解決できます。

-最大実行タイムアウトを1200にしてから明確にしてください

<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" executionTimeout="1200" /> </system.web> </configuration>

0

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);
        }
    }

0

次の方法で確認できます。

        var httpException = ex as HttpException;
        if (httpException != null)
        {
            if (httpException.WebEventCode == System.Web.Management.WebEventCodes.RuntimeErrorPostTooLarge)
            {
                // Request too large

                return;

            }
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.