.NET, Sitecore

Sitecore and System.Web.Routing


There is a lot going on from Microsofts side on the ASP.NET side. .NET 3.5 SP1 included Dynamic Data and in .NET 4.0 the Microsoft MVC framework (out in a preview) will be a major feature.
Alex has already brushed the subject on his blog and although he is right in some of his concerns, I merely look at these new features as tools in my Sitecore/.NET toolbox, not nessecarily a replacement for anything.

Both the mentioned technologies from Microsoft uses another feature in .NET 3.5 SP1, which is URL Routing (available through the System.Web.Routing assembly). Basically, you are able in your global.asax to specify dynamic URL’s which will routed to static ASP.NET pages. Sound familiar? Yes, it is a dynamic resolver similar to the way Sitecore resolves its rendering engine, and this is where the challenge lies. Microsoft uses exactly the same technology as Sitecore, httpModules, to hook into the request and resolve the physical file. Therefore the following must be added to you web.config to get Microsoft URL Routing to work:

<httpModules>
  <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add type="Sitecore.Nexus.Web.HttpModule, Sitecore.Nexus" name="SitecoreHttpModule"/>
  <add type="Sitecore.Resources.Media.UploadWatcher, Sitecore.Kernel" name="SitecoreUploadWatcher"/>
  <add type="Sitecore.IO.XslWatcher, Sitecore.Kernel" name="SitecoreXslWatcher"/>
  <add type="Sitecore.IO.LayoutWatcher, Sitecore.Kernel" name="SitecoreLayoutWatcher"/>
  <add type="Sitecore.Configuration.ConfigWatcher, Sitecore.Kernel" name="SitecoreConfigWatcher"/>
</httpModules>

Notice that I’ve added the UrlRouting to the top of the list, making this my primary URL routing preference. There is a few more entries in the web.config you need to add, but this is really the one that does the trick – well almost…
The problem is that Sitecore is a real bastard for taking over the request – even if Microsoft URL routing is interested in the request, Sitecore says “we’ll I don’t know about this URL, so lets redirect to the ItemNotFoundUrl” (this is also why 404 errors and SEO in Sitecore is handled poorly).
To overcome this, we either have to, manually, enter our URL Routing URLs in the IgnoreURLPrefixes entry in the web.config or create a Sitecore HttpRequestProcessor for handling the URL Routing URLs. To do this, you need to implement a class deriving from HttpRequestProcessor which determines if a URL is handled by Microsoft URL Routing and then skips out the Sitecore stuff.:

using System.Web;
using System.Web.Routing;
using Sitecore.Pipelines.HttpRequest;

namespace WebApplication1
{
  public class IgnoreUrlRouting : HttpRequestProcessor
  {
    public override void Process(HttpRequestArgs args)
    {
      RouteData route = RouteTable.Routes.GetRouteData(new HttpContextWrapper(args.Context));
      if (route != null)
        args.AbortPipeline();
    }
  }
}

This class then needs to be hooked into the Sitecore request pipeline in your web.config. I’ve chose to do it just after the IgnoreList. This is before Sitecore sets up its context, so you can choose to move it even further down the list if you want more Sitecore functionality in your ASP.NET code:

<httpRequestBegin>
  <processor type="Sitecore.Pipelines.HttpRequest.StartMeasurements, Sitecore.Kernel"/>
  <processor type="Sitecore.Pipelines.HttpRequest.IgnoreList, Sitecore.Kernel"/>
  <processor type="WebApplication1.IgnoreUrlRouting, WebApplication1"/>
  <processor type="Sitecore.Pipelines.HttpRequest.SiteResolver, Sitecore.Kernel"/>
  ...

Bam! You are up and running ASP.NET Routing and can now start using MVC, Dynamic Data and all the other fun new stuff coming from Microsoft.

Standard

2 thoughts on “Sitecore and System.Web.Routing

  1. You may also want to look at where in you place your IgnoreUrlRouting Processor. You are cutting off the UserResolver and other resolvers you may still want to use. For instance if you cut off the UserResolver then the user will always be set to anonymous even if they are logged in for routed pages.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s