ASP.NET MVC,URL路由:最大路径(URL)长度(ASP.NET MVC, Url Rou

2019-06-17 16:09发布

场景

我在这里我们把美好的旧查询字符串的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会抛出这个错误。

细节问题

下面是我们发现:

这不是一个IIS问题

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

学习“基于请求限制过滤器”点IIS点网如何使用请求筛选科

如果路径太长了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网址MAX_PATH限制问题ID 265251

问题

那么,有什么问题?

现在的问题是,一个限制是多大呢?

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

怎么样披露? 无论身在何处ASP.NET路由提到我在哪里听说过有关此限制的窥视。 这ASP.NET MVC使用ASP.NET路由的事实使得这种更大的影响。

你怎么看?

Answer 1:

我结束了使用在web.config以下解决使用MVC2和.NET Framework 4.0这个问题

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


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


Answer 3:

HTTP.SYS服务是编码与默认的最大的每地址段260个字符。

一个“地址段”在此上下文中是在URL“/”字符之间的内容。 例如:

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

最大允许的地址段长度可以用注册表设置进行更改:

  • 关键: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
  • 价值: UrlSegmentMaxLength
  • 类型:REG_DWORD
  • 数据:(你所需的新地址段允许的最大长度,例如4096)

更多关于HTTP.SYS设置: http://support.microsoft.com/kb/820129

最大允许值是32766如果指定一个较大的值,它会被忽略。 (来源:胡安·门德斯)

重新启动PC,需要做出改变这个设置生效。 (来源:大卫Rettenbacher,胡安·门德斯)



Answer 4:

行,所以我公布这部分原因是还因为我们已经找到一个变通。

我希望这将是有人在将来有用:d

解决方法

解决方法很简单,这是相当不错的了。

因为我们知道该网站的部分将需要使用动态参数(因此将有一个动态路径和长度),我们能够避免它甚至命中ASP.NET之前拦截它发送这个长的URL到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的休息去吧?

那么,当一个重写规则被激发,IIS7的URL重写模块自动地设置在请求这个头:

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

这包括与ASP.NET MVC定义的URL HtmlHelperUrlHelper方法(如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 。这样做的原因是,我需要在请求管道进入头值以后。)

希望这可以帮助!



Answer 5:

我想你想很难使用GET。 试着改变请求方法POST并把这些查询字符串参数到请求主体。

长URL不利于SEO为好,不是吗?



Answer 6:

看来,硬编码的最大URL长度已被固定在.NET 4.0中 。 特别是,现在有一个web.config有部分:

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

可以让你扩大允许的URL的范围。



Answer 7:

我在使用的ASP.NET Web API 4,这产生了稍微不同的错误类似的最大URL长度问题:

404错误

对我来说,修复程序通过以下两个标签更新的Web.config上述:

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

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


文章来源: ASP.NET MVC, Url Routing: Maximum Path (URL) Length