Most of us already knew the traditional routing concepts in Web API which we configure in WebApiConfig file. This approach solves most of the basic routing problems, but it limits the granular control and flexibility over custom routes. Attribute based routing is a popular nuget which offers flexibility in managing routes at Controller/Action level. In this tutorial we are going to see how we can get the basic Attribute based routing works.
Before we go into some code, let me first share ScottGu’s recent blog post on Attribute based routing and community contribution – http://weblogs.asp.net/scottgu/archive/2013/04/19/asp-net-web-api-cors-support-and-attribute-based-routing-improvements.aspx. Lets thank Tim McCall – http://attributerouting.net/ for providing us with such a beautiful feature.
Lets get start by creating a new ASP.Net MVC4 Project with Web API template. Right click project and select Manage Nuget Packages, search for “AttributeRouting” and from the results install AttributeRouting (ASP.NET Web API) nuget.
Change ValuesController to this way –
using AttributeRouting; using AttributeRouting.Web.Http; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; namespace MvcApplication1.Controllers { [RoutePrefix("Products")] public class ValuesController : ApiController { [GET("GetEverything")] public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } [GET("GetProduct/{id}")] public string Get(string id) { return "value1"; } } }
Lets make first call using fiddler –
With optional parameter, you can add following action –
[GET("GetProductByName/{name?}")] public string GetByName(string name) { return name; }
Output –
Making a value as Route Default as follows –
[GET("GetProductByName/{name=Merc}")] public string GetByName(string name) { return name; }
Lets add constraints to the above route to accept only string as name with only 4 chars long.
[GET("GetProductByName/{name:alpha:length(4)=Merc}")] public string GetByName(string name) { return name; }
Output for invalid length –
We can have same action with multiple routes configured as shown below. ActionPRecedence is used to define the primary route.
[GET("GetEverything", ActionPrecedence = 1)] [GET("Index")] public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; }
we get following output (we have already seen “GetEverything” route outcome in above calls, so skipping that screen shot)-
To configure routes with QueryString parameter –
[GET("GetProduct/{id}?{x}")] public string Get(string id) { return String.Format("Passed Id : {0}, Passed Querystring: {1}", id, System.Web.HttpContext.Current.Request.QueryString["x"].ToString()); }
Output in fiddler –
To have a Route Area specified, append ValuesController with RouteArea attribute –
[RouteArea("My")] [RoutePrefix("Products")] public class ValuesController : ApiController
And then we can make calls with “My” appended in the url, as shown below –
There are many other things which we can accomplish using Attribute based routing, but the scope of this tutorial is limited. I will cover up advanced topics with attribute based routing in my coming tutorials.
Stay tuned.