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

Моя главная проблема заключается в том, что я хочу отобразить пользовательскую страницу ошибки, когда загруженный файл превышает допустимый размер (maxRequestLength в web.config).

Когда большой файл загружен, HttpException генерируется до того, как мой метод действия загрузки в контроллере вызывается. Это ожидается.

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

Хотя возможно перехватить исключение в Application_Error в global.asax, но ни Response.Redirect, ни Server.Transfer не работают для перенаправления на пользовательскую страницу ошибки. Server.Transfer выдает ошибку "Не удалось обработать дочерний запрос", а response.redirect выдает ошибку "Заголовки Http уже отправлены".

Есть идеи?

Заранее спасибо!

Маркус

4 ответа

Решение

При работе под IIS7 и выше есть еще один параметр:

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="10485760" />
    </requestFiltering>
  </security>
</system.webServer>

Значение по умолчанию немного меньше 30 МБ.

Для загруженных файлов с размером между maxRequestLength а также maxAllowedContentLength IIS7 бросит HttpException с HTTP-кодом 500 и текстом сообщения Maximum request length exceeded, Когда выдается это исключение, IIS7 немедленно разрывает соединение. Так что HttpModule который перенаправляет на эту ошибку будет работать только если HttpException обрабатывается и очищается (используя Server.ClearError()) в Application_Error() в global.asax.cs.

Для загруженных файлов размером больше maxAllowedContentLength IIS7 отобразит подробную страницу ошибки с кодом ошибки 404 и subStatusCode 13. Страница ошибки может быть найдена в C:\inetpub\custerr\en-US\404-13.htm

Для перенаправлений на эту ошибку на IIS7 я рекомендую перенаправить на httpErrors вместо. Чтобы перенаправить на другое действие, установите меньшее значение для maxAllowedContentLength чем maxRequestLength в web.config, а также добавьте следующее в web.config:

<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace"> 
    <remove statusCode="404" subStatusCode="13" /> 
    <error statusCode="404" subStatusCode="13" prefixLanguageFilePath=""
       path="http://yoursite.com/Error/UploadTooLarge" responseMode="Redirect" /> 
  </httpErrors>
</system.webServer>

При работе на IIS6 я решил его с помощью HttpModule, обработав BeginRequest и проверил, больше ли httpApplication.Context.Request.Length, чем maxRequestLength.

Чтобы иметь возможность перенаправить весь запрос, необходимо прочитать перед перенаправлением.

Посмотрите пример кода по этой ссылке: http://www.velocityreviews.com/forums/t97027-how-to-handle-maximum-request-length-exceeded-exception.html

Ссылка Speed ​​Eviews была действительно полезна в решении проблемы. Как уже говорилось, единственным недостатком было то, что весь запрос (и файл) необходимо прочитать, прежде чем можно будет выполнить перенаправление.

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

if (HttpContext.Current.Request.Url.ToString().Contains("UploadedPage.aspx") 
{
    //read and process page request
}

Вам нужно создать собственный HttpHandler, который сделает это за вас. ASP.NET автоматически прервет соединение, если размер загрузки слишком велик (как вы узнали).

Другие вопросы по тегам