Global route prefixes with attribute routing in ASP.NET 5 and MVC 6

In the last post a few days ago we looked at adding a centralized route prefix to attribute routing in ASP.NET Web API.

I got a couple of follow up question about how to achieve the same in ASP.NET 5 and MVC 6 framework. Let’s have a look then (btw: this article is written using beta8 version of ASP.NET 5).

Update June 2016

This post was written for ASP.NET Core beta8 and is now out of date. Please have a look at the updated version of the post.

Attribute routing in MVC 6

First of all, the attribute routing in MVC 6 is much different then the implementation in Web API. The implementation details are no longer exposed, and there is no interface similar to IDirectRouteProvider which allows you to modify the routing behavior.

Instead, the encouraged way of adapting MVC 6 to your needs (and not just for routing – but for all other configuration scenarios) is to use conventions.

If you follow this blog, I have already blogged about that, in an article where we were building strongly typed routing using application conventions.

Using the same technique, we can support a centralized route prefix:

Another thing worth noting, is that in ASP.NET Web API, we had RouteAttribute – for defining a route on an action, and RoutePrefixAttribute for defining controller-wide prefixes.

In MVC 6, it’s a little simpler because there is only one RouteAttribute – if you put one ona controller, and there is another on an action in that controller, they will simply get merged together to produce a single route template. This has a de facto net result that’s the same as with RoutePrefixAttribute in Web API.

Creating RouteConvention

Since we have already established we need a custom IApplicationModelConvention, let’s create it. We’ll need to loop through all controllers.

Each controller that we loop through, will expose its attribute routing information via AttributeRoutes collection. This is a collection of objects describing the route metadata and the outline of a single item is shown below.

Based on all that information, our approach and convention can be:

  • loop through all controllers
  • determine if it has any attribute routes
  • and if that’s the case, apply the central route prefix, otherwise, we create a new list of attribute routes just adding the central prefix as the only controller-level attribute route

You can apply the central prefix using AttributeRouteModel.CombineAttributeRouteModel static method. It simply takes a left attribute route and right attribute route and merges them together.

And that’s it. You can can enable this convention in your Startup class, when calling AddMvc.

If you recall the Web API article from a few days ago, we capped it off with a slightly more interesting scenario, where we had a central version prefix.

The same could be achieved here, you can add any route parameter into the central prefix i.e.:

And you now have access to that version in any controller action you create: