your too requestlimits net maximum maxallowedcontentlength large for check change asp iis-7 web-config http-status-code-404 httpapplication

iis 7 - too - ¿Dónde atrapo y manejo maxAllowedContentLength excedido en IIS7?



web config upload file size (2)

Tengo una página aspx donde estoy permitiendo que un usuario cargue un archivo y quiero limitar el tamaño máximo de carga de archivos a 10 MB. IIS7, .NET 3.5. Tengo configurado lo siguiente en mi archivo web.config:

<location path="foo.aspx"> <system.web> <!-- maxRequestLength: kbytes, executionTimeout:seconds --> <httpRuntime maxRequestLength="10240" executionTimeout="120" /> <authorization> <allow roles="customRole"/> <!-- Deny everyone else --> <deny users="*"/> </authorization> </system.web> <system.webServer> <security> <requestFiltering> <!-- maxAllowedContentLength: bytes --> <requestLimits maxAllowedContentLength="10240000"/> </requestFiltering> </security> <handlers accessPolicy="Read, Script"> <add name="foo" path="foo.aspx" verb="POST" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode" /> </handlers> </system.webServer> </location>

Tengo un módulo de manejo de errores personalizado que implementa IHttpModule . He descubierto que cuando se excede HttpApplication.Error , HttpApplication.Error realmente se levanta. Sin embargo, cuando juego con maxAllowedContentLength , el evento HttpApplication.Error no se HttpApplication.Error y el usuario se redirige a una página 404.13. Me he conectado con Visual Studio con excepciones de primera oportunidad activadas, no se lanza nada.

Mi primer pensamiento es verificar la longitud del contenido del encabezado en un evento anterior: ¿hay recomendaciones / mejores prácticas de dónde hago esto? PostLogRequest? EndRequest?


El método más simple es manejarlo en el método de la página OnError.

Creo que esto solo funciona en .NET 4.0, ya que la propiedad WebEventCode está documentada como NUEVA en .NET 4.0.

protected override void OnError(EventArgs e) { Exception err = Server.GetLastError(); if (err is HttpException) { if ((err as HttpException).WebEventCode == 3004) { Context.Items["error"] = "File exceeded maximum allowed length."; Server.Transfer( Context.Request.Url.LocalPath ); return; } } base.OnError(e); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (!IsPostBack) { string error = Context.Items["error"] as string; if (!string.IsNullOrEmpty( error )) showErrorMessage( error ); } }

Lo que hice fue:

  • obtener el último error con Server.GetLastError
  • compruebe que es una "Longitud máxima de solicitud excedida". error (WebEventCode == 3004).
  • agregó un valor a las colecciones Context.Items para marcar la solicitud como un error
  • transferir la solicitud a la página misma con Server.Transfer (Context.Request.Url.LocalPath)
  • el método OnLoad de la página busca el indicador de error y muestra un mensaje si está presente

Esto garantiza que el error se maneje por completo en la página solicitada, y la página puede informar de errores.

También tenga en cuenta que si bien el navegador finalmente recibirá una respuesta adecuada, el navegador puede tomar su tiempo para cargar la solicitud completa antes de que maneje la respuesta del servidor y la muestre. Este comportamiento probablemente se define como parte de la interacción servidor / navegador en el protocolo HTTP, por lo que probablemente no se puede hacer mucho al respecto.


Después de ver el Resumen del ciclo de vida de la aplicación ASP.NET para IIS 7.0 y hacer mi propia experimentación, supongo que la validación de la solicitud se realiza internamente por IIS antes de que se produzca alguno de los eventos.

Parece que solo se generan LogRequest, PostLogRequest, EndRequest, PreSendRequestContent y PreSendRequestHeaders después de la validación interna con este error.

Decidí adjuntar un controlador de eventos al evento HttpApplication.EndRequest en mi controlador de errores personalizado y verificar el código de estado 404.13 en POST y manejarlo cuando lo necesite, lo que en mi caso es redirigir a la página de llamadas. que verificará Server.GetLastError() y mostrará un error amigable para el usuario final.

private 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); } }

Me gustaría recibir comentarios sobre este enfoque y alternativas.