Plus (+) in MVC Argument causes 404 on IIS 7.0
Asked Answered
G

4

29

I have an MVC route that is giving me hell on a staging server running IIS. I am running Visual Studio 2010's development server locally.

Here is a sample URL that actually works on my dev box:

Root/CPUBoards/Full+Size

Results
Server Error404 - File or directory not found.
The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.

Here is the complete behaviour I am seeing.

Localhost:

Root/CPUBoards/Full Size - Resolves
Root/CPUBoards/Full%20Size - Resolves
Root/CPUBoards/Full+Size - Resolves

Staging Server with IIS 7.0:

Root/CPUBoards/Full Size - Resolves
Root/CPUBoards/Full%20Size - Resolves
Root/CPUBoards/Full+Size - 404 Not Found Error.

Any ideas? I need to work with the encoded version for several reasons... won't waste your time with them.

HttpUtility.UrlEncode("Full Size") returns the version with the plus sing... Full+Size. This works on my dev box, but not on the staging server. I would prefer to just get it working on the server, since I already have everything else tested and working locally, but I have no idea where to start looking on the server configuration to get it to behave the same way.

Thanks!

Given answered 30/7, 2010 at 22:20 Comment(1)
Can you build locally using IIS 7 instead of the ASP.NET development environment?Impearl
C
20

+ only has the special meaning of being a space in application/x-www-form-urlencoded data such as the query string part of a URL.

In other parts of the URL like path components, + literally means a plus sign. So resolving Full+Size to the unencoded name Full Size should not work anywhere.

The only correct form of a space in a path component is %20. (It still works when you type an actual space because the browser spots the error and corrects it for you.) %20 also works in form-URL-encoded data as well, so it's generally safest to always use that.

Sadly HttpUtility.UrlEncode is misleadingly-named. It produces + in its output instead of %20, so it's really a form-URL-encoder and not a standard URL-encoder. Unfortunately I don't know of an ASP.NET function to “really URL-encode” strings for use in a path, so all I can recommend is doing a string replace of + to %20 after encoding.

Alternatively, avoid using spaces in path parts, eg. by replacing them with -. It's common to ‘slug’ titles being inserted to URLs, reducing them to simple alphanumerics and ‘safe’ punctuation, to avoid filling the URL with ugly %nn sequences.

Cold answered 30/7, 2010 at 22:35 Comment(2)
OK. This is very helpful. These URL "Segments" are coming from a database, and we prefer to allow the data in the database to be natural. We also need the URL to be unique, so replacing a bunch of stuff with '-' is not desireable. For example, we have both underscore and space characters, both of which people like to replace with a dash. I suppose this means we are stuck using "ugliness" like %20 to represent characters accurately, but these are the edge cases, and the compromise is not so bad. I guess I will have to do some manual replacing before URL Encoding stuff. Thanks!Given
Unfortunately you can't quite get arbitrary strings into path parts. %2F (the encoded form of /) is blocked by many web servers—by default in Apache, and unavoidably in IIS. IIS also blocks %5C, and all servers block %00 (other control codes can also cause various difficulties, and of course Unicode in path parts has some gotchas of its own).Cold
R
23

This is an IIS security setting. There is a standard request filter that rejects URLs containing + (plus) characters.

You can disable it for your web, adding this to your web.config:

<configuration>
   ...
   <system.webServer>
      ...
      <security>
          <requestFiltering allowDoubleEscaping="true" />
      </security>
    </system.webServer>
    ...
</configuration>
Ruth answered 5/11, 2010 at 14:46 Comment(1)
Works for me. More details about 'allowDoubleEscaping' here: https://mcmap.net/q/27088/-is-enabling-double-escaping-dangerousProduction
C
20

+ only has the special meaning of being a space in application/x-www-form-urlencoded data such as the query string part of a URL.

In other parts of the URL like path components, + literally means a plus sign. So resolving Full+Size to the unencoded name Full Size should not work anywhere.

The only correct form of a space in a path component is %20. (It still works when you type an actual space because the browser spots the error and corrects it for you.) %20 also works in form-URL-encoded data as well, so it's generally safest to always use that.

Sadly HttpUtility.UrlEncode is misleadingly-named. It produces + in its output instead of %20, so it's really a form-URL-encoder and not a standard URL-encoder. Unfortunately I don't know of an ASP.NET function to “really URL-encode” strings for use in a path, so all I can recommend is doing a string replace of + to %20 after encoding.

Alternatively, avoid using spaces in path parts, eg. by replacing them with -. It's common to ‘slug’ titles being inserted to URLs, reducing them to simple alphanumerics and ‘safe’ punctuation, to avoid filling the URL with ugly %nn sequences.

Cold answered 30/7, 2010 at 22:35 Comment(2)
OK. This is very helpful. These URL "Segments" are coming from a database, and we prefer to allow the data in the database to be natural. We also need the URL to be unique, so replacing a bunch of stuff with '-' is not desireable. For example, we have both underscore and space characters, both of which people like to replace with a dash. I suppose this means we are stuck using "ugliness" like %20 to represent characters accurately, but these are the edge cases, and the compromise is not so bad. I guess I will have to do some manual replacing before URL Encoding stuff. Thanks!Given
Unfortunately you can't quite get arbitrary strings into path parts. %2F (the encoded form of /) is blocked by many web servers—by default in Apache, and unavoidably in IIS. IIS also blocks %5C, and all servers block %00 (other control codes can also cause various difficulties, and of course Unicode in path parts has some gotchas of its own).Cold
T
4

System.Web.HttpUtility.UrlPathEncode(string str) encodes a + to a %20

Tessietessier answered 15/3, 2012 at 18:53 Comment(1)
I think the OP has that part figured out - why it's causing the error is more the issue.Monoploid
D
0

Totally agree with @bobince, the problem is in the wrong encoding to %2b instead of %20

Sadly HttpUtility.UrlEncode is misleadingly-named. It produces + in its output instead of %20, so it's really a form-URL-encoder and not a standard URL-encoder. Unfortunately I don't know of an ASP.NET function to “really URL-encode” strings for use in a path, so all I can recommend is doing a string replace of + to %20 after encoding.

this is the important part, which is to replace the + sign with %20

Dodder answered 28/4, 2020 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.