Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
I'm experiencing an issue where ApiVersionMatcherPolicy
invalidates a valid candidate, from what looks to be an attempt to optimize performance.
The setup is quite cumbersome, but I managed to setup a minimal solution to verify it (See below).
The use case is when I have a plain old WebAPI without any versioning and I have two endpoints with the same route. Furthermore I need to have a dynamic route, to even hit this code in the ApiVersionMatcherPolicy
.
When I try to call ny POST endpoint, it returns 404, because it have been invalidated by ApiVersionMatcherPolicy
that finds the GET endpoint as the bestMatch
. This is a problem because the ApiVersionMatcherPolicy.Order
is hardcoded to be lower than HttpMethodMatcherPolicy.Order
.
The issue is originally reported in Umbraco here: umbraco/Umbraco-CMS#16434
Expected Behavior
My GET endpoint is hit, like if ApiVersionMatcherPolicy
is removed from the service collection.
Steps To Reproduce
I have setup a minimal setup, that shows the issue.
https://github.com/bergmania/DemoIssueWithAPIVersioning
On a new MVC project, I added a dependency
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
I added the following in program.cs
builder.Services.AddApiVersioning(x=>x.AssumeDefaultVersionWhenUnspecified = true).AddApiExplorer();
builder.Services.AddSingleton<MyDynamicControllerRoute>();
Before var app = builder.Build();
and the following afterwards
app.MapDynamicControllerRoute<MyDynamicControllerRoute>("/{**slug}");
Furtheremore I have a single file with two classes
using System.Net.Mime;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
namespace WebApplication5;
public class MyDynamicControllerRoute : DynamicRouteValueTransformer
{
public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
{
return ValueTask.FromResult(values);
}
}
[ApiController]
[Route("api/")]
public class ShowBugController : Controller
{
[HttpPost("test")]
[ProducesResponseType(StatusCodes.Status200OK)]
[Consumes(MediaTypeNames.Application.Json)] // This is important because it leads to a lower (better) score when the request enter the ApiVersionMatcherPolicy, even when requested with http GET
public IActionResult MyPost()
{
return Ok("OK POST");
}
[HttpGet("test")]
[ProducesResponseType(StatusCodes.Status200OK)]
public IActionResult MyGet()
{
return Ok("OK GET");
}
}
Exceptions (if any)
No response
.NET Version
8.0.303
Anything else?
No response