wake-up-neo.net

ASP.NET MVC, URL-Routing: Maximale Pfadlänge (URL)

Das Szenario

Ich habe eine Anwendung, bei der die gute alte URL-Struktur der Abfragezeichenfolge verwendet wurde:

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

und änderte es in eine Pfadstruktur:

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

Wir verwenden ASP.NET MVC und (natürlich) ASP.NET-Routing.

Das Problem

Das Problem ist, dass unsere Parameter dynamisch sind, und es gibt (theoretisch) keine Begrenzung für die Anzahl der Parameter, die wir berücksichtigen müssen.

Dies ist alles in Ordnung, bis wir von folgendem Zug getroffen wurden:

HTTP-Fehler 400.0 - Fehlerhafte Anforderung ASP.NET hat ungültige Zeichen in der URL gefunden.

IIS würde diesen Fehler auslösen, wenn unsere URL eine bestimmte Länge überschritten hat.

Die Nitty Gritty

Folgendes haben wir herausgefunden:

Dies ist kein IIS Problem

IIS hat eine maximale Pfadlängenbegrenzung, der obige Fehler liegt jedoch nicht darin.

Lernen Sie dot iis dot netWie verwenden Sie die Anforderungsfilterung Abschnitt "Filtern basierend auf Anforderungslimits"

Wenn der Pfad für IIS zu lang wäre, würde er 404.14 und nicht 400.0 werfen.

Außerdem ist die Länge von IIS max Pfad (und Abfrage) konfigurierbar:

<requestLimits


   maxAllowedContentLength="30000000"


   maxUrl="260"


   maxQueryString="25" 


              />

Dies ist ein ASP.NET-Problem

Nach einigem Stöbern:

IIS-Foren Thread: Maximale URL-Länge von ASP.NET 2.0? http://forums.iis.net/t/1105360.aspx

es stellt sich heraus, dass dies ein ASP.NET-Problem (naja, wirklich .NET) ist.

Der Kern der Sache ist, dass ASP.NET, soweit ich das beurteilen kann, keine Pfade verarbeiten kann, die länger als 260 Zeichen sind.

Der Nagel im Sarg, in dem dies von Phil dem Haack selbst bestätigt wird:

Stack OverflowASP.NET URL MAX_PATH-Limit Frage-ID 265251

Die Frage

Also was ist die Frage?

Die Frage ist, wie groß die Einschränkung ist.

Für meine App ist es ein Dealkiller. Für die meisten Apps ist dies wahrscheinlich kein Problem.

Was ist mit der Offenlegung? Wo auch immer, wo ASP.NET Routing erwähnt wird, habe ich jemals einen Blick auf diese Einschränkung gehört. Die Tatsache, dass ASP.NET MVC ASP.NET-Routing verwendet, macht die Auswirkungen noch größer.

Was denkst du?

59
Martin Suchanek

Am Ende habe ich folgendes in der web.config verwendet, um dieses Problem mit Mvc2 und .Net Framework 4.0 zu lösen 

<httpRuntime maxUrlLength="1000" relaxedUrlToFileSystemMapping="true" />
46
lmingle

Um dies zu lösen, tun Sie dies:

In der Wurzel web.config für Ihr Projekt unter dem Knoten system.web:

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

Außerdem musste ich dies unter dem Knoten system.webServer hinzufügen, oder es wurde ein Sicherheitsfehler für meine langen Abfragezeichenfolgen angezeigt:

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxUrl="10999" maxQueryString="2097151" />
      </requestFiltering>
    </security>
...
26
theJerm

Der Http.sys-Dienst ist standardmäßig mit maximal 260 Zeichen pro URL-Segment codiert.

Ein "URL-Segment" ist in diesem Zusammenhang der Inhalt zwischen "/" - Zeichen in der URL. Zum Beispiel:

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

Die maximal zulässige URL-Segmentlänge kann mit den Registrierungseinstellungen geändert werden:

  • Schlüssel: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
  • Wert: UrlSegmentMaxLength
  • Geben Sie Folgendes ein: REG_DWORD
  • Daten: (Ihre gewünschte neue maximal zulässige Länge des URL-Segments, z. B. 4096)

Weitere Informationen zu den http.sys-Einstellungen: http://support.Microsoft.com/kb/820129

Der maximal zulässige Wert ist 32766. Wenn ein größerer Wert angegeben wird, wird er ignoriert. (Bildnachweis: Juan Mendes)

