One topic that comes up often in SitePoint’s .NET Forum is “How do I make rewrite Urls in .NET?” The answer to this question is relatively simple, once you get into the ASP.NET pipeline. Unfortunately, given the current versions of IIS, getting to that pipeline is alot trickier than it should be. IIS really prefers to deal with known extensions rather than fancy mappings. Documentation for getting around this limitation is sparse at best.
Getting IIS Mapping Things it Does Not Want To Map
First and foremost among IIS 7’s new features is the ability to inject HttpHandlers and HttpModules on any request coming to the server. There is a reason this is the headliner—getting IIS 6 to correctly map rewritten urls is a trick in and of itself. IIS 6.0 and earlier really, really want to just take the extension from the request and map it to the proper handler for processing. So, if you wish to make your urls something like http://www.example.com/products/fluffy-bunny-slippers/ you are going to have to do a bit of engineering. Options include:
Let IIS do what IIS wants to do.
There are times when it is best to kowtow to how the underlying technology wants to work. So just change your pages to feel like pages rather than folders—such as http://www.example.com/products/fluffy-bunny-slippers.aspx. The url is nearly as hackable as the previous example while needing considerably less engineering. Your application will require no reconfiguration on the IIS level to get things mapping correctly. This tactic will also work in shared hosting scenarios where you don’t have the ability to make significant configuration changes in IIS.
Use an ISAPI Module or Filter
ISAPI modules and filters sit within IIS and handle requests before they hit ASP.NET’s pipeline. The two options are the rather cheap IISRewrite and the free ISAPI Rewrite Filter. Both use a grammar generally reminiscent, but not identical to, of mod_rewrite. This is probably the cleanest solution, but it also requires a hosting situation that lets one make significant configuration changes to IIS.
Use a Wildcard mapping.
IIS 6.0 supports wildcard mappings, where all requests to a given website are mapped to a given handler. While this sounds like a silver bullet, it has a lot of downsides. Probably the biggest one is that requests for static resources are going to be patched through the ASP.NET pipeline. Moreover, if you are using any estoric content types, you will have to make sure they are assigned a proper handler in your application or in the server’s web.config.
Use a custom ASP.NET 404 page.
If your 404 page is an ASP.NET page, then it will run the entire rendering pipeline, including calling your custom HttpModules. So, any non-existent file will still let your program get a few words in. While comparatively rather ghetto, this is a valid tactic for situations where one cannot modify significant bits of IIS nor just use .aspx urls. Unfortunately, most shared hosts will not let one use options two or three above, so this lowest common denominator is quite often used in applications today.
Now that we have the hard part—getting IIS to feed requests to ASP.NET—taken care of, we can get to the business of actually rewriting URLs. Fortunately, this is relatively easy and markedly more sane than the above. Rather than repeat the wisdom of the interwebs, I shall give you some key links:
- Scott Guthrie’s excellent post on Url Rewriting in .NET. Pay special attention to the last few points; they cover a few of the big gotchas in .NET url rewriting.
- UrlRewritingNet.UrlRewrite is a rather good .NET 2.0 library for handling the mechanics of your url rewriting needs.
- UrlRewriter.Net is another rather good, open source .NET 1.1/2.0 library for handling the mechanics of your url rewriting needs.
- Scott Watermasysk, the man who brought you .TEXT and Community Server, posts this very helpful post on a rather significant bug in .NET’s native url rewriting.
- The MSDN documentation for HttpContext.RewritePath, the “key” method in this endeavor.
So, take control of IIS and get to making them urls more human friendly!