I use Web API 2. I provide clients methods in version1:
http://localhost/version1/api/base http://localhost/version1/api/values It is mine controller:
[RoutePrefix("version1")] public class ValuesController : ApiController { [Route("api/base")] public string GetBaseMethod() { return "bbb"; } [Route("api/values")] public string GetVersion1() { return "aaa"; } } Now I would like to provide clients in version2 methods:
- /version2/api/base (method the same like in version1)
- /version2/api/values (method has changed, now it returns int, not string but address must be the same like in version1: /api/values)
So I have the second controller with inheritance:
[RoutePrefix("version2")] public class Values2Controller : ValuesController { [Route("api/values")] public int GetVersion2() { return 5; } } I have enabled attribute routes inheritance in WebApiConfig.cs:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(new CustomDirectRouteProvider()); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } } public class CustomDirectRouteProvider : DefaultDirectRouteProvider { protected override IReadOnlyList<IDirectRouteFactory> GetActionRouteFactories(HttpActionDescriptor actionDescriptor) { return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>(inherit: true); } } Result:
http://localhost/version1/api/base
- it works.
http://localhost/version2/api/base
- it works.
http://localhost/version1/api/values
- it works.
http://localhost/version2/api/values
- it DOESN”t work. I have error:
{ "Message": "An error has occurred.", "ExceptionMessage": "Multiple actions were found that match the request: \r\nGetVersion2 on type WebApplication1.Controllers.Values2Controller\r\nGetVersion1 on type WebApplication1.Controllers.Values2Controller", "ExceptionType": "System.InvalidOperationException", "StackTrace": " w System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n w System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n w System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n w System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()" }
What can I do?
Routeattribute on the base class, specifying it again in the class that implements the base causes the conflict.