You can do this by overriding DefaultHttpControllerSelector
there you override the selectcontroller method
public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { HttpControllerDescriptor controllerDescriptor = null; IDictionary<string, HttpControllerDescriptor> controllers = GetControllerMapping(); IHttpRouteData routeData = request.GetRouteData(); if (routeData == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } object apiVersion; if (!routeData.Values.TryGetValue("Version", out apiVersion)) { apiVersion = "1"; } object controllerName; if (!routeData.Values.TryGetValue("controller", out controllerName)) { controllerName = string.Empty; } if (controllerName == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } string newControllerName = String.Concat(controllerName.ToString(), "V", apiVersion); if (controllers.TryGetValue(newControllerName, out controllerDescriptor)) { return controllerDescriptor; } if (controllers.TryGetValue(controllerName.ToString(), out controllerDescriptor)) { return controllerDescriptor; } throw new HttpResponseException(HttpStatusCode.NotFound); }
Then you add webapiconfig routes
config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{version}/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
and register controller selector in webapiconfig
config.Services.Replace(typeof(IHttpControllerSelector), new ApiVersioningSelector(config));
So now, if you select the ProductsV1Controller controller, it will be reffer / api / v1 / products. Also note that my example also supports routes without version, so if v1 is not found, it will try to check if ProductsController exists
PS. The code updates one error :(
Volodymyr bilyachat
source share