Улов " максимальная длина запроса превышена"
Я пишу функцию загрузки, и у меня есть проблемы с ловлей "системы.Сеть.HttpException: максимальная длина запроса превышена " с файлами, превышающими указанный максимальный размер в httpRuntime
в интернете.конфигурации (максимальный размер установлен в 5120). Я использую простой <input>
для файла.
проблема заключается в том, что исключение создается перед событием click-event кнопки загрузки, и исключение происходит до запуска моего кода. Так как же мне поймать и обработать исключение?
EDIT: исключение выбрасывается мгновенно, поэтому я уверен, что это не проблема тайм-аута из-за медленных соединений.
13 ответов:
к сожалению, нет простого способа поймать такое исключение. Я либо переопределяю метод OnError на уровне страницы, либо Application_Error в global.asax, затем проверьте, был ли это максимальный сбой запроса и, если да, перейдите на страницу ошибки.
protected override void OnError(EventArgs e) ..... private void Application_Error(object sender, EventArgs e) { if (GlobalHelper.IsMaxRequestExceededException(this.Server.GetLastError())) { this.Server.ClearError(); this.Server.Transfer("~/error/UploadTooLarge.aspx"); } }
это хак, но код ниже работает для меня
const int TimedOutExceptionCode = -2147467259; public static bool IsMaxRequestExceededException(Exception e) { // unhandled errors = caught at global.ascx level // http exception = caught at page level Exception main; var unhandled = e as HttpUnhandledException; if (unhandled != null && unhandled.ErrorCode == TimedOutExceptionCode) { main = unhandled.InnerException; } else { main = e; } var http = main as HttpException; if (http != null && http.ErrorCode == TimedOutExceptionCode) { // hack: no real method of identifying if the error is max request exceeded as // it is treated as a timeout exception if (http.StackTrace.Contains("GetEntireRawContent")) { // MAX REQUEST HAS BEEN EXCEEDED return true; } } return false; }
Как сказал GateKiller, вам нужно изменить maxRequestLength. Вам также может потребоваться изменить executionTimeout в случае, если скорость загрузки слишком медленная. Обратите внимание, что вы не хотите, чтобы любой из этих параметров был слишком большим, иначе вы будете открыты для DOS-атак.
значение по умолчанию для executionTimeout составляет 360 секунд или 6 минут.
вы можете изменить maxRequestLength и executionTimeout с помощью httpRuntime Элемент.
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" executionTimeout="1200" /> </system.web> </configuration>
EDIT:
Если вы хотите обрабатывать исключение независимо от того, как уже было указано, вам нужно будет обрабатывать его в глобальном масштабе.асакс. Вот ссылка на пример кода.
вы можете решить эту проблему, увеличив максимальную длину запроса в вашем интернете.config:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" /> </system.web> </configuration>
приведенный выше пример предназначен для ограничения 100 МБ.
Привет решение упомянуто Дэмиен Макгиверн, Работает только на IIS6,
Он не работает на IIS7 и ASP.NET сервер разработки. Я получаю страницу с надписью "404 - файл или каталог не найден."
какие идеи?
EDIT:
получил его... Это решение по-прежнему не работает ASP.NET сервер разработки, но я получил причину, по которой он не работал на IIS7 в моем случае.
причина в том, что IIS7 имеет встроенное сканирование запросов который накладывает шапку файла загрузки, которая по умолчанию составляет 30000000 байт (что немного меньше 30 МБ).
и я пытался загрузить файл размером 100 МБ, чтобы проверить решение, упомянутое Дэмиеном Макгиверном (с maxRequestLength="10240" т. е. 10 МБ в интернете.конфигурация.) Теперь, если я загружаю файл размером > 10 МБ и 30 МБ, то он показывает уродливую встроенную страницу ошибки, отображающую " 404-файл или каталог нет найдено."
таким образом, чтобы избежать этого, вы должны увеличить Макс. разрешенная длина содержимого запроса для вашего сайта в IIS7. Что можно сделать с помощью следующей команды
appcmd set config "SiteName" -section:requestFiltering -requestLimits.maxAllowedContentLength:209715200 -commitpath:apphost
Я установил Макс. длина содержимого до 200 МБ.
после выполнения этой настройки страница успешно перенаправляется на мою страницу ошибок, когда я пытаюсь загрузить файл размером 100 МБ
см., http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx для получения более подробной информации.
Если вам нужна проверка на стороне клиента, поэтому вам меньше нужно бросать исключения, вы можете попробовать реализовать проверку размера файла на стороне клиента.
Примечание: это работает только в браузерах, которые поддерживают HTML5. http://www.html5rocks.com/en/tutorials/file/dndfiles/
<form id="FormID" action="post" name="FormID"> <input id="target" name="target" class="target" type="file" /> </form> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> $('.target').change(function () { if (typeof FileReader !== "undefined") { var size = document.getElementById('target').files[0].size; // check file size if (size > 100000) { $(this).val(""); } } }); </script>
один из способов сделать это-установить максимальный размер в интернете.конфигурация, как уже было указано выше, например
<system.web> <httpRuntime maxRequestLength="102400" /> </system.web>
затем, когда вы обрабатываете событие загрузки, проверьте размер, и если его более определенной суммы, Вы можете поймать его например,
protected void btnUploadImage_OnClick(object sender, EventArgs e) { if (fil.FileBytes.Length > 51200) { TextBoxMsg.Text = "file size must be less than 50KB"; } }
вот альтернативный способ, который не предполагает никаких "хаков", но требует ASP.NET 4.0 или более поздней версии:
//Global.asax private void Application_Error(object sender, EventArgs e) { var ex = Server.GetLastError(); var httpException = ex as HttpException ?? ex.InnerException as HttpException; if(httpException == null) return; if(httpException.WebEventCode == WebEventCodes.RuntimeErrorPostTooLarge) { //handle the error Response.Write("Sorry, file is too big"); //show this message for instance } }
решение, которое работает с IIS7 и выше:отображение страницы пользовательской ошибки, когда загрузка файла превышает допустимый размер ASP.NET MVC
в IIS 7 и за его пределами:
web.конфигурационный файл:
<system.webServer> <security > <requestFiltering> <requestLimits maxAllowedContentLength="[Size In Bytes]" /> </requestFiltering> </security> </system.webServer>
затем вы можете проверить код позади, например:
If FileUpload1.PostedFile.ContentLength > 2097152 Then ' (2097152 = 2 Mb) ' Exceeded the 2 Mb limit ' Do something End If
просто убедитесь, что [размер в байтах] в интернете.конфигурация больше, чем размер файла, который вы хотите загрузить, то вы не получите ошибку 404. Затем вы можете проверить размер файла в коде, используя ContentLength, который был бы намного лучше
как вы, наверное, знаете, максимальная длина запроса настроен в два места.
maxRequestLength
- контролируется на ASP.NET уровень приложенияmaxAllowedContentLength
- под<system.webServer>
, управляется на уровне IISпервый случай освещается другими ответами на этот вопрос.
поймать ВТОРОЙ вы должны сделать это в глобальном масштабе.асакс:
protected void Application_EndRequest(object sender, EventArgs e) { //check for the "file is too big" exception if thrown at the IIS level if (Response.StatusCode == 404 && Response.SubStatusCode == 13) { Response.Write("Too big a file"); //just an example Response.End(); } }
после тега
<security> <requestFiltering> <requestLimits maxAllowedContentLength="4500000" /> </requestFiltering> </security>
добавить следующий тег
<httpErrors errorMode="Custom" existingResponse="Replace"> <remove statusCode="404" subStatusCode="13" /> <error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="http://localhost/ErrorPage.aspx" responseMode="Redirect" /> </httpErrors>
Вы можете добавить Url-адрес на страницу ошибки...
вы можете решить эту проблему, увеличив максимальную длину запроса и время выполнения в вашем интернете.config:
- пожалуйста, уточните максимальное время выполнения из терки, то 1200
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" executionTimeout="1200" /> </system.web> </configuration>
Как насчет поймать его на EndRequest событие?
protected void Application_EndRequest(object sender, EventArgs e) { HttpRequest request = HttpContext.Current.Request; HttpResponse response = HttpContext.Current.Response; if ((request.HttpMethod == "POST") && (response.StatusCode == 404 && response.SubStatusCode == 13)) { // Clear the response header but do not clear errors and // transfer back to requesting page to handle error response.ClearHeaders(); HttpContext.Current.Server.Transfer(request.AppRelativeCurrentExecutionFilePath); } }