asp.net-mvc ASP.NET MVC,Url 路由:最大路径 (URL) 长度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1185739/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:44:03  来源:igfitidea点击:

ASP.NET MVC, Url Routing: Maximum Path (URL) Length

asp.net-mvciisurlroutingasp.net-routing

提问by Martin Suchanek

The Scenario

情景

I have an application where we took the good old query string URL structure:

我有一个应用程序,我们采用了很好的旧查询字符串 URL 结构:

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

and changed it into a path structure:

并将其更改为路径结构:

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

We're using ASP.NET MVC and (naturally) ASP.NET routing.

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

The Problem

问题

The problem is that our parameters are dynamic, and there is (theoretically) no limit to the amount of parameters that we need to accommodate for.

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

This is all fine until we got hit by the following train:

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

HTTP Error 400.0 - Bad Request ASP.NET detected invalid characters in the URL.

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

IIS would throw this error when our URL got past a certain length.

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

The Nitty Gritty

坚韧不拔

Here's what we found out:

这是我们发现的:

This is not an IIS problem

这不是 IIS 问题

IIS does have a max path length limit, but the above error is not this.

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

Learn dot iis dot net How to Use Request Filtering Section "Filter Based on Request Limits"

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

If the path was too long for IIS, it would throw a 404.14, not a 400.0.

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

Besides, the IIS max path (and query) length are configurable:

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

<requestLimits


   maxAllowedContentLength="30000000"


   maxUrl="260"


   maxQueryString="25" 


              />

This is an ASP.NET Problem

这是一个 ASP.NET 问题

After some poking around:

经过一番摸索:

IIS Forums Thread: ASP.NET 2.0 maximum URL length? http://forums.iis.net/t/1105360.aspx

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

it turns out that this is an ASP.NET (well, .NET really) problem.

事实证明,这是一个 ASP.NET(嗯,确实是 .NET)问题。

The heart of the matter is that, as far as I can tell, ASP.NET cannot handle paths longer than 260 characters.

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

The nail in the coffin in that this is confirmed by Phil the Haack himself:

Phil the Haack 本人证实了棺材中的钉子:

Stack Overflow ASP.NET url MAX_PATH limit Question ID 265251

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

The Question

问题

So what's the question?

那么问题是什么?

The question is, how big of a limitation is this?

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

For my app, it's a deal killer. For most apps, it's probably a non-issue.

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

What about disclosure? No where where ASP.NET Routing is mentioned have I ever heard a peep about this limitation. The fact that ASP.NET MVC uses ASP.NET routing makes the impact of this even bigger.

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

What do you think?

你怎么认为?

采纳答案by lmingle

I ended up using the following in the web.config to solve this problem using Mvc2 and .Net Framework 4.0

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

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

回答by David Richoz

Http.sys service is coded with default maximum of 260 characters per Url segment.

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

An "Url segment" in this context is the content between "/" characters in the Url. For example:

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

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

The max allowed Url segment length can be changed with registry settings:

可以使用注册表设置更改最大允许的 Url 段长度:

  • Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
  • Value: UrlSegmentMaxLength
  • Type: REG_DWORD
  • Data: (Your desired new Url segment maximum allowed length, e.g. 4096)
  • 钥匙: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
  • 价值: UrlSegmentMaxLength
  • 类型:REG_DWORD
  • 数据:(您想要的新 Url 段最大允许长度,例如 4096)

More about http.sys settings: http://support.microsoft.com/kb/820129

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

The maximum allowed value is 32766. If a larger value is specified, it will be ignored. (Credit: Juan Mendes)

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

Restarting the PC is required to make a change to this setting take effect. (Credit: David Rettenbacher, Juan Mendes)

需要重新启动 PC 才能使此设置的更改生效。(图片来源:大卫·雷滕巴赫、胡安·门德斯)

回答by theJerm

To solve this, do this:

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

In the root web.config for your project, under the system.web node:

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

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

In addition, I had to add this under the system.webServer node or I got a security error for my long query strings:

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

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

