ASP.NET MVC, routage D'Url: Longueur de chemin (URL) maximale

Le Scénario

j'ai une application où nous avons pris la bonne vieille structure D'URL de chaîne de requête:

?x=1&y=2&z=3&a=4&b=5&c=6

et changé en une structure de chemin:

/x/1/y/2/z/3/a/4/b/5/c/6

on utilise ASP.NET MVC et (naturellement) ASP.NET routage.

Le Problème

le problème est que nos paramètres sont dynamiques, et il n'y a (théoriquement) aucune limite à la quantité de paramètres que nous nécessité d'en tenir compte.

tout va bien jusqu'à ce que nous soyons percutés par le train suivant:

erreur HTTP 400.0-mauvaise requête ASP.NET détection de caractères invalides dans L'URL.

IIS lancerait cette erreur lorsque notre URL a dépassé une certaine longueur.

The Nitty Gritty

voici ce que nous avons découvert:

ce n'est pas un problème IIS

IIS n'avoir qu'un maximum de longueur de chemin de limite, mais l'erreur ci-dessus n'est-ce pas.

apprendre dot iis dot net Comment utiliser le filtrage des requêtes Section "Filtre basé sur les limites de requête "

si le chemin était trop long pour IIS, il lancerait un 404.14, pas un 400.0.

de plus, la longueur du chemin (et de la requête) IIS max est configurable:

<requestLimits


   maxAllowedContentLength="30000000"


   maxUrl="260"


   maxQueryString="25" 


              />

C'est un ASP.NET problème

après quelques recherches:

IIS Forums Fil: ASP.NET 2.0 longueur maximale de L'URL? http://forums.iis.net/t/1105360.aspx

il s'avère que c'est un ASP.NET (Eh bien, .NET vraiment) problème.

le cœur de la question Est que, pour autant que je puisse dire, ASP.NET ne peut pas gérer des chemins de plus de 260 caractères.

Le clou dans le cercueil que cela est confirmé par Phil le Haack lui-même:

Débordement De La Cheminée ASP.NET url MAX_PATH limit Question ID 265251

La Question

Quelle est la question?

la question Est, Quelle est la taille d'une limitation est-ce?

pour mon application, c'est un tueur à gages. Pour la plupart des applications, il est probablement un non-problème.

Qu'en est-il de la divulgation? Non, où ça? ASP.NET le routage est mentionné ai-je jamais entendu parler de cette limitation? Le fait que ASP.NET utilisations de MVC ASP.NET le routage rend l'impact encore plus grand.

Qu'en pensez-vous?

53
demandé sur Community 2009-07-27 02:29:45

7 réponses

j'ai fini par utiliser ce qui suit sur le web.config pour résoudre ce problème en utilisant Mvc2 et .net Framework 4.0

<httpRuntime maxUrlLength="1000" relaxedUrlToFileSystemMapping="true" />
42
répondu lmingle 2011-04-07 18:23:49

pour résoudre ceci, faites ceci:

dans le réseau racine.config pour votre projet, sous le système.nœud web:

<system.web>
    <httpRuntime maxUrlLength="10999" maxQueryStringLength="2097151" />
...

de plus, j'ai dû ajouter ceci dans le système.noeud webServer ou j'ai eu une erreur de sécurité pour mes longues chaînes de requête:

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxUrl="10999" maxQueryString="2097151" />
      </requestFiltering>
    </security>
...
24
répondu theJerm 2014-07-09 19:07:39

Http.le service sys est codé avec un maximum par défaut de 260 caractères par segment D'Url.

un" segment D'Url "dans ce contexte est le contenu entre les caractères" / " dans l'Url. Par exemple:

http://www.example.com/segment-one/segment-two/segment-three

la longueur maximale permise du segment D'Url peut être modifiée avec les paramètres de registre:

  • clé: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
  • valeur: UrlSegmentMaxLength
  • Type: REG_DWORD
  • Données: (votre nouveau segment D'Url désiré longueur maximale autorisée, par exemple 4096)

plus d'informations sur http.paramètres sys: http://support.microsoft.com/kb/820129

la valeur maximale autorisée est 32766. Si une plus grande valeur est spécifiée, elle sera ignorée. (Crédit: Juan Mendes)

redémarrer le PC est nécessaire pour faire un changement à ce réglage prendre effet. (Crédit: David Rettenbacher, Juan Mendes)

22
répondu David Richoz 2016-02-10 15:06:16

OK donc une partie de la raison pour laquelle j'ai posté ceci était aussi parce que nous avons trouvé un travail autour.

j'espère que cela sera utile à quelqu'un dans le futur :d

la solution

le contournement est assez simple, et il est assez agréable aussi.

étant donné que nous savons quelles parties du site devront utiliser des paramètres dynamiques (et auront donc un chemin et une longueur dynamiques), nous pouvons éviter d'envoyer ce long url to ASP.NET routage en l'interceptant avant même qu'il ne frappe ASP.NET

entrez la réécriture de L'Url IIS7 (ou tout autre module de réécriture équivalent).

nous avons mis en place une règle comme celle-ci:

    <rewrite>
        <rules>
            <rule>
                <rule name="Remove Category Request Parameters From Url">
                <match url="^category/(\d+)/{0,1}(.*)$" />
                <action type="Rewrite" url="category/{R:1}" />
            </rule>
        </rules>
    </rewrite>

En Gros, ce que nous faisons, c'est simplement garder assez du chemin pour pouvoir appeler la bonne route en aval. Le reste du chemin D'URL que nous sommes en train de pirater.

où va le reste de L'URL?

Eh bien, lorsqu'une règle de réécriture est lancée, le module de réécriture D'URL IIS7 définit automatiquement cet en-tête dans la requête:

HTTP_X_ORIGINAL_URL

en aval, dans la partie de l'application qui analyse le chemin dynamique, au lieu de regarder le chemin:

HttpContext.Request.Url.PathAndQuery

nous regardons cet en-tête à la place:

HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]

