113 votes

Attraction de "Longueur maximale de la demande dépassée".

J'écris une fonction de téléchargement, et j'ai des problèmes pour attraper "System.Web.HttpException : Maximum request length exceeded" avec des fichiers plus grands que la taille maximale spécifiée dans le champ httpRuntime dans web.config (taille maximale fixée à 5120). J'utilise un simple <input> pour le fichier.

Le problème est que l'exception est levée avant l'événement de clic du bouton de téléchargement, et l'exception se produit avant l'exécution de mon code. Alors comment puis-je attraper et gérer l'exception ?

EDIT : L'exception est levée instantanément, donc je suis presque sûr qu'il ne s'agit pas d'un problème de délai d'attente dû à des connexions lentes.

5 votes

Quelqu'un a-t-il essayé cela avec MVC ? Je semble être en mesure d'attraper l'exception de la bonne manière, mais je suis incapable de l'arrêter : chaque fois que j'essaie de rendre une page d'erreur, la même exception se produit.

0 votes

Ce message d'erreur est envoyé par IIS avant d'atteindre le contrôleur. Pour informer l'utilisateur que le fichier dépasse la limite maximale de téléchargement (définie dans votre configuration web), vous pouvez valider directement la taille du fichier via JS avec un événement onchange. Par exemple <input type="file" id="upload" name="upload" onchange="showFileSize();" /> À l'intérieur de showFileSize() vous pouvez afficher un message d'erreur basé sur la taille de votre fichier via var input = document.getElementById("upload"); var file = input.files[0]; et ajouter une balise html.

97voto

Damien McGivern Points 1781

Malheureusement, il n'y a pas de moyen simple d'attraper une telle exception. Ce que je fais, c'est soit remplacer la méthode OnError au niveau de la page, soit la méthode Application_Error dans global.asax, puis vérifier s'il s'agit d'un échec de la demande maximale et, si c'est le cas, transférer vers 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;
}

2 votes

Merci. OnError n'a pas fonctionné, mais Application_Error a fonctionné. Nous avons en fait un gestionnaire pour cela, mais quelqu'un l'avait désactivé dans le code.

0 votes

Même il y a deux ans, mais je veux quand même demander si cela a bien fonctionné jusqu'à maintenant ? la comparaison des chaînes de 'GetEntireRawContent' fonctionne-t-elle bien ? Je ne pense pas qu'il s'agisse d'un problème de délai d'attente. Y a-t-il quelqu'un qui puisse m'indiquer le chemin de l'éclaircie à ce sujet ?

0 votes

@Elaine : oui, cette technique fonctionne toujours avec ASP.Net 4.0. Si vous essayez de télécharger une demande qui est plus grande que la longueur maximale de la demande, ASP.Net jette une HttpException avec le code de timeout. Regardez dans System.Web.HttpRequest.GetEntireRawContent() en utilisant reflector.

58voto

Jonathan Parker Points 4206

Comme GateKiller l'a dit, vous devez modifier la longueur maximale des requêtes. Vous devrez peut-être aussi modifier l'executionTimeout au cas où la vitesse de téléchargement serait trop lente. Notez que vous ne voulez pas que ces paramètres soient trop importants, sinon vous serez exposé à des attaques DOS.

La valeur par défaut de l'option executionTimeout est de 360 secondes ou 6 minutes.

Vous pouvez modifier les paramètres maxRequestLength et executionTimeout à l'aide de la commande É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 traiter l'exception sans tenir compte de l'exception, vous devrez, comme cela a déjà été dit, la traiter dans Global.asax. Voici un lien vers un exemple de code .

2 votes

Merci pour votre réponse, mais comme je l'ai dit dans mon commentaire à la réponse de GK, cela ne résout pas vraiment mon problème. Il ne s'agit pas non plus d'un problème de délai d'attente, car l'exception est levée instantanément. Je vais modifier la question pour que ce soit plus clair.

4 votes

L'url de l'exemple de code pointe vers une page qui n'est pas disponible...quelqu'un peut-il résoudre ce problème ?

20voto

GateKiller Points 19113

Vous pouvez résoudre ce problème en augmentant la longueur maximale des requêtes 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 100Mb.

19 votes

Oui, et non. Vous poussez la limite plus loin, mais cela ne gère pas vraiment l'exception. Vous aurez toujours le même problème si quelqu'un essaie de télécharger 101+ Mb. La limite doit vraiment être de 5 Mo.

10voto

Andrew Points 380

Si vous souhaitez également une validation côté client afin de réduire la nécessité de lancer des exceptions, vous pouvez essayer d'implémenter une validation de la taille du fichier côté client.

Remarque : 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>

9voto

Vinod T. Patil Points 1272

Salut solution mentionnée par Damien McGivern, ne fonctionne que sur IIS6,

Il ne fonctionne pas sur IIS7 et le serveur de développement ASP.NET. J'obtiens une page affichant "404 - Fichier ou répertoire non trouvé".

Des idées ?

EDIT :

Je l'ai... Cette solution ne fonctionne toujours pas sur ASP.NET Development Server, mais j'ai trouvé la raison pour laquelle elle ne fonctionnait pas sur IIS7 dans mon cas.

En effet, IIS7 dispose d'un système intégré d'analyse des demandes qui impose un plafond pour les fichiers à télécharger, fixé par défaut à 30000000 octets (soit un peu moins de 30 Mo).

J'ai essayé de télécharger un fichier de 100 Mo pour tester la solution mentionnée par Damien McGivern (avec maxRequestLength="10240", c'est-à-dire 10 Mo dans web.config). Maintenant, si je télécharge le fichier d'une taille > 10MB et < 30 MB, la page est redirigée vers la page d'erreur spécifiée. Mais si la taille du fichier est > 30 Mo, la page d'erreur intégrée laide s'affiche et indique "404 - File or directory not found".

Pour éviter cela, vous devez donc augmenter la longueur maximale autorisée du contenu de la requête 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 fixé la longueur maximale du contenu à 200 Mo.

Après avoir effectué ce réglage, la page est redirigée avec succès vers ma page d'erreur lorsque j'essaie de télécharger un fichier de 100 Mo.

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

0 votes

Désolé ! J'ai ajouté ma requête en tant que réponse, je ne sais pas comment ajouter des commentaires aux articles existants.

1 votes

Vous devez simplement avoir plus de représentants pour commenter les messages. Voir la faq pour plus de détails sur ce que vous pouvez/ne pouvez pas faire avec votre représentant actuel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X