Question

J'écris une fonction de téléchargement et j'ai des problèmes pour intercepter "System.Web.HttpException :Longueur maximale de la requête dépassée" avec des fichiers plus grands que la taille maximale spécifiée dans httpRuntimedans web.config (taille maximale définie sur 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 intercepter et gérer l’exception ?

MODIFIER: 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.

Était-ce utile?

La solution

Il n'y a pas moyen facile de prendre une telle exception, malheureusement. Ce que je fais est soit substituer la méthode OnError au niveau de la page ou Application_Error dans global.asax, puis vérifier si elle a été un échec de demande Max et, le cas échéant, le transfert 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");
    }
}

Il 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;
}

Autres conseils

Comme GateKiller l'a dit, vous devez modifier le maxRequestLength.Vous devrez peut-être également modifier l'exécutionTimeout au cas où la vitesse de téléchargement serait trop lente.Notez que vous ne voulez pas qu'aucun de ces paramètres soit trop grand, sinon vous serez exposé aux attaques DOS.

La valeur par défaut pour l'exécutionTimeout est de 360 ​​​​secondes ou 6 minutes.

Vous pouvez modifier le maxRequestLength et l'exécutionTimeout avec le Élément httpRuntime.

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

MODIFIER:

Si vous souhaitez gérer l'exception malgré tout, comme cela a déjà été indiqué, vous devrez la gérer dans Global.asax.Voici un lien vers un exemple de code.

Vous pouvez résoudre ce problème en augmentant la longueur maximale de la demande 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 une limite de 100Mo.

solution Salut mentionné par Damien McGivern, Fonctionne sur IIS6 seulement,

Il ne fonctionne pas sur IIS7 et serveur de développement ASP.NET. Je reçois la page affichant « 404 -. Fichier ou répertoire introuvable »

Toutes les idées?

EDIT:

Got it ... Cette solution ne fonctionne toujours pas sur ASP.NET Development Server, mais j'ai la raison pour laquelle il ne fonctionnait pas sur IIS7 dans mon cas.

La raison en est IIS7 a un balayage de demande intégré qui impose un plafond de fichier de chargement qui par défaut 30.000.000 octets (ce qui est un peu moins que 30 Mo).

Et j'ai essayé de télécharger le fichier d'une taille de 100 Mo pour tester la solution mentionnée par Damien McGivern (avec maxRequestLength = « 10240 » à savoir 10MB dans web.config). Si je télécharger le fichier de taille> 10 Mo et <30 Mo puis la page est redirigé vers la page d'erreur spécifiée. Mais si la taille du fichier est> 30 Mo il affiche la page d'erreur intégrée laid affichage « 404 -. Fichier ou répertoire introuvable »

Donc, pour éviter cela, vous devez augmenter au maximum. permis longueur du contenu de demande de votre site Web 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 paramètre, la page est succssfully redirigé vers ma page d'erreur lorsque je tente de télécharger le fichier de 100 Mo

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

Si vous manquez une validation côté client aussi si vous obtenez moins d'un besoin de lever des exceptions, vous pouvez essayer de mettre en œuvre la validation de la taille du fichier côté client.

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>

Voici une autre façon, qui ne comporte pas de « hacks », mais nécessite ASP.NET 4.0 ou version ultérieure:

//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
    }
}

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

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

puis lorsque vous gérez l'événement de téléchargement, vérifier la taille et si son sur une quantité spécifique, vous pouvez 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";
    }
}

Dans IIS 7 et au-delà:

fichier web.config:

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

Vous pouvez ensuite vérifier dans le code derrière, comme ceci:

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

Assurez-vous que la [Taille en octets] dans le web.config est supérieure à la taille du fichier que vous souhaitez télécharger, vous ne serez pas obtenir l'erreur 404. Vous pouvez alors vérifier la taille du fichier dans le code derrière l'utilisation de la ContentLength qui serait beaucoup mieux

Comme vous le savez sans doute, la longueur maximale de la demande est configurée dans DEUX endroits.

  1. maxRequestLength - contrôlé au niveau d'application ASP.NET
  2. maxAllowedContentLength - sous <system.webServer>, contrôlé au niveau IIS

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

Pour attraper LA SECONDE vous devez faire en global.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();
    }
}

Après la balise

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

ajouter la balise 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 à la page d'erreur ...

Vous pouvez résoudre ce problème en augmentant la longueur maximale de la demande et le temps d'exécution dans votre web.config:

-Veuillez clarifier le temps d'exécution maximum sur râpe puis 1200

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

Que diriez-vous 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);
        }
    }

Il peut être vérifié via:

        var httpException = ex as HttpException;
        if (httpException != null)
        {
            if (httpException.WebEventCode == System.Web.Management.WebEventCodes.RuntimeErrorPostTooLarge)
            {
                // Request too large

                return;

            }
        }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top