53

I'm using ASP .NET MVC Beta and I get the HTTP 404 (The resource cannot be found) error when I use this url which has a "dot" at the end:

http://localhost:81/Title/Edit/Code1.

If I remove the dot at the end or the dot is somewhere in the middle I don't get the error.

I tried to debug but it I get the error from "System.Web.CachedPathData.GetConfigPathData(String configPath)" before ProcessRequest in MvcHandler.

Is "dot" not allowed at the end of a url? Or is there a way to fix the route definition to handle this url?


For an example: I have a table named Detail1 [Id(integer), Code(string), Description(string)] which has FK relationship with Master1 through it's Id column. Whenever I select a record of Master1, I also select it's Detail1 record to get it's Code field. In order to not to make this join everytime (since usually there isn't only one detail, there are more than one) I choose not to use Id column and I make Code PK of Detail1.

But when I get rid of Id and use Code as PK then my routes also start to work with Code field, like: Detail1\Edit\Code1

This Code can have anything in it or at the end, including DOT. There are cases where I can prohibit a DOT at the end but sometimes it's really meaningfull.

And I'have also seen this post that routes can be very flexible, so I didn't think mine is so weird.

So that's why I do something so non-standard. Any suggestions?

And also why it's so weird to have a DOT at the end of a url?

Tim Post
  • 33,371
  • 15
  • 110
  • 174
ipek
  • 701
  • 1
  • 6
  • 6
  • not sure this still plays for you, but I added an actual solution for older ASP.NET versions, check it out ;). – Abel Mar 11 '11 at 12:35
  • If you'd like to add additional information to your question, just edit your question (click the 'edit' link underneath your question). To comment on an answer you've received, use the comment facility under the answer. If you find the comment space insufficient, you should probably be making an edit. Answers should be just that, direct answers to your question. – Tim Post Oct 14 '11 at 13:31

6 Answers6

56

If you are using .NET 4.0, you can set this flag in the system.web section of your web.config and it will be allowed:

<httpRuntime relaxedUrlToFileSystemMapping="true" />

I've tested it and it works. Haack has an explanation of it.

bkaid
  • 51,465
  • 22
  • 112
  • 128
  • Thanks, will keep in mind when upgrading to 4.0. Any chance there's a way for .NET 3.5? – Jason Jan 14 '11 at 17:09
  • @Jason: yes, there's a way for older .NET versions, have a look at my answer. – Abel Mar 11 '11 at 12:35
  • do yall know- will this allow urls ending in periods to get forwarded to the url rewriting module in iis7.5? this is what's killing me right now – Brady Moritz Feb 08 '12 at 21:18
  • 2
    Aren't there some security issues on doing this? – Jake Gaston Feb 19 '15 at 17:19
  • I don't believe it is a security issue. According to MSDN, the setting simply: > "indicates whether the URL in an HTTP request is required to be a valid Windows file path." – GWR Nov 13 '16 at 16:51
18

This can be solved in a couple of ways in every ASP.NET version from 1.0 and up. I know it's two years after this thread has been created, but anyway, here it goes:

Cause

Creating your custom error handler, or configuring a custom page in IIS for redirecting the 404 will not work. The reason is that ASP.NET considers this URL dangerous. Internally in System.Web.Util.FileUtil, ASP.NET calls a private method IsSuspiciousPhysicalPath, which tries to map the path to a (virtual but legal) filename.

