Отображать пользовательскую страницу ошибки, когда загрузка файла превышает допустимый размер в 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 автоматически прервет соединение, если размер загрузки слишком велик (как вы узнали).