Mar*_*nek 65 iis url asp.net-mvc routing asp.net-routing
我有一个应用程序,我们采用了旧的查询字符串URL结构:
?x=1&y=2&z=3&a=4&b=5&c=6
Run Code Online (Sandbox Code Playgroud)
并将其更改为路径结构:
/x/1/y/2/z/3/a/4/b/5/c/6
Run Code Online (Sandbox Code Playgroud)
我们正在使用ASP.NET MVC和(自然地)ASP.NET路由.
问题是我们的参数是动态的,并且(理论上)我们需要适应的参数数量没有限制.
这一切都很好,直到我们受到以下列车的打击:
HTTP错误400.0 - 错误请求ASP.NET在URL中检测到无效字符.
当我们的URL超过一定长度时,IIS会抛出此错误.
这是我们发现的:
IIS确实有最大路径长度限制,但上面的错误不是这个.
了解dot iis dot net如何使用请求过滤部分"根据请求限制过滤"
如果IIS的路径太长,它将抛出404.14,而不是400.0.
此外,IIS最大路径(和查询)长度是可配置的:
<requestLimits
maxAllowedContentLength="30000000"
maxUrl="260"
maxQueryString="25"
/>
Run Code Online (Sandbox Code Playgroud)
经过一番探讨:
IIS论坛主题:ASP.NET 2.0最大URL长度? http://forums.iis.net/t/1105360.aspx
事实证明,这是一个ASP.NET(嗯,真正的.NET)问题.
事情的核心是,据我所知,ASP.NET无法处理超过260个字符的路径.
在棺材中的钉子,这是由菲尔哈克本人证实的:
Stack Overflow ASP.NET url MAX_PATH limit问题ID 265251
那么问题是什么?
问题是,这有多大的限制?
对于我的应用程序,它是一个交易杀手.对于大多数应用程序,它可能不是问题.
披露怎么样?没有提到ASP.NET路由的地方我听过这个限制的窥视.ASP.NET MVC使用ASP.NET路由这一事实使其影响更大.
你怎么看?
lmi*_*gle 46
我最终在web.config中使用以下内容来使用Mvc2和.Net Framework 4.0解决此问题
<httpRuntime maxUrlLength="1000" relaxedUrlToFileSystemMapping="true" />
Run Code Online (Sandbox Code Playgroud)
the*_*erm 28
要解决此问题,请执行此操作:
在项目的根web.config中,在system.web节点下:
<system.web>
<httpRuntime maxUrlLength="10999" maxQueryStringLength="2097151" />
...
Run Code Online (Sandbox Code Playgroud)
另外,我不得不在system.webServer节点下添加它,或者我的长查询字符串出现了安全性错误:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxUrl="10999" maxQueryString="2097151" />
</requestFiltering>
</security>
...
Run Code Online (Sandbox Code Playgroud)
小智 27
Http.sys服务的编码默认最多为每个Url段260个字符.
此上下文中的"网址片段"是网址中"/"字符之间的内容.例如:
http://www.example.com/segment-one/segment-two/segment-three
Run Code Online (Sandbox Code Playgroud)
可以使用注册表设置更改允许的最大Url段长度:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\ParametersUrlSegmentMaxLength有关http.sys设置的更多信息:http: //support.microsoft.com/kb/820129
允许的最大值为32766.如果指定的值较大,则将忽略该值.(图片来源:Juan Mendes)
需要重新启动PC才能使此设置更改生效.(图片来源:David Rettenbacher,Juan Mendes)
Mar*_*nek 16
好吧,所以我发布这个的部分原因也是因为我们找到了一个解决方法.
我希望这对未来的人有用:D
解决方法非常简单,而且非常好.
由于我们知道站点的哪些部分需要使用动态参数(因此将具有动态路径和长度),因此我们可以通过在它甚至到达ASP.NET之前拦截它来避免将此长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>
Run Code Online (Sandbox Code Playgroud)
基本上,我们正在做的就是保持足够的路径,以便能够调用正确的下游路由.我们正在破解其余的URL路径.
URL的其余部分在哪里?
好吧,当触发重写规则时,IIS7 URL重写模块会在请求中自动设置此标头:
HTTP_X_ORIGINAL_URL
Run Code Online (Sandbox Code Playgroud)
下游,在解析动态路径的应用程序部分,而不是查看路径:
HttpContext.Request.Url.PathAndQuery
Run Code Online (Sandbox Code Playgroud)
我们看一下那个标题:
HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]
Run Code Online (Sandbox Code Playgroud)
问题解决了......差不多!
如果您需要知道,要访问IIS7重写模块标头,您可以通过两种方式执行此操作:
HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]
Run Code Online (Sandbox Code Playgroud)
要么
HttpContext.Request.Headers["X-ORIGINAL-URL"]
Run Code Online (Sandbox Code Playgroud)
您还将注意到,通过上述设置,所有相对路径都会中断(使用"〜"定义的URL).
这包括使用ASP.NET MVC定义的URL HtmlHelper和UrlHelper方法(如Url.Route("Bla")).
这是访问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;
}
Run Code Online (Sandbox Code Playgroud)
如果是,则执行一些工作来保留原始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);
}
}
Run Code Online (Sandbox Code Playgroud)
(注意,在上面的方法中,我正在删除标题Request.ServerVariables但仍保留它,将其存入Context.Items.原因是我需要稍后在请求管道中访问标题值.)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
56984 次 |
| 最近记录: |