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

Scenario

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

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

and changed it to a path structure:

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

We use ASP.NET MVC and (naturally) ASP.NET routing.

Problem

The problem is that our parameters are dynamic, and (theoretically) there are no restrictions on the number of parameters that we need to consider.

This is normal until we hit the next train:

HTTP Error 400.0 - An invalid ASP.NET request detected invalid characters in the URL.

IIS throws this error when our URL has passed a certain length.

Nitty gritty

Here's what we found out:

This is not an IIS problem.

IIS has a maximum path length limit, but the error above is not the same.

Learn dot iis dot net How to use query filtering Filtering based on query restrictions section

If the path was too long for IIS, he would choose 404.14 rather than 400.0.

In addition, the IIS path (and request) length is configurable:

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

This is an ASP.NET issue.

After being punctured:

IIS Forums Topic: Maximum ASP.NET 2.0 URL Length? http://forums.iis.net/t/1105360.aspx

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

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

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

Stack Overflow MAX_PATH Limit ASP.NET URL Question ID 265251

Question

So what is the question?

The question is how big is this limitation?

For my application, this is a deal killer. For most applications, this is probably not a problem.

What about disclosure? No where ASP.NET Routing is mentioned, I have ever heard of this limitation. The fact that ASP.NET MVC uses ASP.NET routing does this even more.

What do you think?

+50
url asp.net-mvc iis routing asp.net-routing
Jul 26 '09 at 22:29
source share
7 answers

In the end, I decided to use the following command in web.config to solve this problem using Mvc2 and .Net Framework 4.0

 <httpRuntime maxUrlLength="1000" relaxedUrlToFileSystemMapping="true" /> 
+40
Apr 7 '11 at 18:23
source share

To resolve this issue, do the following:

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

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

Also, I had to add this to the system.webServer node or I received a security error for my long query strings:

 <system.webServer> <security> <requestFiltering> <requestLimits maxUrl="10999" maxQueryString="2097151" /> </requestFiltering> </security> ... 
+20
Sep 19 '13 at 21:45
source share

The Http.sys service is encoded by default with a maximum of 260 characters per Url segment.

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

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

The maximum allowable Url segment length can be changed with the registry settings:

  • Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters
  • Value: UrlSegmentMaxLength
  • Type: REG_DWORD
  • Data: (Desired maximum allowable Url segment length, e.g. 4096)

More details about http.sys settings: 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)

To make changes to this parameter, a PC reboot takes effect. (Credit: David Rettenbacher, Juan Mendes)

+18
Oct 19 '11 at 7:12
source share

OK, so part of the reason I posted this was also because we found a job.

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

Workaround

The workaround is quite simple, and it is also very pleasant.

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

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

We have established the following rule:

  <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 do just keeps enough paths to be able to call the right route downstream. The rest of the URL we are hacking.

Where is the remaining url located?

Well, when the rewrite rule is triggered, the Rewrite module of the IIS7 URL automatically sets this header in the request:

 HTTP_X_ORIGINAL_URL 

Downstream, in the part of the application that analyzes the dynamic path, instead of looking at the path:

 HttpContext.Request.Url.PathAndQuery 

instead, we look at this heading:

 HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"] 

The problem is solved ... almost!

Snow

Heading access

If you need to know in order to access the IIS7 rewrite module header, you can do this in two ways:

 HttpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"] 

or

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

Fix relative paths

What you will also notice is that with the above setting, all relative paths are interrupted (URLs that were identified with "~").

This includes URLs defined using the ASP.NET MVC HtmlHelper and UrlHelper (for example, Url.Route("Bla") ).

Access to ASP.NET MVC code is available here.

The System.Web.Mvc.PathHelper.GenerateClientUrlInternal() method checks to see if the same Rewrite module header exists (see above):

 // 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 so, some work is being done to keep the original URL.

In our case, since we do not use URL rewriting in the β€œnormal” way, we want to shorten this process shortly.

We want to pretend that URL rewriting did not happen, because we do not want relative paths to be seen in the context of the original URL.

The easiest hack I could come up with was to completely remove this server variable, so ASP.NET MVC would not find it:

 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 remove the header from Request.ServerVariables , but save it by putting it in Context.Items . The reason for this is that I need access to the header value later on the request channel.)

Hope this helps!

+12
Jul 26 '09 at 22:54
source share

I think you are trying to use GET. Try changing the request method to POST and put these query string parameters in the request body.

A long URL doesn't help SEO, does it?

+1
Jul 26 '09 at 22:36
source share

It probably doesn't matter right now ... but it worked for me (since I did not use aspx files, and I would venture to assume that it would work for 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- mentioned-in-kb-932552-or-826437.aspx

0
Mar 30 '10 at 18:49
source share

It seems that the maximum length of the hardcode URL has been fixed in .NET 4.0 . In particular, there is now a web.config section with:

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

which allows you to expand the range of allowed URLs.

0
Apr 05 2018-11-11T00:
source share



All Articles