Ловля "Максимальная длина запроса превышена"

Я пишу функцию загрузки, и у меня проблемы с ловушкой "System.Web.HttpException: Максимальная длина запроса превышена" с файлами, большими, чем указанный максимальный размер, в httpRuntime в web.config(максимальный размер равен 5120), Я использую простой <input> для файла.

Проблема заключается в том, что исключение возникает перед нажатием кнопки click click, а исключение происходит до того, как будет запущен мой код. Итак, как я могу поймать и обработать исключение?

EDIT: Исключение бросается мгновенно, поэтому я уверен, что это не проблема таймаута из-за медленных подключений.

Ответ 1

К сожалению, нет простого способа поймать такое исключение. То, что я делаю, либо переопределяет метод OnError на уровне страницы, либо Application_Error в global.asax, а затем проверяет, был ли это ошибкой 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;
}

Ответ 2

Как сказал GateKiller, вам нужно изменить maxRequestLength. Вам также может потребоваться изменить executeTimeout, если скорость загрузки слишком медленная. Обратите внимание, что вы не хотите, чтобы любой из этих параметров был слишком большим, иначе вы будете открыты для DOS-атак.

Значение по умолчанию для исполненияTimeout составляет 360 секунд или 6 минут.

Вы можете изменить maxRequestLength и executeTimeout с помощью httpRuntime Element.

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

EDIT:

Если вы хотите обработать исключение, независимо от того, как уже было сказано, вам нужно будет обработать его в Global.asax. Здесь ссылка на пример кода.

Ответ 3

Вы можете решить эту проблему, увеличив максимальную длину запроса в файле web.config:

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

Пример выше для ограничения 100 Мб.

Ответ 4

Привет решение, упомянутое Дэмиеном Макгиверном, Работает только с IIS6,

Он не работает на IIS7 и ASP.NET Development Server. Я получаю отображение страницы "404 - Файл или каталог не найдены".

Любые идеи?

EDIT:

Получил это... Это решение все еще не работает на ASP.NET Development Server, но я получил причину, почему он не работал на IIS7 в моем случае.

Причина заключается в том, что IIS7 имеет встроенное сканирование запросов, которое накладывает ограничение на загрузку файла, значение по умолчанию которого составляет 30000000 байт (что чуть меньше 30 МБ).

И я пытался загрузить файл размером 100 МБ, чтобы проверить решение, упомянутое Дэмиеном Макгиверном (с maxRequestLength = "10240", то есть 10 МБ в web.config). Теперь, если я загружу файл размером > 10 МБ и < 30 МБ, тогда страница перенаправляется на указанную страницу ошибки. Но если размер файла составляет > 30 МБ, тогда он показывает уродливую встроенную страницу ошибок, отображающую "404 - Файл или каталог не найден".

Итак, чтобы этого избежать, вам нужно увеличить макс. разрешенную длину содержимого запроса для вашего веб-сайта в IIS7. Это можно сделать, используя следующую команду:

appcmd set config "SiteName" -section:requestFiltering -requestLimits.maxAllowedContentLength:209715200 -commitpath:apphost

Я установил max. длина содержимого до 200 МБ.

После выполнения этого параметра страница будет перенаправлена ​​на мою страницу с ошибкой, когда я попытаюсь загрузить файл размером 100 МБ

Подробнее см. http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx.

Ответ 5

Если вам нужна проверка на стороне клиента, так что вам не нужно бросать исключения, вы можете попытаться реализовать проверку размера файла на стороне клиента.

Примечание. Это работает только в браузерах, поддерживающих 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>

Ответ 6

Один из способов сделать это - установить максимальный размер в 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";
    }
}

Ответ 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
    }
}

Ответ 9

В 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

Просто убедитесь, что размер [Size By Bytes] в файле web.config больше размера файла, который вы хотите загрузить, тогда вы не получите ошибку 404. Затем вы можете проверить размер файла в коде, используя ContentLength, который будет намного лучше

Ответ 10

Как вы, наверное, знаете, максимальная длина запроса настроена в местах TWO​​strong > .

  • maxRequestLength - контролируется на уровне приложения ASP.NET
  • maxAllowedContentLength - под <system.webServer>, управляемый на уровне IIS

Первый случай рассматривается другими ответами на этот вопрос.

Чтобы поймать ВТОРОЙ ОДИН, вам нужно сделать это в 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();
    }
}

Ответ 11

Вы можете решить эту проблему, увеличив максимальную длину запроса и время выполнения в файле web.config:

-Пожалуйста, уточните максимальную продолжительность выполнения, затем 1200

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

Ответ 12

После тега

<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 на страницу с ошибкой...

Ответ 13

Как насчет catch на событии 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);
        }
    }