Domain based routing with ASP.NET Web API

Subdomain route ASP.NET Web API WCFImagine you are building an API which is “multi-tenant”: the domain name defines the tenant or customer name and should be passed as a route value to your API. An example would be http://customer1.mydomain.com/api/v1/users/1. Customer 2 can use the same API, using http://customer2.mydomain.com/api/v1/users/1. How would you solve routing based on a (sub)domain in your ASP.NET Web API projects?

Almost 2 years ago (wow, time flies), I’ve written a blog post on ASP.NET MVC Domain Routing. Unfortunately, that solution does not work out-of-the-box with ASP.NET Web API. The good news is: it almost works out of the box. The only thing required is adding one simple class:

1 public class HttpDomainRoute 2 : DomainRoute 3 { 4 public HttpDomainRoute(string domain, string url, RouteValueDictionary defaults) 5 : base(domain, url, defaults, HttpControllerRouteHandler.Instance) 6 { 7 } 8 9 public HttpDomainRoute(string domain, string url, object defaults) 10 : base(domain, url, new RouteValueDictionary(defaults), HttpControllerRouteHandler.Instance) 11 { 12 } 13 }

Using this class, you can now define subdomain routes for your ASP.NET Web API as follows:

1 RouteTable.Routes.Add(new HttpDomainRoute( 2 "{controller}.mydomain.com", // without tenant 3 "api/v1/{action}/{id}", 4 new { id = RouteParameter.Optional } 5 )); 6 7 RouteTable.Routes.Add(new HttpDomainRoute( 8 "{tenant}.{controller}.mydomain.com", // with tenant 9 "api/v1/{action}/{id}", 10 new { id = RouteParameter.Optional } 11 ));

And consuming them in your API controller is as easy as:

1 public class UsersController 2 : ApiController 3 { 4 public string Get() 5 { 6 var routeData = this.Request.GetRouteData().Values; 7 if (routeData.ContainsKey("tenant")) 8 { 9 return "UsersController, called by tenant " + routeData["tenant"]; 10 } 11 return "UsersController"; 12 } 13 }

Here’s a download for you if you want to make use of (sub)domain routes. Enjoy!

WebApiSubdomainRouting.zip (496.64 kb)

This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.

Leave a Comment