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

情景

我有一个应用程序,我们采取了旧的查询stringURL结构:

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

并将其改为path结构:

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

我们正在使用ASP.NET MVC和(自然)ASP.NET路由。

问题

问题是我们的参数是dynamic的,并且(理论上)我们需要适应的参数数量是没有限制的。

直到我们被下列火车撞到,这一切都很好:

HTTP错误400.0 – 错误的请求ASP.NET检测到URL中的无效字符。

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

Nitty砂砾

以下是我们发现的:

这不是一个IIS问题

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

了解点iis点networking如何使用请求过滤部分“基于请求限制的filter”

如果IIS的path太长,则会抛出404.14,而不是400.0。

此外,IIS最大path(和查询)的长度是可configuration的:

 <requestLimits maxAllowedContentLength="30000000" maxUrl="260" maxQueryString="25" /> 

这是一个ASP.NET问题

经过一番探讨:

IIS论坛主题:ASP.NET 2.0的最大URL长度? http://forums.iis.net/t/1105360.aspx

事实certificate,这是一个ASP.NET(好,.NET真的)问题。

问题的核心在于,据我所知,ASP.NET无法处理超过260个字符的path。

在棺材里的钉子,这是由菲尔哈克本人证实:

堆栈溢出ASP.NET URL MAX_PATH限制问题ID 265251

问题

那么问题是什么?

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

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

怎么披露? 没有提到ASP.NET路由的地方,我听说过这个限制的窥视。 ASP.NET MVC使用ASP.NET路由的事实使得这个影响更大。

你怎么看?

我结束了在web.config中使用以下使用Mvc2和.Net Framework 4.0来解决此问题

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

要解决这个问题,请这样做:

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

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

另外,我不得不在system.webServer节点下添加它,否则我的长查询string出现安全错误:

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

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

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

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

允许的最大URL长度可以通过registry设置来更改:

  • 注意: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
  • 值: UrlSegmentMaxLength
  • 键入:REG_DWORD
  • 数据:(你想要的新的URL段最大允许长度,例如4096)

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

允许的最大值是32766.如果指定的值较大,则会被忽略。 (信用:胡安·门德斯)

重新启动电脑需要对此设置进行更改才能生效。 (信用:David Rettenbacher,胡安·门德斯)

好,所以我发布这个的原因也是因为我们find了解决办法。

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

解决方法

解决方法非常简单,也很好。

由于我们知道网站的哪些部分需要使用dynamic参数(因此会有一个dynamic的path和长度),所以我们可以避免在连接到ASP.NET之前通过拦截来将这个长的url发送到ASP.NET路由

inputIIS7 Url重写(或任何等效的重写模块)。

我们build立这样一个规则:

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

基本上,我们所做的只是保持足够的path,以便能够调用正确的下游路线。 剩下的URLpath,我们正在黑客。

URL的其余部分在哪里?

那么,当重写规则被触发时,IIS7 URL重写模块自动在请求中设置这个头部:

 HTTP_X_ORIGINAL_URL 

在下游,在parsingdynamicpath的应用程序部分,而不是查看path:

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

修复相对path

你还会注意到,通过上面的设置,所有的相对path都会中断(用“〜”定义的URL)。

这包括使用ASP.NET MVC HtmlHelperUrlHelper方法(如Url.Route("Bla") )定义的URL。

这是访问ASP.NET MVC代码真棒。

System.Web.Mvc.PathHelper.GenerateClientUrlInternal()方法中,检查是否存在相同的URL Rewrite模块头(请参阅上文):

 // 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的上下文中考虑相对path。

我能想到的最简单的方法是完全删除服务器variables,所以ASP.NET MVC不会find它:

 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 ,原因是我需要访问请求pipe道中的头值。)

希望这可以帮助!

我想你正在努力使用GET。 尝试将请求方法更改为POST,并将这些查询string参数放入请求正文中。

长URL也不能帮助search引擎优化,是吗?

现在可能没什么问题…但是这对我来说很有效(因为我没有使用aspx文件,所以我敢打赌,这可以用于MVC):

http://blogs.iis.net/rakkimk/archive/2008/10/10/asp-net-2-0-x64-you-may-get-http-400-bad-request-or-error-as-在-kb的提及–932552或- 826437.aspx

看起来硬编码的最大URL长度已经在.NET 4.0中修复了 。 特别是,现在有一个web.config部分:

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

允许您扩展允许的URL范围。