Search code examples
c#asp.net-coreasp.net-web-apiswagger-ui

Why is this API considered having ambiguous method/path combination when the names and routes are different?


Although I could change the names and assign a different attribute, I just don't understand why Swagger thinks this is ambiguous when everything is different between the two methods (except parameters)?

SwaggerGeneratorException: Ambiguous HTTP method for action - WebApplication5.Controllers.WeatherForecastController.GetWeatherB (WebApplication5). Actions require an explicit HttpMethod binding for Swagger/OpenAPI 3.0

This is the sample api from VS 2022.

  [ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }
    [HttpGet(Name = "TestB")]
    [Route("/TestRouteB")]
    public IEnumerable<WeatherForecast> GetWeatherB([FromQuery] QueryParameters queryParam)
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }

    [HttpGet(Name = "TestA")]
    [Route("/TestRouteA")]
    public IEnumerable<WeatherForecast> GetWeatherA([FromQuery] QueryParameters queryParam)
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }

This can be resolved by removing the "Name" attribute. But I thought that NAME attribute will resolve duplicate method names? In this case the value of Name on both methods are different ("TestA" and "TestB"), so I just want a basic explanation please why it's not being considered for uniqueness.


Solution

  • This looks like an issue/bug in Swashbuckle since there is no real ambiguity.
    Both endpoints on your controller are running perfectly fine. It is only Swashbucle that fails. The source code at GitHub shows that the error gets thrown here.

    In case you would have conflicting endpoints/routes then an AmbiguousMatchException would have been thrown by the ASP.NET Core framework when executing one of those endpoints.

    AmbiguousMatchException: The request matched multiple endpoints
    

    You can try that by using the same route template on both action methods.


    A route name does not take part in determining the uniqueness of an endpoint.
    From the documentation

    Route names:

    • Have no impact on URL matching or handling of requests.
    • Are used only for URL generation.

    For you to resolve, keep the name with the same attribute on which you set the route template.
    Do one of below.

    [HttpGet] 
    [Route("/TestRouteA", Name = "TestA")]
    public IEnumerable<WeatherForecast> GetWeatherA()
    
    [HttpGet]
    [Route("/TestRouteB", Name = "TestB")]
    public IEnumerable<WeatherForecast> GetWeatherB()
    

    Or

    [HttpGet("/TestRouteA", Name = "TestA")]
    public IEnumerable<WeatherForecast> GetWeatherA()
    
    [HttpGet("/TestRouteB", Name = "TestB")]
    public IEnumerable<WeatherForecast> GetWeatherB()