Search code examples
asp.net-coreasp.net-core-webapiaspnet-api-versioning

ASP.NET Core MVC API versioning by URL segment with Asp.Versioning.Mvc


I try to versioning ASP.NET Core MVC API with Asp.Versioning.Mvc.

I create a new project like :

dotnet new webapi --framework net7.0
dotnet add package Asp.Versioning.Mvc --version 7.0.1

Next, I remove all controllers and edit Program.cs like :

using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddApiVersioning();


var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();


app.Run();


[ApiVersion(1.0)]
[Route("api/v{version:apiVersion}/helloworld")]
public class HelloWorldController : ControllerBase
{
    public string Get() => "Hello world! v1";
}

[ApiVersion(2.0)]
[Route("api/v{version:apiVersion}/helloworld")]
public class HelloWorld2Controller : ControllerBase
{
    public string Get() => "Hello world! v2";
}

But when I start the API and call http://localhost:5069/api/v1.0/helloworld, I get this error :

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches: 

HelloWorldController.Get (ApiVersioningPoc)
HelloWorld2Controller.Get (ApiVersioningPoc)
   at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ReportAmbiguity(CandidateState[] candidateState)
   at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ProcessFinalCandidates(HttpContext httpContext, CandidateState[] candidateState)
   at Microsoft.AspNetCore.Routing.Matching.DfaMatcher.MatchAsync(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

I found this similar question :

Asp.Versioning.Http AmbiguousMatchException: The request matched multiple endpoints on controllers

I try to add AddMvc (from the answer) without success.


Solution

  • You definitely need AddMvc() after the AddApiVersioning() part because you are using Controllers instead of the Minimal APIs approach in this example.

    After that you need to add the [ApiController] attribute to both of your Controllers like this:

    [ApiVersion(1.0)]
    [ApiController]
    [Route("api/v{version:apiVersion}/helloworld")]
    public class HelloWorldController : ControllerBase
    {
        public string Get() => "Hello world! v1";
    }
    
    [ApiVersion(2.0)]
    [ApiController]
    [Route("api/v{version:apiVersion}/helloworld")]
    public class HelloWorld2Controller : ControllerBase
    {
        public string Get() => "Hello world! v2";
    }
    

    The library needs this attribute setup for all of your controller to work properly.