Skip to content

Single version-neutral controller and DefaultApiVersion set to neutral causes AmbiguousMatchException #1011

Closed
@siewers

Description

@siewers

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.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions