b.logrythmik

{ independency injection }

Expression-Based URLs in MVC - Using a Specific Route with LinkBuilder

In the MVC Future Assembly there lives a super handy class called "LinkBuilder". This class takes an expression and builds a URL using your configured routes.

Creating an extension method in your own project to use this class is pretty straight forward:

public static string Action<TController>(this UrlHelper helper, Expression<Action<TController>> action)

    where TController : Controller

{

    return Microsoft.Web.Mvc.LinkBuilder.BuildUrlFromExpression(helper.RequestContext, helper.RouteCollection, action);

}

You can also use this library to create your own "ActionLink" extensions too. BUT, this isn't why I wrote this article.

I wanted to extend this method to specify an EXACT route to use, as I had a special route to format the URLs and the above method uses the first route it finds that could work - usually the default route.

After struggling for hours trying to parse the expression myself (UGH!), a simple solution presented itself:

public static string Action<TController>(this UrlHelper helper, Expression<Action<TController>> action, string routeName)

    where TController : Controller

{

    var routeCollection = helper.RouteCollection;

 

    // Check to ensure this route exists first. If not, don't filter the routes.

    if (helper.RouteCollection[routeName] != null)
         routeCollection  = new RouteCollection { helper.RouteCollection[routeName] };

 

    return Microsoft.Web.Mvc.LinkBuilder.BuildUrlFromExpression(helper.RequestContext, routeCollection, action);

}

This method filters the RouteCollection down to the exact route you are want to use and passes the filtered collection to the LinkBuilder... ahhh, routing-bliss.

Now you can use it in your views like this:

<%= Url.Action<CredentialsController>(c => c.Edit(credID), "CredentialActions") %>