2010-05-03 7 views
10

Je limite la taille de fichier que les utilisateurs peuvent télécharger sur le site à partir de Web.config. Comme expliqué here, il devrait lancer une exception ConfigurationErrorsException si la taille n'est pas acceptée. J'ai essayé de l'attraper de la méthode d'action ou du contrôleur pour des demandes de téléchargement mais aucune chance. La connexion est réinitialisée et je n'arrive pas à l'afficher pour afficher une page d'erreur.Comment faire pour attraper ConfigurationErrorsException pour violer maxRequestLength?

J'ai essayé de l'attraper dans l'événement BeginRequest mais peu importe ce que je fais, l'exception n'est pas gérée. Voici le code:

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

Mais je reçois encore ceci:

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. 

Mise à jour:

Quelle méthode soulève l'exception de toute façon? Si je lis la requête, elle soulève une exception Si je ne la lis pas du tout, je reçois "101 Connection Reset" dans le navigateur. Que peut-on faire ici?

+0

Je voulais suivre votre réponse, je googlé et trouvé ceci: http://stackoverflow.com/questions/2966076/getting-file-size-en-javascript. Selon ce sujet, il n'y a pas de moyen de trouver la taille du fichier par JavaScript (je ne veux pas utiliser Flash, ActiveX ou HTML 5!). Est-ce que je comprends bien? – celticharp

+0

@necronio Je le pense. –

Répondre

1

Il n'y a aucun moyen de le faire correctement sans une aide côté client. Vous ne pouvez pas déterminer si la demande est trop longue à moins que vous ne l'ayez entièrement lu. Si vous lisez chaque requête jusqu'à la fin, n'importe qui arrive et maintient votre serveur occupé. Si vous regardez juste la longueur du contenu et déposez la demande, l'autre côté va penser qu'il y a un problème de connexion. Ce n'est rien que vous puissiez faire avec la gestion des erreurs, c'est un défaut de HTTP.

Vous pouvez utiliser des composants Flash ou Javascript pour faire les choses correctement car cette chose ne peut pas échouer gentiment.

5

Vous cant erreur de capture dans la méthode d'action becouse exception vient plus tôt, mais vous pouvez l'attraper ici

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

lorsque la taille du actualy fichier dépasse les limites HttpException erreur se posent.

Il existe également une limite IIS sur le contenu, qui ne peut pas être interceptée dans l'application. IIS 7 jette

Erreur HTTP 404,13 - Non trouvé Le module de filtrage de requête est configuré de refuser une demande qui dépasse la longueur du contenu de la demande .

Vous pouvez google, il y a beaucoup d'informations sur cette erreur iis.

+0

Je ne l'ai pas encore hébergé sur IIS. J'essaye sur le serveur de développement mais je garderai à l'esprit. Je suppose que je devrais le gérer de global.asax? –

+0

Oui, de global.asax –

+0

C'est étrange.J'ai réussi à attraper l'erreur mais je ne peux pas la rediriger ailleurs. Cela vaut pour l'URL de téléchargement. Regardez comme quelqu'un d'autre avait [le même problème] (http://forums.asp.net/p/845691/957981.aspx#957981) –

0

sur ce que je ne suis pas 100%, mais je pense que cela pourrait aider si vous avez essayé de changer:

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

à

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

Ma pensée est que la sur- max-request-length La requête est toujours en cours de traitement dans l'appel Redirect, mais si vous lui dites d'abandonner les données du formulaire, il deviendra inférieur à la longueur maximale de la requête et se comportera différemment.

Aucune garantie, mais il est facile à vérifier.

+0

Server.Transfer ne fonctionne pas dans MVC. Response.Redirect fait la même chose en réalité. Le problème est le navigateur pense qu'il y avait un problème de connexion si vous ne lisez pas le tout et jette 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

J'ai un problème similaire à ce que je veux attraper la « longueur maximale de la demande dépassé » exception dans le gestionnaire Application_Error puis faire un Redirect.

(La différence est que j'écris un service REST avec ASP.Net Web API et au lieu de rediriger vers une page d'erreur, je voulais rediriger vers un contrôleur d'erreur qui retournerait alors la réponse appropriée).

Cependant, ce que j'ai trouvé était que lors de l'exécution de l'application via le serveur de développement ASP.Net, le Response.Redirect ne semblait pas fonctionner. Fiddler indiquerait que "ReadResponse() a échoué: le serveur n'a pas retourné de réponse pour cette requête."

Mon client (client REST avancé pour Chrome) affiche simplement "0 NO RESPONSE".

Si j'ai ensuite exécuté l'application via une copie locale d'IIS sur ma machine de développement, la redirection fonctionnerait correctement!

Je ne suis pas sûr que je peux définitivement dire que Response.Redirect ne fonctionne pas sur le serveur de développement ASP.Net mais cela ne fonctionnait certainement pas dans ma situation. Par conséquent, je recommande d'essayer d'exécuter votre application via IIS au lieu d'IIS Express ou du serveur de développement et de voir si vous obtenez un résultat différent.

Voir ce lien sur la façon de spécifier le serveur Web pour les projets Web dans Visual Studio:

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

Questions connexes