回答by Martin Suchanek

OK so part of the reason I posted this was also because we have found a work around.

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

I hope this will be useful to someone in the future :D

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

The workaround

解决方法

The workaround is quite simple, and it's quite nice too.

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

Since we know which parts of the site will need to use dynamic parameters (and hence will have a dynamic path and length), we can avoid sending this long url to ASP.NET routing by intercepting it before it even hits ASP.NET

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

Enter IIS7 Url Rewriting (or any equivalent rewrite module).

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

We set up a rule like this:

我们设置了这样的规则:

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

Basically, what we're doing is just keeping enough of the path to be able to call the correct route downstream. The rest of the URL path we are hacking off.

基本上,我们所做的只是保留足够的路径,以便能够调用正确的下游路由。我们正在破解的 URL 路径的其余部分。

Where does the rest of the URL go?

URL 的其余部分去哪儿了?

Well, when a rewrite rule is fired, the IIS7 URL Rewrite module automagically sets this header in the request:

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

HTTP_X_ORIGINAL_URL

Downstream, in the part of the app that parses the dynamic path, instead of looking at the path:

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

HttpContext.Request.Url.PathAndQuery

we look at that header instead:

我们改为查看该标题:

HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]

Problem solved... almost!

问题解决了……差不多了!

The Snags

障碍

Accessing the Header

访问标题

In case you need to know, to access the IIS7 Rewrite Module header, you can do so in two ways:

如果您需要知道,要访问 IIS7 重写模块标头,可以通过两种方式进行:

HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"]

or

或者

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

Fixing Relative Paths

修复相对路径

What you will also notice is that, with the above setup, all relative paths break (URLs that were defined with a "~").

您还会注意到,通过上述设置,所有相对路径都会中断(用“~”定义的 URL)。

This includes URLs defined with the ASP.NET MVC HtmlHelperand UrlHelpermethods (like Url.Route("Bla")).

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

This is where access to the ASP.NET MVC code is awesome.

这就是访问 ASP.NET MVC 代码的绝佳之处。

In the System.Web.Mvc.PathHelper.GenerateClientUrlInternal()method, there is a check being made to see if the same URL Rewrite module header exists (see above):

在该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;
}

If it does, some work is done to preserve the originating URL.

如果是,则会执行一些工作来保留原始 URL。

In our case, since we are not using URL rewriting in the "normal" way, we want to short circuit this process.

在我们的例子中,由于我们没有以“正常”的方式使用 URL 重写,我们希望缩短这个过程。

We want to pretend like no URL rewriting happened, since we don't want relative paths to be considered in the context of the original URL.

我们想假装没有发生 URL 重写,因为我们不希望在原始 URL 的上下文中考虑相对路径。

The simplest hack that I could think of was to remove that server variable completely, so ASP.NET MVC would not find it:

我能想到的最简单的 hack 是完全删除该服务器变量,因此 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);
    }
}

(Note that, in the above method, I'm removing the header from Request.ServerVariablesbut still retaining it, stashing it in Context.Items. The reason for this is that I need access to the header value later on in the request pipe.)

(请注意,在上述方法中,我正在删除标头,Request.ServerVariables但仍保留它,将其隐藏在Context.Items.中。原因是我稍后需要在请求管道中访问标头值。)

Hope this helps!

希望这可以帮助!

回答by Adrian Godong

I think you're trying to hard to use GET. Try changing the request method to POST and put those query string parameters into the request body.

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

Long URL does not help SEO as well, does it?

长 URL 也无助于 SEO,是吗?

回答by J. Ventry

I was having a similar max URL length issue using ASP.NET Web API 4, which generated a slightly different error:

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

404 Error

404错误

The fix for me was described above by updating the Web.config with BOTH of the following tags:

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

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

and

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

回答by Joannes Vermorel

It appears that the hard-coded max URL length has been fixed in .NET 4.0. In particular, there is now a web.configsection with:

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

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

that let you expand the range of allowed URLs.

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