Imagine you are declaring your routes as follows:
config.Routes.MapHttpRoute("defaultVersioned", "v{version}/{controller}/{id}", new { id = RouteParameter.Optional }, new { version = @"\d+" }); config.Routes.MapHttpRoute("default", "{controller}/{id}", new { id = RouteParameter.Optional });
Now you can create separate controllers for individual versions using a specific naming convention, for example:
public class FooController : ApiController {} public class FooV2Controller : ApiController {} public class FooV3Controller : ApiController {}
Now, since the version is part of your route, you can implement a specialized controller selector where you get the version from the route and select the appropriate controller based on this.
public class VersionAwareControllerSelector : DefaultHttpControllerSelector { public VersionAwareControllerSelector(HttpConfiguration configuration) : base(configuration) { } public override string GetControllerName(HttpRequestMessage request) { var controllerName = base.GetControllerName(request); var versionFinder = new VersionFinder(); var version = versionFinder.GetVersionFromRequest(request); if (version > 0) { return GetVersionedControllerName(request, controllerName, version); } return controllerName; } private string GetVersionedControllerName(HttpRequestMessage request, string baseControllerName, int version) { var versionControllerName = string.Format("{0}v{1}", baseControllerName, version); HttpControllerDescriptor descriptor; if (GetControllerMapping().TryGetValue(versionControllerName, out descriptor)) { return versionControllerName; } throw new HttpResponseException(request.CreateErrorResponse( HttpStatusCode.NotFound, String.Format("No HTTP resource was found that matches the URI {0} and version number {1}", request.RequestUri, version))); } }
This code uses the helper class VersionFinder , which can be found here .
Then you just need to register a custom selector:
config.Services.Replace(typeof(IHttpControllerSelector), new VersionAwareControllerSelector(config));
For a complete example, take a look here on Github , this is part of the ASP.NET Web API 2 Recipes book.