Deploying ASP.NET MVC applications on an Apache web server

April 9th, 2009 | Tags:

I struggled a bit to get the live demo up and running for my previous article on ASP.NET MVC because my hosting provider runs on the Apache web platform, which wasn’t all too keen on the MVC URL rewriting.

One of the problems is that on Apache (same as on IIS6), the document being served has to have a particular file extension in order for the mod_aspdotnet module to be invoked at all. Since the URL scheme in ASP.NET MVC by default does not have an extension, ie. www.wheresmymovie.net/home/about, this results in a 404 generated in Apache before the ASP.NET module ever gets invoked, and thus before any URL rewriting occurs.

If you have direct access to the server configuration, you can add a wildcard pattern to the AddHandler directive in the httd.conf file. This has the disadvantage of serving all content (including images and style sheets) through the ASP.NET module. Not to mention that it requires you to have direct access to the httpd.conf file, which you might not have in a shared hosting environment.

A better solution is to modify the routes in the Global.asax.cs file, and add an extension that the module will intercept, so that the links will look like this: http://www.wheresmymovie.net/home.aspx/about

The .aspx extension on the controller will do the trick, causing Apache to invoke mod_aspdotnet to serve the page, and then the URL rewriting will kick in.

Here’s a copy of the URL route from Global.asax.cs running on the live sample which is hosted on an Apache web server:

public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

  routes.MapRoute(
    "Default.aspx",
    "{controller}.aspx/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" },
    new { controller = @"[^\.]*" }
  );

  routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" },
    new { controller = @"[^\.]*" }
  );
}

Big thanks to bia securities, which is where I got the above code snippet.

Note that the “Default.aspx” route, which adds the .aspx extension to the controller comes before the “Default” route. This is so that calls to Html.ActionLink will generate links conforming to this scheme, since it will pick the first in the list.

This is basically the same thing that dasBlog does. It you have a look at the address bar above (this blog runs on dasBlog), you’ll notice that the .aspx extension is there, at the end of the URL routing scheme, which is actually something like {year}/{month}/{day}/{title}.aspx.

If you want pretty URLs and you don’t want the .aspx extension in there, you can either change it to some other extension, like .mvc, and add it to the AddHandler directive in the httpd.conf file. That, or upgrade to IIS7.

For more information about deploying ASP.NET MVC, check out this great article over at asp.net.

No comments yet.