4

I have basically an out-of-the box MVC 5.2 app, with attribute-based routes enabled (calling routes.MapMvcAttributeRoutes(); from the provided RouteConfig.RegisterRoutes(RouteCollection routes) method).

The following is in HomeController:

    [Route("hello.txt")]
    [Route("hellotxt-testing")]
    public ActionResult ShowFile()
    {
        return Content("Hello world");
    }

I can successfully access /hellotxt-testing (proving attribute-based routing is working correctly):

accessing /hellotxt-testing

But I get a 404 page if I access /hello.txt:

accessing /hello.txt

In contrast to when I go to /hello404, where I get a different 404 page:

accessing /hello404

I am guessing that the second 404 page is from ASP.NET, while the first is from IIS which isn't even passing the request to ASP.NET?

What do I do to ensure that I can ensure ASP.NET gets these URLs that have periods in them? Are there other 'special' characters that would also cause a problem?

gregmac
  • 24,276
  • 10
  • 87
  • 118
  • pls check this http://stackoverflow.com/questions/11728846/dots-in-url-causes-404-with-asp-net-mvc-and-iis – Veena Feb 24 '15 at 03:31
  • That fix effectively requires a web.config modification for every path that might contain periods. This seems crazy to me, there must be a better way. ASP.NET already has a list of all possible URL patterns (the routing table). I would have thought ASP.NET should be responsible for ensuring IIS passes those through (maybe ASP.NET 6 adds this?).. but barring that, is it possible to do that dynamically (eg write a handler that registers all known routes with IIS), or is there a limitation that would prevent that from working? – gregmac Feb 24 '15 at 03:42
  • Have you tried ``? – haim770 Feb 24 '15 at 10:36
  • I guess I would be curious *why* you would want this? Beyond that, as someone already specified, Routing ignores static paths (so IIS can do things like deliver images and static files to the browser). It's pretty much a case of specificity, the "ignore things that look like static files" 'route' appears before hello.txt route and resolves first. @rexilion's answer has a good number of alternatives. – Vassi Feb 28 '15 at 04:18

2 Answers2

10

The difference between errors you see is because when you try to access /hello.txt IIS tries to reach the static resource file located on the server, on the other hand /hello404 is just an unknown route so 404 is thrown.

To ensure that I am right try to add slash at the end and access /hello.txt/ you should now get 404 error.

There are several ways to resolve this problem:

First you can try

<modules runAllManagedModulesForAllRequests="true">

but this option called RAMMFAR hurts the performance of web application. and has other consequences.

Second you can create rule for IIS URL REWRITE to always add trailing slash to each incoming URL's

Third go with Dots in URL causes 404 with ASP.NET mvc and IIS and

<add name="ApiURIs-ISAPI-Integrated-4.0"
     path="/people/*"
     verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
     type="System.Web.Handlers.TransferRequestHandler"
     preCondition="integratedMode,runtimeVersionv4.0" />

but you did not like this.

Fourth try to create custom http handler to add trailing slash to all requests like in this topic Add a trailing slash at the end of each url?


I would go with second option if you need this to work in many places in your application.

But I think the best one is third. Such url's with dots are not user friendly and are against SEO rules. You should avoid them in publicly available websites. So assuming you need this for only one controller and route this option is the fastest and cleanest one.

Community
  • 1
  • 1
Piotr Leniartek
  • 1,177
  • 2
  • 14
  • 33
0

We had this same issue (albeit not with attribute routing) and it started to appear in MVC 4 and continues in every version since.

One of the contributors to our project discovered the solution. I am afraid I can't offer much of an explanation as to why, but removing and then replacing the UrlRoutingModule fixes the 404 problem when using a route with a . in it.

<configuration>
    <system.webServer>
        <modules>
            <remove name="UrlRoutingModule-4.0" />
            <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
        </modules>
    </system.webServer>
</configuration>

This was discovered about 2 years ago, and so far we have not run into any negative effects caused by this change.

BTW - If anyone has an explanation why this works, please do share.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • From the look of it, your "add" directive leaves out the preCondition that the module be applied only in the context of a "managedHandler". I believe that the default reference to the module, which you are removing, has a specification like this: So you've essentially applied UrlRouting to each request, whether via managedHandler or not. More info in section 2 at this URL: https://svenaelterman.wordpress.com/2011/01/31/using-asp-net-4-0-extension-less-routing-on-iis-7-5/ – theta-fish Feb 22 '17 at 16:54