When the resulting legalized path is not equal to the original path, processing stops and the ASP.NET code returns a 404 (it doesn't ask IIS or the web.config for the custom 404, it returns one itself, which makes it so hard to do something about this).

Windows Explorer works the same way. Try to create a filename ending in one or more dots, i.e. test.txt.. You will find that the resulting name is text.txt.

Solution for ending URL in a dot in ASP.NET

The solution is simple (once you know it, it always is). Just before it sends out this 404, it will call Application_PreSendRequestHeaders, a simple event that you can register to in Global.asax.cs (or the VB equivalent). The following code will return a simple text to the browser, but a Redirect, or any other valid response is also possible.

protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{

    HttpResponse response = this.Context.Response;
    HttpRequest request = this.Context.Request;
    if (request.RawUrl.EndsWith("."))
    {
        response.ClearContent();
        response.StatusCode = 200;
        response.StatusDescription = "OK";
        response.SuppressContent = false;
        response.ContentType = "text/plain";
        response.Write("You have dot at the end of the url, this is allowed, but not by ASP.NET, but I caught you!");
        response.End();
    }
}

Note: this code also works when "aspx" is not part of the URL. I.e., http://example.com/app/somepath. will call that event. Also note that some paths still won't work (ending with multiple dots, with a hash-tag, or a < -sign, for instance, causes a 400- Bad Request). Then again, it does work for ending on a quote, a space+slash, or multiple dots separated by spaces.

Abel
  • 56,041
  • 24
  • 146
  • 247
  • this should probably work in mvc too right? man that would be nice. – Brady Moritz Feb 08 '12 at 01:44
  • @boomhauer: yes, whether or not you use MVC doesn't matter. – Abel Feb 08 '12 at 02:50
  • awesome, if the relaxedurl thing above doesnt work, i'll fall back to this. thanks – Brady Moritz Feb 08 '12 at 21:18
  • @boomhauer: it depends on which version of .NET you can use whether `RelaxedUrl` works. Also, in those cases where you need more control (like: deny all except one special type), it's easier to keep the security that `relaxedUrlToFileSystemMapping="false"` can give you. – Abel Feb 10 '12 at 10:03
  • @David: make sure to run your .NET 3.5 app in a .NET 2.0 CLR (there is no 3.0 or 3.5 CLR). If you run it in a 4.0 apppool, I'd not be surprised when it doesn't work. But I'm guessing at the source of your issue. You might want to elaborate and/or create a question for your specific scenario. – Abel Aug 24 '12 at 20:46
  • This didn't work for me in a .NET 4.0 site. It doesn't seem to hit this event for a page: "/default.aspx.". Admittedly it's an Umbraco site, but other requests do hit this. I was actually trying to solve the problem of '%20' appearing at the end - but in that case the RawURL doesn't include the %20 and it will then still 404 with me none the wiser in this event handler that it's about to fall over. – Ian Grainger Jul 02 '13 at 15:32
  • @IanGrainger: for .NET 4.0, have a look at the solution provided in the accepted answer above, by bkaid. I believe it will allow you to catch these. However, be aware that a few requests (and I'm not sure yours is part of it), will never reach ASP.NET handlers. – Abel Jul 21 '13 at 22:22
  • @Abel yes, I was trying to avoid having to use the relaxed checking. – Ian Grainger Jul 23 '13 at 09:43
6

Well, in .NET 4.5 I fixed this problem by adding "/" to the end of the url.

So, in your case it would be "http://localhost:81/Title/Edit/Code1./". It was the only thing I did, I didn't have to add httpRuntime setting.

Nat
  • 467
  • 1
  • 6
  • 12
3

add this to handlers

  <add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
 path="api/*"
 verb="*"
 type="System.Web.Handlers.TransferRequestHandler"
 preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
Toolkit
  • 10,779
  • 8
  • 59
  • 68
-1

Perhaps http://localhost:81/Title/Edit/Code1%2E would work.

I escaped the period with a hex ascii code.

recursive
  • 83,943
  • 34
  • 151
  • 241
  • 5
    Doesn't work. Most browsers change %2E back to . before sending the request since it's an unreserved character. – Dan Fitch Mar 08 '10 at 16:42
-3

Why can't you have a dot-terminated URI?

Because a URI is a resource request and a historical imperitive exists on all relevant operating systems that the dot character is the extension separator. The last dot is treated as denoting a file extension, hence dot-terminating will make no sense.

Also worth reading:

annakata
  • 74,572
  • 17
  • 113
  • 180
  • 3
    RFC3986 says nothing about this. See section 3.3, where it explicitly says that "... a path segment is considered opaque by the generic syntax." – Dan Fitch Mar 08 '10 at 16:44
  • 2
    There is no such thing as an extension separator in a URI. You're mistakingly confusing filenames with URIs. They are not the same. – Abel Oct 14 '11 at 11:22