2010-05-03 19 views
10

Limito el tamaño del archivo que los usuarios pueden cargar al sitio desde Web.config. Como se explica en here, debería arrojar una excepción ConfigurationErrorsException si no se acepta el tamaño. Traté de atraparlo desde el método de acción o el controlador para las solicitudes de carga, pero no tuve suerte. La conexión se restablece y no puedo mostrar una página de error.Cómo atrapar la excepción ConfigurationErrorsException por violar maxRequestLength?

Intenté detectarlo en el evento BeginRequest pero no importa lo que haga, la excepción no se ha manejado. Aquí está el código:

protected void Application_BeginRequest(Object sender, EventArgs e) 
{ 
    HttpContext context = ((HttpApplication)sender).Context; 
    try 
    { 
     if (context.Request.ContentLength > maxRequestLength) 
     { 
      IServiceProvider provider = (IServiceProvider)context; 
      HttpWorkerRequest workerRequest = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest)); 

      // Check if body contains data 
      if (workerRequest.HasEntityBody()) 
      { 
       // get the total body length 
       int requestLength = workerRequest.GetTotalEntityBodyLength(); 
       // Get the initial bytes loaded 
       int initialBytes = 0; 
       if (workerRequest.GetPreloadedEntityBody() != null) 
        initialBytes = workerRequest.GetPreloadedEntityBody().Length; 
       if (!workerRequest.IsEntireEntityBodyIsPreloaded()) 
       { 
        byte[] buffer = new byte[512]; 
        // Set the received bytes to initial bytes before start reading 
        int receivedBytes = initialBytes; 
        while (requestLength - receivedBytes >= initialBytes) 
        { 
         // Read another set of bytes 
         initialBytes = workerRequest.ReadEntityBody(buffer, buffer.Length); 

         // Update the received bytes 
         receivedBytes += initialBytes; 
        } 
        initialBytes = workerRequest.ReadEntityBody(buffer, requestLength - receivedBytes); 
       } 
      } 
     } 
    } 
    catch(HttpException) 
    { 
     context.Response.Redirect(this.Request.Url.LocalPath + "?action=exception"); 
    } 
} 

Pero todavía sale esto:

Maximum request length exceeded. 

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: Maximum request length exceeded. 

Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Actualización:

¿Qué método plantea la excepción de todos modos? Si leo la solicitud, genera una excepción. Si no la leo en absoluto, obtengo "101 Connection Reset" en el navegador. ¿Qué se puede hacer aquí?

+0

quería seguir su respuesta, busqué en Google y encontré esto: http://stackoverflow.com/questions/2966076/getting-file-size-in-javascript. De acuerdo con este tema, no hay una manera de averiguar el tamaño del archivo a través de Javascript simple (¡no quiero usar Flash, ActiveX o HTML 5!). ¿Lo estoy entendiendo correctamente? – celticharp

+0

@necronio, creo que sí. –

Respuesta

1

No hay forma de hacerlo bien sin una ayuda del lado del cliente. No puede determinar si la solicitud es demasiado larga a menos que la lea por completo. Si lee cada solicitud hasta el final, cualquiera puede venir y mantener su servidor ocupado. Si solo mira la longitud del contenido y elimina la solicitud, el otro lado creerá que hay un problema de conexión. No es nada que puedas hacer con el manejo de errores, es un defecto de HTTP.

Puede utilizar componentes Flash o Javascript para hacerlo bien, porque esto no puede fallar muy bien.

5

Usted no puede error de captura en el método de acción becouse excepción viene antes, pero se puede coger desde aquí

protected void Application_Error() { 
    var lastError = Server.GetLastError(); 
    if(lastError !=null && lastError is HttpException && lastError.Message.Contains("exceed")) { 
     Response.Redirect("~/errors/RequestLengthExceeded"); 
     } 
    } 

actualy cuando el tamaño del archivo supera los límites HttpException surgen de error.

También hay límite de IIS en el contenido, que no se puede atrapar en la aplicación. IIS 7 lanza

Error HTTP 404.13 - no encontrado El módulo de filtrado solicitud está configurado de denegar una solicitud que excede la longitud del contenido petición.

Puede buscar en google, hay mucha información acerca de este error.

+0

Aún no lo he alojado en IIS. Lo intento en el servidor de desarrollo pero lo tendré en cuenta. Supongo que debería manejarlo desde global.asax? –

+0

Sí, desde global.asax –

+0

Es extraño. Logro detectar el error pero no puedo redirigirlo a otro lugar. Va para la URL de carga. Parece que alguien más tuvo [el mismo problema] (http://forums.asp.net/p/845691/957981.aspx#957981) –

0

no estoy 100% en esto, pero creo que podría ayudar si se trató de cambiar:

context.Response.Redirect(this.Request.Url.LocalPath + "?action=exception");

a

Server.Transfer(this.Request.Url.LocalPath + "?action=exception,false)

Mi pensamiento es que el exceso de la max-request-length La solicitud todavía se está procesando en la llamada de Redirect, pero si le indica que elimine los datos del formulario, se convertirá en la longitud máxima de solicitud y luego podría comportarse de manera diferente.

No hay garantías, pero es fácil de verificar.

+0

Server.Transfer no funciona en MVC. Response.Redirect hace lo mismo en realidad. El problema es que el navegador piensa que hubo un problema de conexión si no lo lee todo y arroja 101 –

0
catch (Exception ex) 
    { 
     if (ex is HttpException && (ex as HttpException).WebEventCode == 3004) 
     { 
      //-- you can now inform the client that file uploaded was too large. 
     } 
     else 
      throw; 
    } 
0

Tengo un problema similar en que quiero coger el 'Longitud máxima pedido superado' excepción dentro del manejador Application_Error y luego hacer una redirección.

(La diferencia es que estoy escribiendo un servicio REST con ASP.Net Web API y en lugar de redireccionar a una página de error, quería redireccionar a un controlador de error que luego devolvería la respuesta adecuada).

Sin embargo, lo que encontré fue que al ejecutar la aplicación a través del servidor de desarrollo ASP.Net, el Response.Redirect no parecía estar funcionando. Fiddler declararía que "ReadResponse() falló: el servidor no devolvió una respuesta para esta solicitud".

Mi cliente (Advanced REST Client for Chrome) simplemente muestra "0 NO RESPONSE".

Si luego ejecuté la aplicación a través de una copia local de IIS en mi máquina de desarrollo, ¡entonces la redirección funcionaría correctamente!

No estoy seguro de que definitivamente puedo decir que Response.Redirect no funciona en ASP.Net Development Server, pero ciertamente no funcionaba en mi situación.

Por lo tanto, le recomiendo que intente ejecutar su aplicación a través de IIS en lugar de IIS Express o del Servidor de Desarrollo y vea si obtiene un resultado diferente.

Vea este enlace sobre cómo especificar el servidor Web para proyectos web en Visual Studio:

http://msdn.microsoft.com/en-us/library/ms178108(v=vs.100).aspx

Cuestiones relacionadas