MonoRail: Mapping root directory to specific controller and action

April 28, 2008 at 2:38 PMAndre Loker

Most often, you want a web application to transfer the user to a specific controller action when he or she accesses the root directory of your application. For example, if the user entered http://somedomain/TheWebApp you'd want the app to handle it as if the user entered http://somedomain/TheWebApp/Home/Index.

In MonoRail this can be easily achieved using the built in URL rewriting service. Setting up the configuration is a matter of two steps:

1. Enable rewriting rules for the application

To enable url rewriting in the first place, you will have to add a specific IHttpModule in your web.config. It should be the first module in the <system.web><httpModules> section to ensure proper working.

   1: <system.web>
   2:   <!-- other stuff -->
   3:   <httpModules>
   4:     <add name="routing" type="Castle.MonoRail.Framework.RoutingModule, Castle.MonoRail.Framework" />
   5:     <!-- other modules -->
   6:   </httpModules>
   7:   <!-- other stuff -->
   8: </system.web>


2. Configure rewriting rules

In your <monorail> section in web.config or - if you are like me - in the external monorail configuration file add a <routing> section like this:

   1: <routing excludeAppPath="true">
   2:   <rule>
   3:     <pattern>^/?$</pattern>
   4:     <replace>/home/index</replace>
   5:   </rule>
   6: </routing>

This section contains only one rule, that will rewrite any request that targets the root directory of the application (either with or without a trailing slash) to the index action of the home controller. Of course, you may fill in whatever route fits your needs.

If you are not familiar with regular expressions: the pattern ^/?$ can be read like this: the whole url (from the start ^ to the end $) must be either empty or may optionally consist of one slash (? means: the slash is optional).

The excludeAppPath attribute makes your life much easier if the app exists in a subdirectory instead of the root directory. It simply means that you may write your rules as if all urls are targeted at the root directory. Otherwise, you would have to write:

   1: <routing excludeAppPath="false">
   2:   <rule>
   3:     <pattern>^/TheWebApp/?$</pattern>
   4:     <replace>/TheWebApp/home/index</replace>
   5:   </rule>
   6: </routing>

This would be a lot harder to maintain and deploy.

Some notes:

  • The pattern does not match the query string part, so http://somedomain/TheWebApp/?foo=bar would still be correctly rewritten to /home/index
  • The query string is passed to the rewritten URL as well, so (in the example above), the query parameter foo would be usable in the Home controller
  • I work with the subversion repository trunk of the castle project, so I cannot guarantee that this works for the current officially released version (RC3 as of now) or that it will work in the future.

Posted in: Snippets | Castle

Tags: , ,