I searched for my problem beforehand in various sources but the answers did not provide me with a solution.
I implemetend Url based web api versioning in a .net core 2.2 project with the way presented here. The version that I used for versioning is the latest Microsoft.AspNetCore.Mvc.Versioning 3.1.2. I also tried to understand how it works from the following sources: source1, source2, source3, source4.
I am having a ValueController with a GET method in a folder called Initial and a Value2Controller in a folder called New. Both folders are subfolders of the 'Controllers' folder.
The structure is as follows:
The routing in ValueController is
[Route("api/v{version:apiVersion}/[controller]")]
and in Value2Controller is:
[Route("api/v{version:apiVersion}/value")]
I have also set options.EnableEndpointRouting = false; in the Startup.cs and I tried calling api/v1/value or api/v2/value. Both times I get the error: Multiple actions matched. It cannot differentiate between the two controllers actions.
I tried using services.AddApiVersioning(); with no options at all and remove AddVersionedApiExplorer. It does not work. The only thing that works is
putting
[Route("api/v{version:apiVersion}/[controller]")]
in both controllers and make the following api calls:
api/v1/value and api/v2/value2.
The configuration in my startup.cs is as follows:
services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
options.ApiVersionReader = new UrlSegmentApiVersionReader();
options.UseApiBehavior = true;
});
services.AddVersionedApiExplorer(
options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
});
What am I missing to call either api/v1/value or api/v2/value and go to the correct request?
Routeattribute isv{apiVersion:int}rather than what you currently have, this specifies that the apiVersion parameter for your method is of type int. The supported route constraints are listed in the table here. This assumes that the version parameter in your controller method is of type int and is calledapiVersion.[ApiController]attribute and your controller methods with the[ApiVersion]attribute as per this documentation. They should look like[ApiVersion("1.0")]and you can go back to usingv{version:apiVersion}inside your[Route]attributes, there are example URLs on that page too.[ApiController]and[ApiVersion("n.0")]attributes and on a specific method I mapped it as[HttpGet("{id}"), MapToApiVersion("3.0")]. I followed the documentation to the letter but I get multiple actions matched error.[Controller]andvalueearlier on because I believe it is doing naive matching based on types. So if you had[Route("api/[controller]/v{version:apiVersion}")]on both, or some other item in place of "controller" then the router would be able to tell the difference between the routes, because currently what it is seeing is two routes that look likeapi/vXand it doesn't know how to pick between them - hence why addingvalueandcontrollerto the route definition "worked" for you. Hope this makes sense.