Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to route a request for a directory that exists on disk to ASP.NET MVC?

I have an ASP.NET MVC 4 app (using .NET framework 4.5) with extensionless URLs. The site contains some static files, but all extensionless requests should go into MVC routing.

It all works fine for requests like:

  • /
  • /news
  • /fr/news

However if I make a request for /fr I get the error:

HTTP Error 403.14 - Forbidden, 
The Web server is configured to not list the contents of this directory. 

I understand that this is because there actually exists a /fr directory on disk, however I still want to map this request to my MVC app. It is not an option to remove the fr directory, as it contains some static files.

Is this possible? I have tried adding runAllManagedModulesForAllRequests="true" to the modules element in system.webServer (I don't really want to do this, but it didn't help anyway).

Edit - in case its useful, here is the routing:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("cid/{*pathInfo}");
        routes.MapRoute(
           "Page",
           "{*PageId}",
           new { controller = "Page", action = "Page" }, // Parameter defaults
           new { pageId = @"^(.*)?$" } // Parameter constraints
        );
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
like image 786
Will Avatar asked Apr 23 '14 09:04

Will


People also ask

Which method is used for adding routes to an MVC application?

When an MVC application first starts, the Application_Start() method is called. This method, in turn, calls the RegisterRoutes() method. The RegisterRoutes() method creates the route table. The default route table contains a single route (named Default).

How you can define a route in ASP.NET MVC?

Routing in ASP.NET MVC cs file in App_Start Folder, You can define Routes in that file, By default route is: Home controller - Index Method. routes. MapRoute has attributes like name, url and defaults like controller name, action and id (optional).

What are the three main elements of routing in MVC 3?

The three segments of a default route contain the Controller, Action and Id.

What is IgnoreRoute route MVC?

IgnoreRoute(RouteCollection, String) Ignores the specified URL route for the given list of available routes. IgnoreRoute(RouteCollection, String, Object) Ignores the specified URL route for the given list of the available routes and a list of constraints.


1 Answers

EDIT: I initially thought that it was necessary to remove the DirectoryListingModule, but this is not the case, my custom HttpModule rewrite kicks in before this, so it can be left in.

The workaround I used to fix this was to add some logic to a custom HttpModule which was doing some request processing. Here I detect if the request corresponds to the root of one of my localizations (/fr/ /es/ etc.) and if so, rewrite the url to the default page /fr/index, for which the routing works as normal.

private void BeginRequest(object sender, EventArgs e)
{
    HttpApplication application = (HttpApplication)sender;
    HttpContext context = application.Context;
    var url = context.Request.Url.AbsolutePath;
    if (IsLocalizationRoot(url))
    {
        context.RewritePath(url + GetDefaultPageName());
    }
}

If you are interested in how to remove the DirectoryListingModule (as mentioned above, this is not necessary, but its useful info anyway):

As the StaticFileHandler references it, you need to remove it and remove and re-add the StaticFileHandler (without the DirectoryListingModule) in your web.config:

<system.webServer>
    <handlers>
      <remove name="StaticFile"/>
      <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule" 
           resourceType="Either" requireAccess="Read" />  
    </handlers>
    <modules>
      <remove name="DirectoryListingModule"/>
    </modules>
</system.webServer>

This will probably cause a HTTP 500 error, due to a lock violation. You need to unlock it in the IIS applicationHost.config:

open a command prompt (run as Administrator) and go to C:\Windows\system32\inetsrv

appcmd set module DirectoryListingModule /lockItem:false
like image 102
Will Avatar answered Oct 05 '22 21:10

Will