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

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

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

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

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

Есть идеи?

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

Marcus

Ответы [ 4 ]

57 голосов
/ 24 сентября 2010

При работе под 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>
3 голосов
/ 18 мая 2010

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

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

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

1 голос
/ 03 ноября 2010

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

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

if (HttpContext.Current.Request.Url.ToString().Contains("UploadedPage.aspx") 
{
    //read and process page request
}
0 голосов
/ 03 мая 2010

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

...