ASP.NET MVC, Url Routing: Maksymalna długość ścieżki (URL)

Scenariusz

Mam aplikację, w której wzięliśmy starą, dobrą strukturę URL ciągu zapytania:

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

I zmienił ją w strukturę ścieżki:

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

Używamy ASP.NET MVC i (naturalnie) ASP.NET / align = "left" /

Problem

Problem polega na tym, że nasze parametry są dynamiczne i nie ma (teoretycznie) limitu ilości parametrów, dla których musimy pomieścić.

Wszystko jest w porządku, dopóki nie uderzymy w następujące pociąg:

Błąd HTTP 400.0 - złe żądanie ASP.NET wykryto nieprawidłowe znaki w adresie URL.

IIS wyrzuciłby ten błąd, gdy nasz adres URL przekroczy określoną długość.

The Nitty Gritty

Oto czego się dowiedzieliśmy:

To nie jest problem IIS

Program IIS ma limit maksymalnej długości ścieżki, ale powyższy błąd nie jest taki.

Learn dot iis Dot net Jak korzystać z filtrowania żądań Sekcja "filtr na podstawie limitów żądania"

Jeśli ścieżka była zbyt długa dla IIS, rzuciłaby 404.14, a nie 400.0.

Poza tym Maksymalna długość ścieżki (i zapytania) usługi IIS jest konfigurowalna:

<requestLimits


   maxAllowedContentLength="30000000"


   maxUrl="260"


   maxQueryString="25" 


              />

To jest ASP.NET Problem

Po jakimś szturchaniu:

IIS Forums Wątek: ASP.NET 2.0 maksymalna długość URL? http://forums.iis.net/t/1105360.aspx

Okazuje się, że jest to ASP.NET (no,. net naprawdę) problem.

Sednem sprawy jest to, o ile mogę powiedzieć, ASP.NET nie można obsługuje ścieżki dłuższe niż 260 znaków.

Gwóźdź do trumny w tym, że potwierdza to sam Phil Haack:

Przepełnienie Stosu ASP.NET url MAX_PATH limit Identyfikator pytania265251

Pytanie

Więc jakie jest pytanie? Pytanie brzmi, jak duże jest to ograniczenie? Dla mojej aplikacji, to zabójczy układ. W przypadku większości aplikacji prawdopodobnie nie jest to problem. A co z ujawnieniem? No where where ASP.NET Routing jest wymieniony czy kiedykolwiek słyszałem o tym ograniczeniu. Fakt, że ASP.NET zastosowania MVC ASP.NET routing sprawia, że wpływ tego jest jeszcze większy. Co o tym myślisz?
Author: Community, 2009-07-27

7 answers

Skończyło się na użyciu następujących W Sieci.config, aby rozwiązać ten problem przy użyciu Mvc2 i. Net Framework 4.0

<httpRuntime maxUrlLength="1000" relaxedUrlToFileSystemMapping="true" />
 42
Author: lmingle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-07 18:23:49

Aby to rozwiązać, zrób to:

W sieci głównej.config dla Twojego projektu, pod system.węzeł sieci:

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

Dodatkowo musiałem dodać to pod system.webServer node or I got a security error for my long query strings:

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxUrl="10999" maxQueryString="2097151" />
      </requestFiltering>
    </security>
...
 24
Author: theJerm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-09 19:07:39

Http.usługa sys jest kodowana domyślnie maksymalnie 260 znaków na segment Url.

"segment Url" w tym kontekście jest zawartością pomiędzy znakami " / " w adresie Url. Na przykład:

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

Maksymalna dozwolona długość segmentu Url może być zmieniona za pomocą ustawień rejestru:

  • Klucz: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
  • wartość: UrlSegmentMaxLength
  • Typ: REG_DWORD
  • Dane: (żądany nowy segment adresu URL maksymalna dozwolona długość, np. 4096)

Więcej o http.sys ustawienia: http://support.microsoft.com/kb/820129

Maksymalna dozwolona wartość to 32766. Jeśli podano większą wartość, zostanie ona zignorowana. (Kredyt: Juan Mendes)

Ponowne uruchomienie komputera jest wymagane, aby zmiana tego ustawienia weszła w życie. (Kredyt: David Rettenbacher, Juan Mendes)

 22
Author: David Richoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-10 15:06:16

