Outbound Urls with Regular Expression Routes

An entry about asp.net mvc Publication date 28. March 2008 21:38

A couple of weeks back, I wrote a post about how one could implement a custom Route which used regular expressions to define the routing. It didn't take me long though to figure out one major flaw with using regular expressions for the routes (and I bet this is why the Asp.Net MVC team didn't include them in the framework, at least not yet)...

You see, Asp.Net MVC has this great feature where it can generate an outbound url by 'reverse engineering' the routes. Let's look at an example. Assume you have a controller HomeController and an action Index on it:

public class HomeController : Controller
{
    public void Index()
    {
        RenderView("Index");
    }
}

 

And a route defined as follows:

routes.Add(new Route("{controller}/{action}/", new MvcRouteHandler());

 

Then you can use the ActionLink helper method to create a hyperlink for executing that action:

<%= this.Html.ActionLink((HomeController c) => c.Index(), "Home") %>

 

This will then render a hyperlink which links to "Home/Index". The benefit of doing this instead of hard coding the hyperlink, is that refactoring the names of controllers and actions won't result in broken links.

The magic that makes this work, is the GetVirtualPath method on the RouteBase class. The default Rule implementation performs some string parsing of the route pattern, and is able to construct a link using it. However, for my RegexRoute, implementing the GetVirtualPath method gets tricky - given a set of route values (the controller name, the action name and any parameters the action takes), how can we reverse engineer the regular expression pattern and build an URL? With a normal route pattern it's easy, because it is just a tokenized string with a well-defined, one-to-one match against a set of values -but a regular expression can contain wildcards, optional groups and so forth, resulting in it possibly having many valid matches for a set of values...

Thus, I can't really see a way to implement a generic algorithm that can come up with a url which matches the pattern given a set of values. Which means that basically, routes defined with regular expressions will not support outbound url generation.

A Possible Workaround

A workaround would be if you provide the code to generate that url on a route by route basis by deriving from the RegexRoute class and overriding the GetVirtualPath method. This could also be simplified by including a property on the RegexRoute class that would take a delegate that could be used to inject the GetVirutalPath implementation, so you'd get syntax looking something like this:

routes.Add(new RegexRoute("^(?<controller>.*?)//(?<action>.*?)(.aspx)?$", new MvcRouteHandler())
{
    GetVirtualPath = ((route, context, dictionary) => 
                            new VirtualPathData(route, String.Format("{0}/{1}/", dictionary["controller"],dictionary["action"])))
});

 

If anyone have any better ideas, I'd love to hear about them :)

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Powered by BlogEngine.NET 1.4.5.0

Welcome!

My name is Fredrik Kalseth, and this is my blog - thanks for visiting! I am fortunate enough to work with what I love for a living, and this blog is essentially the biproduct of that.

I work as a senior consultant for Capgemini, and am also an active participant in the Norwegian .NET community, as an avid attendee but also as a speaker (most recently at NNUG and MSDN Live).

As a developer, I have a wide circle of interest. My primary passion is for agile, test-driven development, with focus on best practices and clean code. That said, I also love to work on the frontend, especially with web development.

On Twitter? My handle is fkalseth. On LinkedIn? I`m there too.

NDC 2010

The conference to attend this summer happens June 16th-18th in Oslo, Norway. Are you going? Be sure to catch my talk on AOP while you're there!

 

Disclaimer

This is a personal blog; any opinions expressed here are my own and do not necessarily reflect those of my employer. All content herein is my own original creation, and as such is protected by copyright law. Unless otherwise stated, all source code posted on this blog is freely usable under the Microsoft Permissive License.

What Readers Talk About

Comment RSS