Web API 2's Attribute Routing: Looking Deeper

  • Nov 12, 2013 at 1:38 PM
  • Shawn Wildermuth
  • 5 Comments

underwaterI recently recorded a new module for ASP.NET  Web API course (on Pluralsight) to cover the new features of Web API 2 (it’s not out yet, soon…I promise).

It was fun plumbing the depths of how it works. I generally like the feature but the implementation may change some of your code if you’re dealing with routes under the covers (i.e. for auth or versioning).

If you want a quick overview, I really like Dan Wahlin’s walkthrough of the feature here:

http://weblogs.asp.net/dwahlin/archive/2013/11/11/new-features-in-asp-net-web-api-2-part-i.aspx

While most of us are used to creating routes using the Web API configuration, attributed routes are different. Before attributed routing, when you would look at the route data (e.g. request.GetRouteData()) you would get a route with a name that tied to the configured name. This was really useful for the way to use UrlHelper to build your URLs.

In fact, you can get this behavior by supplying names to the individual routes in your attributed routing:

public FooController : ApiController
{
  [Route("api/foos", Name = "Foo")]
  public object Get()
  {
    // ...
  }
}

...

var helper = new UrlHelper(Request);
var url = helper.Link("Foo");

But if you’re traversing the route collection in any way (e.g. in a ControllerSelector) it is important to understand where these routes actually are. When you use attribute routing, all the route attributes get added to a common route without a name. This is a special route that is an instance of an internal class called RouteCollectionRoute (Source Link). This route has a collection of sub-routes that you can query for that includes *all* the attribute routes. But if you just want the selected route for your call, you can simple ask for it using the RouteData.Values:

var routeData = request.GetRouteData();
var subroutes = (IEnumerable<IHttpRouteData>)routeData.Values["MS_SubRoutes"];
var route = subroutes.First().Route;

The real problem for some is that there is no longer controller name in the route data. This makes sense of course because there is no specific controller that a route points to as attributed routes are related to methods, not controllers. Being aware of these internals may help you solve issues when you use or move to using attributed routes.

Hope this helps!

 

Comments

Gravatar

Rune Monday, January 20, 2014

Hi,

I've watched your great "Implementing ASP.NET Web API" course on PluralSight.
Do you know of any code samples where versioning (not url) and attributed routing is being used?

What is your personal perferences? Do you use the old routing style or are you using attributed routing when versioning is required?

Thanks,
Rune

Gravatar

Shawn Wildermuth Monday, January 20, 2014

I use attributed routes for exceptions and standard routing for main cases.


Leave a Comment

*
*
*