OK więc po części napisałem to było również dlatego, że znaleźliśmy pracę wokół.

Mam nadzieję, że w przyszłości komuś się to przyda: d

Obejście pracy

Obejście jest dość proste i całkiem przyjemne.

Ponieważ wiemy, które części witryny będą musiały używać dynamicznych parametrów (a tym samym będą miały dynamiczną ścieżkę i długość), możemy uniknąć wysyłania tego długiego adresu url do ASP.NET routingu, przechwytując go zanim jeszcze uderzy ASP.NET

Wprowadź przepisywanie adresu URL IIS7(lub jakikolwiek równoważny moduł przepisywania).

Ustawiamy taką regułę:

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

Zasadniczo, to co robimy, to utrzymywanie wystarczającej ilości ścieżki, aby móc nazwać właściwą trasę w dół rzeki. Reszta ścieżki URL, którą hakujemy.

Gdzie znajduje się reszta adresu URL?

Cóż, gdy reguła przepisywania jest wywoływana, moduł przepisywania adresu URL IIS7 automatycznie ustawia ten nagłówek w zapytanie:

HTTP_X_ORIGINAL_URL
[14]} poniżej, w części aplikacji, która przetwarza ścieżkę dynamiczną, zamiast patrzeć na ścieżkę:
HttpContext.Request.Url.PathAndQuery

Zamiast tego patrzymy na ten nagłówek:

HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]
Problem rozwiązany... prawie!

The Snags

Dostęp do nagłówka

Jeśli chcesz wiedzieć, aby uzyskać dostęp do nagłówka modułu IIS7 Rewrite, możesz to zrobić na dwa sposoby:

HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]

Lub

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

Naprawianie Ścieżek Względnych

To, co również zauważysz, to że przy powyższej konfiguracji wszystkie ścieżki względne ulegają zerwaniu (adresy URL zdefiniowane przez "~").

Dotyczy to adresów URL zdefiniowanych za pomocą ASP.NET metody MVC HtmlHelper i UrlHelper (Jak Url.Route("Bla")).

Tutaj dostęp do ASP.NET kod MVC jest super.

W metodzie System.Web.Mvc.PathHelper.GenerateClientUrlInternal() wykonywane jest sprawdzenie, czy istnieje ten sam nagłówek modułu przepisywania adresu URL (patrz powyżej):

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

Jeśli tak się stanie, wykonywana jest pewna praca, aby zachować pochodzący adres URL.

W naszym przypadku, ponieważ nie używamy przepisywania adresów URL w "normalny" sposób, chcemy zwarcie tego procesu.

Chcemy udawać, że nie doszło do przepisania adresu URL, ponieważ nie chcemy, aby ścieżki względne były brane pod uwagę w kontekście oryginalnego adresu URL.

Najprostszym hackiem, jaki przyszło mi do głowy, było całkowite usunięcie tej zmiennej serwera, więc ASP.NET MVC nie znajdzie:

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

(zauważ, że w powyższej metodzie usuwam nagłówek z Request.ServerVariables ale nadal go zachowuję, schowanie go w Context.Items. Powodem tego jest to, że potrzebuję dostępu do wartości nagłówka później w potoku żądania.)

Mam nadzieję, że to pomoże!

 14
Author: Martin Suchanek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-26 22:54:09

Myślę, że starasz się ciężko wykorzystać GET. Spróbuj zmienić metodę żądania na POST i umieść te parametry ciągu zapytania w treści żądania.

Długi adres URL nie pomaga również w SEO, prawda?

 2
Author: Adrian Godong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-26 22:36:59

Wygląda na to, że maksymalna długość zakodowanego adresu URL została ustalona w. NET 4.0. W szczególności istnieje obecnie web.config sekcja z:

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

Które pozwalają rozszerzyć zakres dozwolonych adresów URL.

 1
Author: Joannes Vermorel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-05 09:23:15

Miałem podobny problem z maksymalną długością URL używając ASP.NET Web API 4, które generowało nieco inny błąd:

404 błąd

Poprawka dla mnie została opisana powyżej przez aktualizację sieci.config z obu następujących tagów:

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

I

<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxUrl="10999" maxQueryString="2097151" />
      </requestFiltering>
    </security>
 0
Author: J. Ventry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-20 17:34:12