c# - Captura "Se excedió la longitud máxima de solicitud"
asp.net httpexception (13)
¿Qué te parece atraparlo en el evento 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);
}
}
Estoy escribiendo una función de carga y tengo problemas para detectar "System.Web.HttpException: se excedió la longitud máxima de solicitud" con archivos mayores que el tamaño máximo especificado en httpRuntime
en web.config (tamaño máximo configurado en 5120). Estoy usando una <input>
simple para el archivo.
El problema es que la excepción se lanza antes del evento de clic del botón de carga, y la excepción ocurre antes de que se ejecute mi código. Entonces, ¿cómo atrapo y manejo la excepción?
EDIT: la excepción se produce al instante, así que estoy bastante seguro de que no es un problema de tiempo de espera debido a las conexiones lentas.
Aquí hay una forma alternativa, que no implica ningún "hack", sino que requiere ASP.NET 4.0 o posterior:
//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
}
}
Como GateKiller dijo que necesita cambiar maxRequestLength. Es posible que también deba cambiar el tiempo de ejecución en caso de que la velocidad de carga sea demasiado lenta. Tenga en cuenta que no desea que ninguna de estas configuraciones sea demasiado grande, de lo contrario, estará abierto a los ataques de DOS.
El valor predeterminado para executionTimeout es 360 segundos o 6 minutos.
Puede cambiar maxRequestLength y executionTimeout con httpRuntime Element .
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="102400" executionTimeout="1200" />
</system.web>
</configuration>
EDITAR:
Si desea manejar la excepción independientemente, como ya se ha indicado, deberá manejarla en Global.asax. Aquí hay un enlace a un ejemplo de código .
Como probablemente sepa, la longitud máxima de solicitud se configura en DOS lugares.
-
maxRequestLength
: controlado en el nivel de la aplicación ASP.NET -
maxAllowedContentLength
- en<system.webServer>
, controlado en el nivel IIS
El primer caso está cubierto por otras respuestas a esta pregunta.
Para atrapar EL SEGUNDO, debes hacer esto en global.asax:
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();
}
}
Después de la etiqueta
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4500000" />
</requestFiltering>
</security>
agregue la siguiente etiqueta
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="13" />
<error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="http://localhost/ErrorPage.aspx" responseMode="Redirect" />
</httpErrors>
puede agregar la URL a la página de error ...
En IIS 7 y más allá:
archivo web.config:
<system.webServer>
<security >
<requestFiltering>
<requestLimits maxAllowedContentLength="[Size In Bytes]" />
</requestFiltering>
</security>
</system.webServer>
A continuación, puede verificar el código detrás, así:
If FileUpload1.PostedFile.ContentLength > 2097152 Then '' (2097152 = 2 Mb)
'' Exceeded the 2 Mb limit
'' Do something
End If
Solo asegúrese de que [Tamaño en Bytes] en el archivo web.config sea mayor que el tamaño del archivo que desea cargar, entonces no obtendrá el error 404. Luego puede verificar el tamaño del archivo en el código que está detrás utilizando ContentLength, que sería mucho mejor
Hola solución mencionada por Damien McGivern, Works on IIS6 solamente,
No funciona en IIS7 y ASP.NET Development Server. Aparece la página que muestra "404 - Archivo o directorio no encontrado".
¿Algunas ideas?
EDITAR:
Entendido ... Esta solución aún no funciona en ASP.NET Development Server, pero entendí por qué no funcionaba en IIS7 en mi caso.
El motivo es que IIS7 tiene un escaneo de solicitud incorporado que impone un límite de carga de archivo que por defecto es de 30000000 bytes (que es ligeramente inferior a 30 MB).
Y estaba tratando de cargar un archivo de tamaño de 100 MB para probar la solución mencionada por Damien McGivern (con maxRequestLength = "10240", es decir, 10 MB en web.config). Ahora, si subo el archivo de tamaño> 10 MB y <30 MB, la página se redirige a la página de error especificada. Pero si el tamaño del archivo es> 30 MB, muestra la fea página de error incorporada que muestra "404 - Archivo o directorio no encontrado".
Entonces, para evitar esto, debes aumentar el máximo. permitida la longitud del contenido de la solicitud para su sitio web en IIS7. Eso se puede hacer usando el siguiente comando
appcmd set config "SiteName" -section:requestFiltering -requestLimits.maxAllowedContentLength:209715200 -commitpath:apphost
He establecido el máximo. contenido de longitud a 200 MB.
Después de hacer esta configuración, la página se redirige satisfactoriamente a mi página de error cuando intento cargar un archivo de 100 MB.
Consulte http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx para obtener más detalles.
No hay una manera fácil de atrapar dicha excepción por desgracia. Lo que hago es anular el método OnError a nivel de página o Application_Error en global.asax, luego verificar si se trata de un error de solicitud máxima y, de ser así, transferirlo a una página de error.
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");
}
}
Es un truco, pero el siguiente código funciona para mí
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;
}
Puede resolver esto aumentando la longitud máxima de solicitud en su web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpRuntime maxRequestLength="102400" />
</system.web>
</configuration>
El ejemplo anterior es para un límite de 100Mb.
Puede resolver esto aumentando la longitud máxima de solicitud y el tiempo de ejecución en su web.config:
-Por favor clarifique el tiempo máximo de ejecución fuera del rallador luego 1200
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" executionTimeout="1200" /> </system.web> </configuration>
Si también desea una validación del lado del cliente para que no tenga que lanzar excepciones, podría intentar implementar la validación del tamaño del archivo del lado del cliente.
Nota: Esto solo funciona en navegadores compatibles con 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>
Una forma de hacerlo es establecer el tamaño máximo en web.config como ya se ha indicado anteriormente, por ejemplo
<system.web>
<httpRuntime maxRequestLength="102400" />
</system.web>
luego, cuando maneja el evento de carga, verifique el tamaño y si supera una cantidad específica, puede atraparlo, por ejemplo
protected void btnUploadImage_OnClick(object sender, EventArgs e)
{
if (fil.FileBytes.Length > 51200)
{
TextBoxMsg.Text = "file size must be less than 50KB";
}
}
Una solución que funciona con IIS7 y versiones posteriores: muestra una página de error personalizada cuando la carga de archivos excede el tamaño permitido en ASP.NET MVC