Attribute Routing in Web API 2

This article explains Attribute Routing in Web API 2 and the necessity of it.

Since you have clicked on this article by seeing the title, I will assume you have a fundamental understanding of MVC design patterns and understanding of Routing in MVC. Well, you have. Then let’s start our explanation.

We know that routing is a mechanism to transfer HTTP requests to an appropriate Action. It goes through several pipelines and filtering processes. But that’s not our core explanation. Anyway, routing in Web API is very similar to Routing in ASP.NET MVC. The only difference is that the Web API uses the HTTP method (GET, PUT, POST and so on) to map to the correct action, not URI path like ASP.NET MVC.

Although you are allowed to use ASP.NET style routing in Web API by setting an action name (we will discuss it in another article).

Attribute Routing is the new feature that has been initiated in Web API 2. Now, let’s discuss the necessity of Attribute Routing.

Why another routing?

When does Web API use convenience-based routing? Attribute Routing leverages the limitation of convenience-based routing. In this routing, you can define one or more route templates, that are basically parameterized strings.

Now let’s think about the situation where a student information service system wants to serve student data using a Web API service.

The requirement is, a URL consumer can access all the submitted fees, pending fees and deduction fees of a specific student. Let’s try to implement the URL.

www.mystudentservice/student/1/pending
www.mystudentservice/student/1/paid
www.mystudentservice/student/1/deduce

Now, think that we are passing a student ID in the middle of the URL.

Let’s think if another scenario. Here in one blog service, the user wants to read all blogs that were submitted in a specific month of a certain year. The URL might be very similar as in the following.

www.blogservice/articles/2014/1   

Here the consumer is requesting to show all the blogs that have been posted in the month of January in 2014. Now, this type of URL is a little bit tough in ASP.NET routing mechanism. But we can do them using Attribute Routing very easily.

Let’s try to implement Attribute Routing in our Web API 2 application.

Step 1: Ensure that your entire configuration has been initialized

The is the first step. Open your Global.asax page of the Web API application. Don’t forget to add the last line at last of the Application_start() event. It will ensure that your configuration has been initialized properly.

protected void Application_Start()

{

      WebApiConfig.Register(GlobalConfiguration.Configuration);
     
RouteConfig.RegisterRoutes(RouteTable.Routes);

      BundleConfig.RegisterBundles(BundleTable.Bundles);

      GlobalConfiguration.Configuration.EnsureInitialized();

}

Step 2: Setting in WebApiConfig.cs file

This is the second tuning in our application if we want to enable Attribute Routing. Open the "WebApiConfig.cs" file in your application. This file contains the Register() static function where we can register our custom method and inject it into the controller or action. Within the register function we will call the MapHttpAttributeRoutes() function that will enable attributing routing in the application by mapping the HTTP request flow to an appropriate action.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web.Http;

using TestWEB_API.Controllers;

 

namespace TestWEB_API

{

    public static class WebApiConfig

    {

        public static void Register(HttpConfiguration config)

        {

            config.MapHttpAttributeRoutes();

            //config.Routes.MapHttpRoute(

            //    name: "DefaultApi",

            //    routeTemplate: "api/{controller}/{id}",

            //    defaults: new { controller = "Values", id = RouteParameter.Optional }

            //);           

        }

    }

}

In my case, I have commented out the default route template. If you want, you can keep it happily.

Step 3: Set Route attribute to Action

We have done all our settings, now it’s time to set the Route attribute on Action. In this example we have created a Student controller and over the Get() method, we are setting Attribute Routing by providing the following attribute.

[Route("api/myRoute/{id}")]

 
The “api/myRoute/” is a fixed string and the “id” part is a placeholder. In other words, we will only provide the id value along with a fixed string in the browser’s URL.
 

using System;

using System.Collections.Generic;

using System.Collections.Specialized;

using System.Linq;

using System.Net.Http;

using System.Web;

using System.Web.Http;

using System.Web.Http.Dispatcher;

using System.Web.Mvc;

using System.Web.Routing;

using TestWEB_API.Models;

using System.IO;
 

namespace TestWEB_API.Controllers

{   

    public class StudentController : ApiController

    {

        [Route("api/myRoute/{id}")]

        public void Get(int id)

        {

        }

    }

}

 
Now, Let’s run the application and provide the following URL.

“api/myRoute/1”

If everything is fine then we will see the following output. We are seeing that the HTTP request has hit on our Get() action. And the fact to note is that we did not provide a controller name in the URL. We have just supplied the fixed string as defined in the Route attribute in the Action.

Route attribute

So, Cheers!!! Our first example in Attribute Routing is working and very quickly we will learn a few more important concepts of Attribute Routing.

Let’s implement another little complex URL to understand the power of Attribute Routing.

Let’s think about one order processing application where we want to search for order information by customer ID (cid) and order ID (oid).  The URL formation is as in the following.

api/customer/{cid}/Orders/{oid}

In this URL pattern there are two placeholder values that we need to supply to get a specific order information of a specific customer. Have a look at the following output screen. We are trying to get the 1st order of the first customer and the Get() action is being hit.

Get Action

Set route prefix to controller

If we don’t want to set the full routing path to each and every action, we can set the route prefix over the controller. And all the actions within this controller will be effected with the same prefix. Have a look at following example.
 

namespace TestWEB_API.Controllers

{   

    [RoutePrefix("api/customer")]

    public class StudentController : ApiController

    {

        [Route("{cid}/Orders/{oid}")]

        public void Get(int cid, int oid)

        {

        }

    }

}


In this example we have placed the constant part of the Route within the RoutePrefix attribute of the Student controller. And when we are hitting the same URL in the browser, our Get() method is being executed.

RoutePrefix attribute

Conclusion

In this example we have learned to implement Attribute Routing in a Web API 2 application. I hope you have understood the power and flexibility of Attribute Routing of Web API 2.