Introducing SmartyRoute: A smarty-ier way to do routing in ASP.NET applications

Update 9/9/2012: Scott Hanselman has just blogged about the new Friendly URL system for ASP.NET Web Forms. It's a much fancier, and admittedly much smarty-ier way to do routing and other features for Web Forms. Also, that feature will be officially supported, unlike my original sample code! 


 

Inspired by ideas I have heard from people on my team (ideas that apparently I misunderstood!), I am introducing the new SmartyRoute, which provides a smarty-ier way to do routing in ASP.NET applications.

The basic idea is that you can make a request to a resource in an ASP.NET application without specifying a file extension in the URL. SmartyRoute will try to append a set of supported file extensions to find a handler to serve the request.

Basic Routing

In the simplest usage a user can make a request to ~/helloworld and SmartyRoute will find ~/helloworld.aspx on disk and use that as the handler. This is a very common scenario: Many developers don’t want to have file extensions in the URLs of their web sites. SmartyRoute enables developers to do that without making other changes to the application.

Slightly More Advanced Routing

A more advanced scenario is where a developer wants to have a URL such as ~/category/beverages. With the feature shown so far the developer has to have a ~/category/beverages.aspx on disk. There would also need to be another ASPX for every category in the application. However, SmartyRoute can walk up the path segments of the URL to locate a parent ASPX file. In this case SmartyRoute will detect that there is a file ~/category.aspx and load that instead. The rest of the data on the URL (in this case "beverages") can get passed in as parameters to the ASPX page.

Even More Advanced Routing

To get parameter values there are a number of helper APIs that SmartyRoute offers. The simplest way is to call SmartyRoute.GetRouteMatch().PathInfo, which will return everything after the last "/" of what was handled in the request. For example, if the user requests ~/category/beverages and it gets handled by ~/category.aspx then the remaining "beverages" value in the URL will be the path info:

    string category = SmartyRoute.GetRouteMatch().PathInfo; // category == "beverages" 

If the path info contains multiple segments there is an alternative API that will do some of the heavier lifting for the developer. For example, if the URL is ~/category/beverages/5 (where "5" is the page number) there are these helpers:

    string category = SmartyRoute.GetNextRouteValue(); // category == "beverages"
    int page = SmartyRoute.GetNextRouteValue<int>(); // page == 5

Setting It Up

To use SmartyRoute in an application add a reference to the eStuff.Routing project and then go to your global.asax.cs and add this simple registration:

    string[] supportedExtensions = new[] { "aspx", "ashx" };
    RouteTable.Routes.Add(new SmartyRoute(supportedExtensions));

And that’s it!

Sample Project

In the attached sample project (13KB) there is the eStuff.Routing project and a sample ASP.NET Web Application Project. Open the solution in Visual Studio 2008 (with SP1) and try out these URLs:

  1. http://localhost:59519/Default (will load ~/default.aspx)
  2. http://localhost:59519/foo/bar (will load ~/foo/bar.aspx)
  3. http://localhost:59519/category/beverages/5/soda (will load ~/category.aspx with parameters)
  4. http://localhost:59519/MyHandlers/Boring (will load ~/MyHandlers/Boring.ashx handler)
  5. http://localhost:59519/MyHandlers/CoolStuff/Quote (will try to load ~/MyHandlers/CoolStuff/Quote.ashx handler but will fail due to web.config security)

Note that you can still make requests using the file extensions: SmartyRoute doesn’t block any current functionality (not really, anyway).

Feedback, Please!

I’d love to hear whether people find this sort of routing functionality useful. The key advantage of this simplified routing system is that you, the developer, don’t have to specify any URL route formats, yet you get most of the advantages of ASP.NET Routing: Extensionless URLs, custom data in the path info, better SEO.

Would you use this in an application that you are building?

Are you already doing something similar in an existing application?

7 Comments

  • Sounds pretty handy!

  • Brilliant. I might give a little more thought to the brand name, tho, before trademarking it. :-)

  • Very nice idea. I looks really useful.

  • Neat idea,

    This is the classic "Why those guys don't think in that before". I'm sure many teams trying to embrace the ASP.Net 3.5 Routing or even jump into the train of MVC.Net would find this very handy to "sale" the "REST" concept in the team itself or the company, I even would be interested on apply this in our current dev efforts to help close the gap between the legacy (ASP.Net) and the new (MVC.Net) sections of the site.

    One point I would like to see being addressed in this SmartyRoute approach is how will be processed the query string parameters, and the options available to map those into more RESTfull URL's.

    Cheers for the efforts...

  • We are using routing to create more advanced SEO URLs like

    /{category} -> category.aspx

    /{category}/{product} -> product.aspx

    the issue is where we need to treat same url patterns like:

    /{category}

    /{manufacturer}

    /{blog}

    /{contact}

    all these will be treated by same handler.

    I haven't found yet an elegant solution to this (besides an if else structure or case) however the URLs are much more relevant than adding a word in URL just to match a pattern

    if you have a good solution to this please let me know cristian.micliuc@heavensolutions.com




  • I like the sound of this. Implimentations a lot like this have been popular for years, typically achieved through ISAPI filters and rewrite rules.

    Conditional rules and mappings like this are very convenient for developers. Conditional rules can help increase productivity by making application development faster and applications simpler.

    I love the conditional mappings already built-in with ASP.NET MVC, e.g. between Controllers and Views. I make extensive use of it in my own blog. I also like having the ability to override these conditions, e.g. explicitly specifying the View.

  • What's happened to SmartyRoute will it be bundled with ASP.NET in the future?

Comments have been disabled for this content.