【问题标题】:ASP.NET MVC, Url Routing: Maximum Path (URL) LengthASP.NET MVC,Url 路由:最大路径 (URL) 长度
【发布时间】:2010-11-14 05:14:37
【问题描述】:

情景

我有一个应用程序,我们采用了良好的旧查询字符串 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 中检测到无效字符。

当我们的 URL 超过一定长度时,IIS 会抛出这个错误。

细枝末节

这是我们发现的:

这不是 IIS 问题

IIS确实有最大路径长度限制,但上面的错误不是这个。

学习dot iis dot net 如何使用请求过滤 “基于请求限制的过滤器”部分

如果路径对于 IIS 来说太长,它会抛出 404.14,而不是 400.0。

此外,IIS 最大路径(和查询)长度是可配置的:

<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 url MAX_PATH 限制 问题ID265251

问题

那么问题是什么?

问题是,这个限制有多大?

对于我的应用来说,它是一个交易杀手。对于大多数应用来说,这可能不是问题。

披露呢?没有任何地方提到过 ASP.NET 路由,我从来没有听说过这个限制。 ASP.NET MVC 使用 ASP.NET 路由这一事实使其影响更大。

你怎么看?

【问题讨论】:

    标签: asp.net-mvc iis url routing asp.net-routing


    【解决方案1】:

    我最终在 web.config 中使用以下内容使用 Mvc2 和 .Net Framework 4.0 解决了这个问题

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

    【讨论】:

    • 最大网址长度可以是2097151。
    • nogo 为 260 段限制,也更改了 support.microsoft.com/en-us/kb/820129 UrlSegmentMaxCount 也 nogo
    • 是的,relaxedUrlToFileSystemMapping 是唯一的方法
    • 我不需要 RelaxUrlToFileSystemMapping 来纠正长 URL 上的 HTTP 400 错误;只需设置 maxUrlLength 就可以了。
    • .NET MAXPATH 限制现已在 4.6.2 (blogs.msdn.microsoft.com/dotnet/2016/08/02/…) 中解决
    【解决方案2】:

    要解决这个问题,请执行以下操作:

    在您项目的根 web.config 中,在 system.web 节点下:

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

    此外,我必须在 system.webServer 节点下添加它,否则我的长查询字符串出现安全错误:

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

    【讨论】:

    • 它对我有用,system.webServer 节点很重要!
    • @edelwater 似乎与再次检查文件系统规则有关,但将 RelaxUrlToFileSystemMapping 设置为 true 也无济于事。
    • 解决了我在 rest api 应用程序中处理非常长的 GET 查询的问题
    【解决方案3】:

    Http.sys 服务的编码默认为每个 Url 段最多 260 个字符。

    此上下文中的“Url 段”是Url 中“/”字符之间的内容。例如:

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

    可以通过注册表设置更改允许的最大 URL 段长度:

    • 密钥:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
    • 值:UrlSegmentMaxLength
    • 类型:REG_DWORD
    • 数据:(您所需的新 URL 段最大允许长度,例如 4096)

    有关 http.sys 设置的更多信息: http://support.microsoft.com/kb/820129

    允许的最大值为 32766。如果指定了更大的值,它将被忽略。 (来源:胡安·门德斯)

    需要重新启动 PC 才能使对此设置的更改生效。 (图片来源:David Rettenbacher、Juan Mendes)

    【讨论】:

    • 这也为我修复了它。我们有一个非常长的 url 段(注意:不是总 url 长度),这导致了问题。我想在这种情况下,当单个 url 段超过 260 个字符时,你是否做对了?
    • 值得注意的是,此设置需要重新启动才能生效。
    • 机器重启还是只是 IIS?
    • 我不得不重新启动整个机器。 警告:我最初将此值设置得太高 (2097151),但它没有坚持下去。当我查看答案中链接的文档并看到最大值为 32766 时,它终于起作用了
    • 我在 Win Server 08 上的注册表中没有看到此设置。我认为需要添加此设置。请说明是否需要将其添加为键或 dword / 等。谢谢。
    【解决方案4】:

    好的,所以我发布此内容的部分原因也是因为我们找到了解决方法。

    我希望这对将来的某人有用:D

    解决方法

    解决方法很简单,也很不错。

    由于我们知道站点的哪些部分需要使用动态参数(因此将具有动态路径和长度),我们可以通过在它到达 ASP 之前拦截它来避免将这个长 url 发送到 ASP.NET 路由。网络

    输入 IIS7 Url Rewriting(或任何等效的重写模块)。

    我们这样设置规则:

        <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 的其余部分去哪里了?

    好吧,当触发重写规则时,IIS7 URL 重写模块会自动在请求中设置此标头:

    HTTP_X_ORIGINAL_URL
    

    下游,在app解析动态路径的部分,而不是看路径:

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

    这包括使用 ASP.NET MVC HtmlHelperUrlHelper 方法定义的 URL(如 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 中。原因是我稍后需要访问标头值请求管道。)

    希望这会有所帮助!

    【讨论】:

    • 请问你能把这个设为答案吗?
    • 我根据您的要求将此设置为答案。
    • 如果我这样做,是否还需要更改 web.config 文件?我想避免更改 web.config 文件,这样我就可以只允许对一个特定 URL 的长请求,而对所有其他 URL 正常阻止它们。
    【解决方案5】:

    我在使用 ASP.NET Web API 4 时遇到了类似的最大 URL 长度问题,它产生了一个略有不同的错误:

    404 Error

    上面通过使用以下两个标签更新 Web.config 对我的修复进行了描述:

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

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

    【讨论】:

      【解决方案6】:

      我认为您正在努力使用 GET。尝试将请求方法更改为 POST 并将这些查询字符串参数放入请求正文中。

      长 URL 对 SEO 也没有帮助,是吗?

      【讨论】:

      • 我使用 GET 有两个原因:1) 这些 URL 需要共享,并且需要持久 2) 我没有发布任何内容。这是一个读操作。 > 长 URL 对 SEO 也没有帮助,是吗?我不确定,但如果请求很复杂,那么查询也很复杂......除非我使用非语义 URL,否则无法解决这个问题。
      【解决方案7】:

      硬编码的最大 URL 长度似乎是 fixed in .NET 4.0。特别是,现在有一个 web.config 部分,其中包含:

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

      让您扩大允许的 URL 范围。

      【讨论】:

      • Joannes,感谢您更新此主题。这计划在 .NET 4 中修复,幸运的是它已经成功了。
      • 很遗憾,这是不正确的。微软改变主意,改成lmingle给出的答案。即类似于
      • Dommer,Joannes,感谢您跟进此事。我已经相应地更改了接受的答案。不过,我无法验证自己。
      猜你喜欢
      • 1970-01-01
      • 2010-11-22
      • 2010-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多