Problème résolu... presque!

Accrocs

accéder au En-tête

si vous avez besoin de savoir, pour accéder à L'en-tête du Module de réécriture IIS7, vous pouvez le faire de deux façons:

HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]

ou

HttpContext.Request.Headers["X-ORIGINAL-URL"]

La Fixation Des Chemins Relatifs

ce que vous remarquerez également est que, avec la configuration ci-dessus, tous les chemins relatifs se brisent (URLs qui ont été définis avec un"~").

Cela inclut les URLs définies avec le ASP.NET MVC HtmlHelper et Méthodes UrlHelper (comme Url.Route("Bla") ).

c'est là que l'accès au ASP.NET le code MVC est génial.

dans la méthode System.Web.Mvc.PathHelper.GenerateClientUrlInternal() , il y a une vérification en cours pour voir si L'en-tête de module de réécriture D'URL existe (voir ci-dessus):

// we only want to manipulate the path if URL rewriting is active, else we risk breaking the generated URL
NameValueCollection serverVars = httpContext.Request.ServerVariables;
bool urlRewriterIsEnabled = (serverVars != null && serverVars[_urlRewriterServerVar] != null);
if (!urlRewriterIsEnabled) {
    return contentPath;
}

S'il le fait, un certain travail est fait pour préserver L'URL d'origine.

dans notre cas, puisque nous n'utilisons pas la réécriture D'URL de la manière "normale", nous voulons de court-circuiter ce processus.

nous voulons prétendre qu'aucune réécriture D'URL ne s'est produite, car nous ne voulons pas que les chemins relatifs soient considérés dans le contexte de l'URL originale.

le hack le plus simple que j'ai pu imaginer était de supprimer complètement cette variable de serveur, donc ASP.NET MVC ne le trouverait pas:

protected void Application_BeginRequest()
{
    string iis7UrlRewriteServerVariable = "HTTP_X_ORIGINAL_URL";

    string headerValue = Request.ServerVariables[iis7UrlRewriteServerVariable];

    if (String.IsNullOrEmpty(headerValue) == false)
    {
        Request.ServerVariables.Remove(iis7UrlRewriteServerVariable);

        Context.Items.Add(iis7UrlRewriteServerVariable, headerValue);
    }
}

(notez que, dans la méthode ci-dessus, j'enlève l'en-tête de Request.ServerVariables mais je le conserve toujours), je le planque dans Context.Items . La raison en est que j'ai besoin d'accéder à la valeur de l'en-tête plus tard dans le tube de requête.)

Espérons que cette aide!

14
répondu Martin Suchanek 2009-07-26 22:54:09

je pense que vous essayez de difficilement utiliser GET. Essayez de changer la méthode request pour POST et mettez ces paramètres de chaîne de requête dans le corps de la requête.

longue URL n'aide pas SEO aussi bien, n'est-ce pas?

2
répondu Adrian Godong 2009-07-26 22:36:59

il apparaît que la longueur d'URL maximale codée en dur a été fixée dans .NET 4.0 . En particulier, il y a maintenant une section web.config avec:

<httpRuntime maxRequestPathLength="260" maxQueryStringLength="2048" /> 

qui vous permettent d'étendre la portée des URLs autorisées.

1
répondu Joannes Vermorel 2011-04-05 09:23:15

j'avais un problème similaire de longueur D'URL Max en utilisant ASP.NET Web API 4, qui a généré une erreur légèrement différente:

erreur 404

le correctif pour moi a été décrit ci-dessus en mettant à jour le Web.config avec les deux tags suivants:

<system.web>
    <httpRuntime maxUrlLength="10999" maxQueryStringLength="2097151" />

et

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxUrl="10999" maxQueryString="2097151" />
      </requestFiltering>
    </security>
0
répondu J. Ventry 2018-08-20 17:34:12