Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
To start, this is a bit obscure and likely not something a lot of people will ever encounter.
If I set DefaultApiVersion
to ApiVersion.Neutral
and only have a single controller annotated with [ApiVersionNeutral]
I'm getting an AmbiguousMatchException.
I've tracked it down to how the ApiVersionMatcherPolicy
handles neutral endpoints, and it seems like the endpoint is added twice in this specific case here.
The issue might also be in the ApiVersionCollator
, I'm not sure.
Expected Behavior
I would expect the endpoint to be accessible as normal, and did not expect an exception to happen, although I understand the configuration is unusual.
Steps To Reproduce
using Asp.Versioning;
using Asp.Versioning.Conventions;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddApiVersioning(options =>
{
options.DefaultApiVersion = ApiVersion.Neutral;
})
.AddMvc(options =>
{
options.Conventions.Add(new VersionByNamespaceConvention());
});
var app = builder.Build();
app.UseRouting()
.UseEndpoints(endpoints => endpoints.MapControllers());
app.Run();
[Route("[controller]")]
[ApiController]
[ApiVersionNeutral]
public class NeutralController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok("Neutral yay!");
}
}
#region Remove this region and it breaks
namespace V1
{
[Route("v{version:apiVersion}/[controller]")]
[ApiController]
public class VersionedController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok("Versioned yay!");
}
}
}
#endregion
Exceptions (if any)
By removing or commenting out the region in the repro, you will get the following error:
An unhandled exception occurred while processing the request.
AmbiguousMatchException: The request matched multiple endpoints. Matches:
NeutralController.Get (ControllerFilterTests)
NeutralController.Get (ControllerFilterTests)
Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ReportAmbiguity(CandidateState[] candidateState)
.NET Version
7.0.306
Anything else?
My team spent quite some time getting to the bottom of this, and in our case, the solution was to simply remove the [ApiVersionNeutral]
attribute.
However, I don't think this is expected behavior and it was very difficult to track down.