[c#] “최대 요청 길이 초과”포착

업로드 기능을 작성 httpRuntime중이며 web.config 에 지정된 최대 크기 (최대 크기는 5120으로 설정) 보다 큰 파일에서 “System.Web.HttpException : Maximum request length exceeded”를 잡는 데 문제가 있습니다 . 간단한 <input>파일을 사용하고 있습니다.

문제는 업로드 버튼의 클릭 이벤트 전에 예외가 발생하고 내 코드가 실행되기 전에 예외가 발생한다는 것입니다. 그렇다면 예외를 어떻게 포착하고 처리합니까?

편집 : 예외는 즉시 발생하므로 느린 연결로 인한 시간 초과 문제가 아니라고 확신합니다.



답변

불행히도 그러한 예외를 잡는 쉬운 방법은 없습니다. 내가하는 일은 페이지 수준에서 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;
}


답변

GateKiller가 maxRequestLength를 변경해야한다고 말했듯이. 업로드 속도가 너무 느린 경우 executionTimeout을 변경해야 할 수도 있습니다. 이러한 설정 중 어느 것도 너무 크지 않도록하십시오. 그렇지 않으면 DOS 공격에 노출 될 것입니다.

executionTimeout의 기본값은 360 초 또는 6 분입니다.

httpRuntime 요소를 사용하여 maxRequestLength 및 executionTimeout을 변경할 수 있습니다 .

<?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 제한에 대한 것입니다.


답변

클라이언트 측 유효성 검사를 원하므로 예외를 던질 필요가 적어 클라이언트 측 파일 크기 유효성 검사를 구현할 수 있습니다.

참고 : 이는 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>


답변

Damien McGivern이 언급 한 Hi 솔루션은 IIS6에서만 작동합니다.

IIS7 및 ASP.NET 개발 서버에서는 작동하지 않습니다. “404-파일 또는 디렉토리를 찾을 수 없음”이라는 페이지가 나타납니다.

어떤 아이디어?

편집하다:

알겠습니다 …이 솔루션은 여전히 ​​ASP.NET 개발 서버에서 작동하지 않지만 제 경우에는 IIS7에서 작동하지 않는 이유가 있습니다.

그 이유는 IIS7에는 기본적으로 30000000 바이트 (30MB보다 약간 적음) 인 업로드 파일 캡을 부과하는 기본 제공 요청 스캔이 있기 때문입니다.

그리고 Damien McGivern이 언급 한 솔루션을 테스트하기 위해 크기가 100MB 인 파일을 업로드하려고했습니다 (maxRequestLength = “10240”즉 web.config에서 10MB 사용). 이제 10MB보다 크고 30MB보다 작은 파일을 업로드하면 페이지가 지정된 오류 페이지로 리디렉션됩니다. 그러나 파일 크기가 30MB보다 크면 “404-파일 또는 디렉토리를 찾을 수 없음”을 표시하는 추악한 내장 오류 페이지가 표시됩니다.

따라서이를 방지하려면 최대 값을 높여야합니다. IIS7에서 웹 사이트에 대해 허용 된 요청 콘텐츠 길이. 다음 명령을 사용하여 수행 할 수 있습니다.

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 를 참조하십시오.


답변

다음은 “해킹”을 포함하지 않지만 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
    }
}


답변

이 작업을 수행하는 한 가지 방법은 위에서 이미 설명한대로 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";
    }
}