Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow URLs to contain dots in ASP.NET MVC5?

I am working on a website that should allow dots in URLs, like www.mysite.com/somedata/my.name-123. My desired behaviour is to make that url equivalent to www.mysite.com/somedata/myname-123, but instead I am getting 404 errors because those dots make IIS try to find a static file. A similar question can be found here, but the proposed solutions do not work in my case, as I explain below. This is what I have tried:

  • Adding a new handler like suggested in the answer accepted in the old question does not work because I need this to work for several paths. If I set path="*" then all static files (for example .css files) fail. I can specify a url pattern using RegEx, but the path attribute does not allow it as far as I know (only wildcards are allowed)

  • Using lines like <httpRuntime relaxedUrlToFileSystemMapping="true" /> and <requestFiltering allowDoubleEscaping="true"/> to the web.config simply doesn't work in MVC5.

  • Adding <modules runAllManagedModulesForAllRequests="true"> to the system.webServer section in the web.config does actually work but this practice is discouraged for many reasons, exposed in this article, so I am trying to avoid this approach if possible.

  • Appending a trailing slash (/) to the URL also solves the problem, but doing so would lead Google to think that I am serving duplicate content, so I cannot use this solution.

I cannot think of any other alternatives. Ideally I would like to add a new handler and make it work for all URLs except those ending with certain patterns (.css, .js).


UPDATE: I have found a solution that works for me. I will try to explain the steps I took:

First of all, I found a really good explanation of why this behaviour is happening: Scott Forsyth's blog. Some of the solutions listed above are also discussed. After rading the article I decided to handle dotted urls with a rewrite rule. Instead of adding a trailing slash I decided to serve the url without the troublesome dots and then check what the user is looking for in the controller of my application. My base rule looks like this one:

<rule name="remove troublesome dots" stopProcessing="false">
    <match url="^(.*)\.(\S*)$" />
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}{R:2}" />
</rule>

Note that dots are removed one at a time, so urls with several dots will hit this rule several time. This is bad if urls are likely to have a large number of dots.

If a static file path does not map directly it's disk location, my approach will make it crash. To avoid problems, we need to add exceptions to the remove dots rule for the file endings we need. Seb Nilsson explains how to do it in this blog post, under the "Adding conditions for specific file-endings" section.

like image 670
ederbf Avatar asked Aug 19 '14 14:08

ederbf


1 Answers

I remember confronting this situation some months ago. I was really in a hurry, so what I did may not be the recommended approach.

I specified only one segment, and then created the appropiate regex as a constraint

For instance, it'd end up something like this:

url: somedata/{dotted}

constraints: dotted: "(.*\.)*.*"

That regex is extremely generic, you should reformulate it to accept only supported characters, in order to avoid invalid symbols.

like image 101
Matias Cicero Avatar answered Sep 28 '22 04:09

Matias Cicero