Как отловить ConfigurationErrorsException за нарушение maxRequestLength? - PullRequest
10 голосов
/ 03 мая 2010

Я ограничиваю размер файла, который пользователи могут загружать на сайт из Web.config. Как объяснено здесь , оно должно вызвать исключение ConfigurationErrorsException, если размер не принят. Я пытался поймать его из метода действия или контроллера для запросов на загрузку, но безуспешно. Соединение сброшено, и я не могу показать страницу ошибки.

Я пытался перехватить его в событии BeginRequest, но независимо от того, что я делаю, исключение не обрабатывается. Вот код:

protected void Application_BeginRequest(Object sender, EventArgs e)
{
    HttpContext context = ((HttpApplication)sender).Context;
    try
    {
        if (context.Request.ContentLength > maxRequestLength)
        {
            IServiceProvider provider = (IServiceProvider)context;
            HttpWorkerRequest workerRequest = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));

            // Check if body contains data
            if (workerRequest.HasEntityBody())
            {
                // get the total body length
                int requestLength = workerRequest.GetTotalEntityBodyLength();
                // Get the initial bytes loaded
                int initialBytes = 0;
                if (workerRequest.GetPreloadedEntityBody() != null)
                    initialBytes = workerRequest.GetPreloadedEntityBody().Length;
                if (!workerRequest.IsEntireEntityBodyIsPreloaded())
                {
                    byte[] buffer = new byte[512];
                    // Set the received bytes to initial bytes before start reading
                    int receivedBytes = initialBytes;
                    while (requestLength - receivedBytes >= initialBytes)
                    {
                        // Read another set of bytes
                        initialBytes = workerRequest.ReadEntityBody(buffer, buffer.Length);

                        // Update the received bytes
                        receivedBytes += initialBytes;
                    }
                    initialBytes = workerRequest.ReadEntityBody(buffer, requestLength - receivedBytes);
                }
            }
        }
    }
    catch(HttpException)
    {
        context.Response.Redirect(this.Request.Url.LocalPath + "?action=exception");
    }
}

Но я все еще получаю это:

Maximum request length exceeded.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: Maximum request length exceeded.

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Обновление:

Какой метод вызывает исключение? Если я читаю запрос, он вызывает исключение. Если я его вообще не читаю, в браузере появляется сообщение «101 Connection Reset». Что тут можно сделать?

Ответы [ 5 ]

5 голосов
/ 03 мая 2010

Вы не можете перехватить ошибку в методе действия, потому что исключение наступает раньше, но вы можете перехватить его здесь

protected void Application_Error() {
     var lastError = Server.GetLastError();
     if(lastError !=null && lastError is HttpException && lastError.Message.Contains("exceed")) {
      Response.Redirect("~/errors/RequestLengthExceeded");
      }
    }   

На самом деле, когда размер файла превышает пределы, возникает ошибка HttpException.

Существует также ограничение IIS на содержимое, которое не может быть отслежено в приложении. IIS 7 бросков

Ошибка HTTP 404.13 - не найден модуль фильтрации запросов настроен отклонить запрос, который превышает длина содержимого запроса.

Вы можете погуглить, есть много информации об этой ошибке.

1 голос
/ 28 апреля 2011

Невозможно сделать это правильно без помощи на стороне клиента. Вы не можете определить, является ли запрос слишком длинным, если вы не прочитали все его. Если вы прочитаете каждый запрос до конца, кто-нибудь придет и будет занят вашим сервером. Если вы просто посмотрите на длину контента и отбросите запрос, другая сторона подумает, что есть проблема с соединением. Вы ничего не можете сделать с обработкой ошибок, это недостаток HTTP.

Вы можете использовать компоненты Flash или Javascript, чтобы сделать это правильно, потому что эта штука не может хорошо работать.

0 голосов
/ 10 мая 2013

У меня похожая проблема: я хочу перехватить исключение «Максимальная длина запроса превышена» в обработчике Application_Error, а затем выполнить перенаправление.

(Разница в том, что я пишу службу REST с помощью ASP.Net Web API и вместо перенаправления на страницу ошибки я хотел перенаправить на контроллер ошибок, который затем возвращал бы соответствующий ответ).

Однако я обнаружил, что при запуске приложения через сервер разработки ASP.Net, Response.Redirect, похоже, не работал. Fiddler заявил бы, что «ReadResponse () не выполнен: сервер не возвратил ответ на этот запрос».

Мой клиент (Advanced REST Client для Chrome) просто показывает "0 NO RESPONSE".

Если бы я затем запустил приложение через локальную копию IIS на моей машине для разработки, тогда перенаправление работало бы правильно!

Я не уверен, что могу однозначно сказать, что Response.Redirect не работает на сервере разработки ASP.Net, но, безусловно, не работал в моей ситуации.

Итак, я рекомендую попробовать запустить ваше приложение через IIS вместо IIS Express или сервера разработки и посмотреть, получите ли вы другой результат.

См. Ссылку для указания веб-сервера для веб-проектов в Visual Studio:

http://msdn.microsoft.com/en-us/library/ms178108(v=vs.100).aspx

0 голосов
/ 23 мая 2012
   catch (Exception ex)
   {
       if (ex is HttpException && (ex as HttpException).WebEventCode == 3004)
       {
            //-- you can now inform the client that file uploaded was too large.
       }
       else
           throw;
   }
0 голосов
/ 29 января 2011

Я не на 100% в этом, но я думаю, что это может помочь, если вы попытаетесь изменить:

context.Response.Redirect(this.Request.Url.LocalPath + "?action=exception");

до

Server.Transfer(this.Request.Url.LocalPath + "?action=exception,false)

Я думаю, что запрос over-max-request-length все еще обрабатывается в вызове Redirect, но если вы скажете ему отбросить данные формы, он станет меньше максимальной длины запроса, и тогда он может вести себя иначе .

Нет гарантий, но его легко проверить.

...