Working on Marinas.info, we want to create SEO friendly links to specific searches that will hopefully rank high up in the search engines. They should look something like www.marinas.info/germany for marinas situated in Germany or www.marinas.info/wífi for marinas that provide wifi internet access. We also plan on supporting most European languages, some 30+ or so, even if not from the start. Anyway, the number of URLs we will generate is likely to explode, and we need a solution to consistently generate and handle those thousands of different URLs. This post investigates a few solutions that have popped up.
External URL Rewriting solutions – UrlRewritingNet and the IIS Url Rewrite Module
The two solutions listed here are called external because they integrate with the ASP.NET MVC request pipeline in way that they will be invisible to the actual web application. Routes would be rewritten in an early step and the application would only get to see the rewritten URL that it would know how to handle.
Since 2006, UrlRewritingNet has been around and I assume it’s a widespread solution. We use it in Camping.info, and probably the best part is the easy configuration. Still, I remember that we had a few problems with it that needed fixing, so we would most likely have to use that slightly customized version. I’m not 100% sure if it would work with MVC out of the box since we’ve only used it with ASP.NET WebForms.
IIS Url Rewrite Module
This is a solution by Microsoft that would certainly get the job done, too. I haven’t really used it yet in any larger project though, so I’d have to dive into it first. If you feel like giving it a go, check out http://learn.iis.net/page.aspx/734/url-rewrite-module/.
Internal solutions – Orchard Rewrite Rules and ASP.NET MVC Routing
These approaches work inside the application.
Orchard Rewrite Rules
Orchard Rewrite Rules is an Orchard Module that brings (a subset of) mod_rewrite style URL rewriting to any Orchard installation. We’ve successfully used it e.g. to redirect traffic from http://marinas.info to http://www.marinas.info. The greatest benefit is that it’s just another module that you can simply enable and disable at runtime from within the application without a need to recycle the app pool as would be the case for the two external rewriting solutions since their configuration is coupled to the web.config file. The drawback of this solution is that we’re also new to its syntax and it’s not that clear (yet) how we would efficiently map the thousands of routes with their dynamic values that we are aiming at.
ASP.NET MVC Routing
It seems that ASP.NET MVC’s built-in routing engine can provide us with what we are looking for. At first glance, looking at the standard examples of route definition, it didn't appear that promising. Remember, we want to support URLs such as www.marinas.info/germany and www.marinas.info/wifi for a lot of search categories. The routes to match those request would either have to be very specific, e.g. one per category, or very general, e.g. one for all categories. The first approach would lead to the thousands of routes I mentioned earlier, the latter would also catch requests for other parts of the application that might have nothing to do with search since it’s so general. It turns out there are more advanced features in ASP.NET MVC Routing that allow to overcome these restrictions.
Custom Route Constraint with IRouteConstraint and Custom Route Handler with MvcRouteHandler
This answer on Stack Overflow to a question concerning exactly the same problem points to a blog post on writing your own Route Constraint which is a great way to deal with the second problem mentioned above, that a too general route would match too many requests. The custom route constraint could e.g. constrain the application of a certain route to only valid values.
Another approach, presented in this post on SEO friendly URLs in MVC, would be to derive from the default MvcRouteHandler and implement some custom logic to handle our custom URLs.
Conclusion: ASP.NET MVC Routing has it all
I’m glad I set out to examine those different solutions because I totally underestimated the power of ASP.NET MVC Routing if I hadn’t. Another great post on Optimizing ASP.NET MVC3 Routing talks about even more of its aspects and how Stack Overflow handles their large number of routes with high performance using (mostly) built-in functionality. Looks very much like this is the way to go!