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

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

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

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

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

Любые идеи?

Спасибо заранее!

Марк

Ответ 1

При работе под 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 than 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>

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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