ASP.NET MVC, url Routing: максимальная длина пути (URL)



Сценарий



у меня есть приложение, где мы взяли старую добрую структуру URL строки запроса:



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


и изменил его в путь структуру:



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


мы используем ASP.NET MVC и (естественно) ASP.NET маршрутизация.



Проблема



проблема в том, что наши параметры являются динамическими, и нет (теоретически) никаких ограничений на количество параметров, которые мы должны учитывать.



Это все нормально пока нас не сбил следующий поезд:




ошибка HTTP 400.0-неверный запрос
ASP.NET обнаружены недопустимые символы в URL-адресе.




IIS выдаст эту ошибку, когда наш URL-адрес прошел определенную длину.



Вшивый Песчаный



вот что мы выяснили:



это не проблема IIS



IIS имеет максимальный предел длины пути, но выше ошибка не это.



узнать точку iis точка сеть
Как использовать фильтрацию запросов
Раздел "фильтр на основе ограничений запроса"



если путь был слишком длинным для IIS, он будет выбрасывать 404.14, а не 400.0.



кроме того, длина пути IIS max (и запроса) настраивается:



<requestLimits


maxAllowedContentLength="30000000"


maxUrl="260"


maxQueryString="25"


/>


это Ан ASP.NET проблема



после некоторого ковыряния вокруг:



форумы IIS
Нить: ASP.NET 2.0 максимальная длина URL?
http://forums.iis.net/t/1105360.aspx



получается что это такое ASP.NET (ну, .NET действительно) проблема.



суть дела в том, что, насколько я могу судить, ASP.NET не может обрабатывать пути длиной более 260 символов.



гвоздь в гробу в том, что это подтверждается самим Филом Хааком:



Переполнение Стека
Предел ASP.NET в max_path URL-адрес
Вопрос код 265251



Вопрос



так в чем вопрос?



вопрос в том, насколько большие ограничения это?



для моего приложения, это убийца сделки. Для большинства приложений это, вероятно, не проблема.



насчет раскрытия? Нет Где где ASP.NET маршрутизация упоминается я когда-нибудь слышал писк об этом ограничении. Дело в том, что ASP.NET MVC использует ASP.NET маршрутизация делает влияние этого еще больше.



что вы думаете?

866   7  

7 ответов:

в конечном итоге я использовал следующее в интернете.конфигурация для решения этой проблемы с помощью Mvc2 и .Net Framework 4.0

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

чтобы решить эту проблему, делаем так:

в корневой паутине.конфигурация для вашего проекта, в системе.веб-узел:

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

кроме того, мне пришлось добавить это в систему.узел веб-сервера или я получил ошибку безопасности для моих длинных строк запроса:

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

Http.служба sys кодируется с максимальным значением по умолчанию 260 символов на сегмент Url.

"сегмент Url" в этом контексте-это содержимое между символами " / " в Url. Например:

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

максимальная разрешенная длина сегмента Url может быть изменена с помощью параметров реестра:

    Итак, отчасти поэтому я написал это потому, что мы обойти.

    я надеюсь, что это будет полезно кому-то в будущем :D

    решение

    обходной путь довольно прост, и это довольно приятно тоже.

    поскольку мы знаем, какие части сайта должны будут использовать динамические параметры (и, следовательно, будут иметь динамический путь и длину), мы можем избежать отправки этого длинного url-адреса ASP.NET маршрутизация путем ее перехвата прежде чем он даже попадает ASP.NET

    введите IIS7 Url перезапись (или любой эквивалентный модуль перезаписи).

    мы установили такое правило:

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

    в основном, то, что мы делаем, просто сохраняет достаточно пути, чтобы иметь возможность называть правильный маршрут вниз по течению. Остальную часть URL-пути мы взламываем.

    куда идет остальная часть URL?

    Ну, когда правило перезаписи запускается, модуль перезаписи URL IIS7 автоматически устанавливает этот заголовок в запросе:

    HTTP_X_ORIGINAL_URL
    

    вниз по течению, в той части приложения, которая анализирует динамический путь, вместо того, чтобы смотреть на путь:

    HttpContext.Request.Url.PathAndQuery
    

    вместо этого мы смотрим на этот заголовок:

    HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]
    
    решена... почти!

    Корягах

    доступ к заголовок

    в случае, если вам нужно знать, чтобы получить доступ к заголовку модуля перезаписи IIS7, вы можете сделать это за два способы:

    HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]
    

    или

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

    Фиксация Относительных Путей

    вы также заметите, что при вышеуказанной настройке все относительные пути ломаются (URL-адреса, которые были определены с помощью "~").

    сюда входят URL-адреса, определенные с помощью ASP.NET MVC HtmlHelper и UrlHelper методы (например,Url.Route("Bla")).

    это где доступ к ASP.NET MVC код является удивительным.

    на System.Web.Mvc.PathHelper.GenerateClientUrlInternal() метод, есть проверка делается, чтобы увидеть если существует один и тот же заголовок модуля перезаписи URL (см. выше):

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

    если это так,то некоторые работы выполняются для сохранения исходного URL.

    в нашем случае, поскольку мы не используем перезапись URL "нормальным" способом, мы хотим закоротить этот процесс.

    мы хотим притвориться, что переписывание URL не произошло, так как мы не хотим, чтобы относительные пути рассматривались в контексте исходного URL.

    самый простой хак, который я мог придумать было удалить эту переменную сервера полностью, так что ASP.NET MVC не нашел бы его:

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

    (обратите внимание, что в приведенном выше методе я удаляю заголовок из Request.ServerVariables, но все еще сохраняя его, прятала его в Context.Items. Причина этого заключается в том, что мне нужен доступ к значению заголовка позже в канале запроса.)

    надеюсь, что это помогает!

    Я думаю, что вы пытаетесь трудно использовать GET. Попробуйте изменить метод запроса на POST и поместить эти параметры строки запроса в тело запроса.

    длинный URL также не помогает SEO, не так ли?

    похоже, что жестко заданная максимальная длина URL-адреса была исправлено в .NET 4.0. В частности, теперь есть web.config раздел:

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

    что позволяет расширить диапазон разрешенных URL-адресов.

    у меня была аналогичная проблема с максимальной длиной URL, используя ASP.NET Web API 4, который сгенерировал немного другую ошибку:

    Ошибка 404

    исправление для меня было описано выше, обновив веб.конфигурация с обоими из следующих тегов:

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

    и

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

    Comments

      Ничего не найдено.