Der Neustart des PCs ist erforderlich, damit diese Einstellung wirksam wird. (Bildnachweis: David Rettenbacher, Juan Mendes)

23
David Richoz

OK, ein Teil des Grundes, den ich gepostet habe, war auch, dass wir eine Lösung gefunden haben.

Ich hoffe, dass dies in Zukunft für jemanden nützlich sein wird: D

Die Problemumgehung

Die Problemumgehung ist ziemlich einfach und auch ganz nett.

Da wir wissen, welche Teile der Website dynamische Parameter verwenden müssen (und daher einen dynamischen Pfad und eine Länge haben), können wir das Senden dieser langen URL an das ASP.NET-Routing vermeiden, indem sie abgefangen werden, bevor sie überhaupt auf ASP.NET stößt

Geben Sie IIS7 Url Rewriting (oder ein gleichwertiges Überschreibungsmodul) ein.

Wir haben eine Regel wie folgt aufgestellt:

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

Grundsätzlich halten wir einfach genug vom Pfad, um die richtige Route stromabwärts aufrufen zu können. Der Rest des URL-Pfads, den wir abhacken.

Wohin geht der Rest der URL?

Wenn eine Umschreibregel ausgelöst wird, setzt das IIS7-URL-Umschreibungsmodul diesen Header in der Anforderung automatisch:

HTTP_X_ORIGINAL_URL

Downstream in dem Teil der App, der den dynamischen Pfad analysiert, statt den Pfad zu betrachten:

HttpContext.Request.Url.PathAndQuery

wir schauen uns stattdessen diesen Header an:

HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]

Problem gelöst ... fast!

Die Haken

Zugriff auf die Kopfzeile

Wenn Sie wissen möchten, dass Sie auf den Header des IIS7-Rewrite-Moduls zugreifen können, haben Sie zwei Möglichkeiten:

HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]

oder

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

Relative Pfade reparieren

Sie werden auch bemerken, dass bei dem obigen Setup alle relativen Pfade unterbrochen werden (URLs, die mit einem "~" definiert wurden).

Dazu gehören URLs, die mit den ASP.NET-MVC-Methoden HtmlHelper und UrlHelper (wie Url.Route("Bla")) definiert wurden.

Hier ist der Zugriff auf den ASP.NET-MVC-Code hervorragend.

In der System.Web.Mvc.PathHelper.GenerateClientUrlInternal()-Methode wird geprüft, ob der gleiche URL-Rewrite-Modulheader vorhanden ist (siehe oben):

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

In diesem Fall wird daran gearbeitet, die Ursprungs-URL beizubehalten. 

In unserem Fall möchten wir diesen Vorgang kurzschließen, da wir das URL-Überschreiben nicht auf "normale" Weise verwenden.

Wir möchten so tun, als ob keine URL-Umschreibung erfolgt ist, da keine relativen Pfade im Kontext der ursprünglichen URL berücksichtigt werden sollen.

Der einfachste Hack, den ich mir vorstellen konnte, war, diese Servervariable vollständig zu entfernen, sodass ASP.NET MVC sie nicht finden würde:

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

(Beachten Sie, dass ich in der obigen Methode die Kopfzeile aus Request.ServerVariables entferne, sie aber weiterhin in Context.Items verstecke. Der Grund dafür ist, dass ich später in der Anforderungsleitung auf den Kopfzeilenwert zugreifen muss.)

Hoffe das hilft!

14
Martin Suchanek

Ich denke, du versuchst hart, GET einzusetzen. Ändern Sie die Anforderungsmethode in POST und fügen Sie diese Abfragezeichenfolgeparameter in den Anforderungstext ein.

Lange URL hilft SEO auch nicht, oder?

2
Adrian Godong

Es scheint, dass die fest codierte maximale URL-Länge in .NET 4.0 behoben war. Insbesondere gibt es jetzt einen web.config-Abschnitt mit:

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

damit können Sie den Bereich der zulässigen URLs erweitern.

1

Ich hatte ein ähnliches Problem mit der maximalen URL-Länge bei der Verwendung von ASP.NET Web API 4, was zu einem etwas anderen Fehler führte: 

404 Fehler

Das Update für mich wurde oben beschrieben, indem die Web.config mit BEIDEN der folgenden Tags aktualisiert wurde:

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

und

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxUrl="10999" maxQueryString="2097151" />
      </requestFiltering>
    </security>
0
J. Ventry