Capture " longueur maximale de la demande dépassée"

j'écris une fonction de téléchargement, et j'ai des problèmes avec le système".Web.HttpException: longueur de requête maximale dépassée" avec des fichiers plus grands que la taille maximale spécifiée dans httpRuntime dans web.config (max taille définie à 5120). J'utilise un simple <input> pour le fichier.

le problème est que l'exception est lancée avant le click-event du bouton de téléchargement, et l'exception se produit avant que mon code ne soit lancé. Alors comment puis-je attraper et gérer l'exception?

EDIT: L'exception est levée, instantanément, donc je suis sûr que ce n'est pas un problème de délai d'attente en raison de la lenteur des connexions.

100
demandé sur Jonathan Moffatt 2009-03-20 12:23:08

13 réponses

il n'y a malheureusement pas de moyen facile d'attraper une telle exception. Ce que je fais est soit de remplacer la méthode OnError au niveau de la page ou L'Application_Error dans global.asax, puis vérifiez si C'était un échec de requête Max et, si oui, transférez à une page d'erreur.

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

C'est un hack mais le code ci-dessous fonctionne pour moi

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;
}
91
répondu Damien McGivern 2015-07-30 18:12:08

comme GateKiller a dit que vous devez changer la longueur maxrequestl. Vous pouvez également avoir besoin de changer le executionTimeout au cas où la vitesse de téléchargement est trop lente. Notez que vous ne voulez pas que l'un ou l'autre de ces paramètres soit trop grand sinon vous serez ouvert aux attaques DOS.

la valeur par défaut pour le executionTimeout est de 360 secondes ou 6 minutes.

vous pouvez changer la durée maxRequestLength et executionTimeout avec L'élément httpRuntime .

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" executionTimeout="1200" />
    </system.web>
</configuration>

EDIT:

si vous voulez gérer l'exception indépendamment, comme cela a déjà été dit, vous aurez besoin de le gérer dans Global.asax. Voici un lien vers un exemple de code .

56
répondu Jonathan Parker 2012-05-17 21:43:38

vous pouvez résoudre cela en augmentant la longueur maximale de la requête dans votre web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="102400" />
    </system.web>
</configuration>

L'exemple ci-dessus est pour une limite de 100 mo.

19
répondu GateKiller 2009-03-20 09:34:36

Hi solution mentionnée par Damien McGivern, Ne fonctionne que sur IIS6,

ne fonctionne pas sur IIS7 et ASP.NET serveur de développement. Je reçois la page d'affichage " 404-fichier ou répertoire non trouvé."

des idées?

EDIT:

compris... Cette solution ne fonctionne toujours pas ASP.NET serveur de développement, mais j'ai eu la raison pour laquelle il ne fonctionnait pas sur IIS7 dans mon cas.

la raison est que IIS7 a une requête intégrée de numérisation qui impose un cap de fichier de téléchargement qui est par défaut de 30000000 octets (ce qui est légèrement moins que 30MB).

et j'ai essayé de télécharger un fichier de taille 100 MB pour tester la solution mentionnée par Damien McGivern (avec maxRequestLength=" 10240 " i.e. 10MB dans le web.config). Maintenant, si je télécharge le fichier de taille > 10MB et < 30 MB alors la page est redirigée vers la page d'erreur spécifiée. Mais si la taille du fichier est > 30MB alors il afficher la page d'erreur intégrée moche affichant " 404-fichier ou répertoire introuvable."

Donc, pour éviter cela, vous devez augmenter le max. longueur de contenu de demande autorisée pour votre site Web dans IIS7. Cela peut être fait en utilisant la commande suivante,

appcmd set config "SiteName" -section:requestFiltering -requestLimits.maxAllowedContentLength:209715200 -commitpath:apphost

j'ai mis le max. longueur du contenu à 200MB.

après avoir fait ce réglage, la page est redirigée avec succès vers ma page d'erreur quand j'essaie de télécharger le fichier de 100MB

, on entend, http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx pour plus de détails.

9
répondu Vinod T. Patil 2010-07-08 12:16:08

si vous voulez une validation côté client aussi afin d'obtenir moins d'un besoin de jeter des exceptions, vous pouvez essayer d'implémenter la validation côté client de la taille du fichier.

Note: cela ne fonctionne que dans les navigateurs qui prennent en charge 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>

9
répondu Andrew 2011-07-05 10:56:02

une façon de faire ceci est de définir la taille maximale dans le web.config as a déjà été indiqué ci-dessus par exemple

<system.web>         
    <httpRuntime maxRequestLength="102400" />     
</system.web>

ensuite, lorsque vous gérez l'événement de téléchargement, vérifiez la taille et si son au-dessus d'une quantité spécifique, vous pouvez le piéger par exemple

protected void btnUploadImage_OnClick(object sender, EventArgs e)
{
    if (fil.FileBytes.Length > 51200)
    {
         TextBoxMsg.Text = "file size must be less than 50KB";
    }
}
5
répondu BaggieBoy 2012-09-14 22:12:50

Voici une autre façon, qui n'implique pas de "hacks", mais nécessite ASP.NET 4.0 ou plus tard:

//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
    }
}
5
répondu Serge Shultz 2015-05-23 20:00:53

Dans IIS 7 et au-delà:

web.fichier de configuration:

<system.webServer>
  <security >
    <requestFiltering>
      <requestLimits maxAllowedContentLength="[Size In Bytes]" />
    </requestFiltering>
  </security>
</system.webServer>

vous pouvez ensuite enregistrer le code derrière, comme suit:

If FileUpload1.PostedFile.ContentLength > 2097152 Then ' (2097152 = 2 Mb)
  ' Exceeded the 2 Mb limit
  ' Do something
End If

assurez-vous simplement de la [taille en octets] dans le web.config est plus grand que la taille du fichier que vous souhaitez télécharger alors vous n'obtiendrez pas l'erreur 404. Vous pouvez alors vérifier la taille du fichier en code derrière en utilisant le ContentLength qui serait beaucoup mieux

3
répondu Walery Strauch 2014-06-23 11:47:44

comme vous le savez probablement, la longueur maximale de la requête est configurée en deux places.

  1. maxRequestLength - contrôlée à la ASP.NET niveau app
  2. maxAllowedContentLength - sous <system.webServer> , commandé au niveau IIS

Le premier cas est couvert par d'autres réponses à cette question.

D'attraper LA SECONDE ce que vous devez faire ce mondial.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();
    }
}
2
répondu jazzcat 2016-12-22 10:30:58

après l'étiquette

<security>
     <requestFiltering>
         <requestLimits maxAllowedContentLength="4500000" />
     </requestFiltering>
</security>

ajouter l'étiquette suivante

 <httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404" subStatusCode="13" />
  <error statusCode="404" subStatusCode="13" prefixLanguageFilePath="" path="http://localhost/ErrorPage.aspx" responseMode="Redirect" />
</httpErrors>

vous pouvez ajouter l'Url de la page d'erreur...

1
répondu Diego 2016-04-05 18:44:52

vous pouvez résoudre cela en augmentant la longueur maximale de la requête et le temps d'exécution dans votre web.config:

- S'il vous plaît préciser le temps d'exécution maximum grater puis 1200

<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <httpRuntime maxRequestLength="102400" executionTimeout="1200" /> </system.web> </configuration>
0
répondu Nasurudeen 2014-06-24 07:19:33

Que Diriez-vous de l'attraper à L'événement 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);
        }
    }
0
répondu Khoa Tran 2016-04-22 16:04:09