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

avatar

4 responses

  1. Avatar for David Pfeffer
    David Pfeffer July 16th, 2012

    Can you create/publish a NuGet?

  2. Avatar for maartenba
    maartenba July 18th, 2012

    Contributing it to https://github.com/maartenb.... Let&#39s wait for Phil an see if he adds it ino RouteMagic (an excellent package by the way)

  3. Avatar for Kevinhan
    Kevinhan October 8th, 2013

    hi. I'm always find a sub-domain routing solution under normal asp.net mode but not MVC. Could you please give me some help? thx

  4. Avatar for yas
    yas July 11th, 2015

    I run your code and got the Object Null Reference error. When I debug everything is working correctly in method GetRouteData and the method returns all values (contrller, action and id) correctly but related action of controller not executed and in the response of request I got the Object Null Reference error.

    stack trace is:
    [NullReferenceException: Object reference not set to an instance of an object.]
    System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) +220
    System.Web.Http.HttpServer.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) +254
    System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) +78
    System.Web.Http.WebHost.HttpControllerHandler.BeginProcessRequest(HttpContextBase httpContextBase, AsyncCallback callback, Object state) +286
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +12288923
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288

    Do you know where is the problem?