Web API 2 Routing Attributes, Part 1

Microsoft has recently released the Visual Studio 2013 Preview 1, which includes ASP .NET Web API 2. One of the most notable new additions to Web API is attribute-based routing. Prior to version 2, all routing in Web API was convention-based, as it is in ASP.NET MVC. Convention-based routing is great for most cases, but can be cumbersome if you need to specify many custom route templates.

You may want to use attributed routing if you need many custom routes in a controller, or just want to have a more SEO-friendly routes. Web API 2 includes a few different types of routing attributes. To start with, the base HttpGet, HttpPut, HttpPost, and HttpDelete now have an override that allows you to specify a custom route template. For example, if your Web service is for a blog, you could have a route for a particular entry in multiple formats, such as blog/2013-8-28/ or blog/8-28-2013/ to retrieve all entries for Aug. 28, 2013. You can also create more complex routes too; if you wanted to get all blog posts from a particular author for a given date, you could define a route like blog/evogel/2013-8-28/.

In addition to just overriding routes for a particular controller action, you can also set a custom route template for an entire controller by using the RoutePrefix attribute. The RoutePrefix attribute is best to use when you want all of your controller actions to have a particular custom path. For example, if you wanted all blog posts to be available at api/blogs, you'd use the following RoutePrefix attribute:

[RoutePrefix("api/blogs")]

You can also apply constraints and default values in a controller action route attribute. The built-in route template constraints include some value-type checks as well as range checks. For example, to specify that a route template parameter named orderId is an integer type, you'd use the following attribute:

[HttpGet("orderId:int")]

There's also an included regex parameter constraint for high flexibility. In addition, you can create custom route template constraints by implementing the IInlineContraintResolver interface; but I'll leave that for a future article.

Now let's build an app that includes some of the aforementioned custom routing attributes in Web API 2. The sample application allows the consumer to create, update and retrieve blog posts by date or author in an SEO-friendly manner. First, create a new ASP.NET project in Visual Studio 2013, as seen in Figure 1.

[Click on image for larger view.]Figure 1. Creating the new ASP.NET project.

The first step is to set up the data access library for the Web service. The data access layer (DAL) will use Entity Framework to create, update, delete and retrieve blog posts. Create a new Class Library project and name it DAL, with the same namespace as your Web API project. Next, install Entity Framework 6 via NuGet, as seen in Figure 3.

As you can see, there are defined methods for retrieving all blog posts, and blog posts by a creation date or author. I've also added methods for retrieving a single blog post by its ID, and to update and add a blog post to the database. The next step is implement the IBlogRepository via the BlogRepository class. Create a new class file named BlogRepository in the Repository folder in your DAL project:

Then add the get by ID controller action method. The method is annotated with an HttpGet attribute with a "posts" path. In addition, I've set an integer type constraint on the route with a minimum value constraint of 1, and a route order of 3. This means that if any other controller action of the same name exists with a lower value, its route will have higher priority than this method. The actual Get method simply calls the GetById method on the blog repository:

It's time to add the get by author controller action method, which has an HttpGet attribute with an author regex type constraint; it allows words and white space with a route order of 2. The method simply calls the GetByAuthor method to retrieve all blog posts created by the given author:

Next, add the get by created date method that's annotated with an HttpGet attribute with date parameter. The date parameter is constrained to be of type date time and the route is given an order of 1. The GetByDate blog repository method is used to actually retrieve the needed blog posts:

As you can see, the new routing attributes are very easy to put to good use, and flexible. In addition, the attributes are extensible through custom routing parameter constraints. Stay tuned for the next article in the series, where I cover how to consume the Web API service from a Windows Store app.