I am trying to achieve header based versioning on my controllers with Asp.Versioning.Http package version 6.4.0
it is supposed to be super simple here however i get AmbiguousMatchException: The request matched multiple endpoints exception
Here is my Program class
and my controllers defined like that:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddApiVersioning(options => {
// options.ApiVersionReader = new HeaderApiVersionReader("api-version");
options.DefaultApiVersion = new ApiVersion(1.0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
}).EnableApiVersionBinding();
builder.Services.AddMvc();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
// app.UseSwagger();
//app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.MapHealthChecks("/health/live");
app.MapControllers();
app.Run();
namespace Things.Service.Controllers.V1
{
[ApiController]
[ApiConventionType(typeof(DefaultApiConventions))]
[Route("[controller]")]
[Asp.Versioning.ApiVersion(1.0)]
public class ThingsController : ControllerBase
{
// controller logic
}
}
namespace Things.Service.Controllers.V2
{
[ApiController]
[ApiConventionType(typeof(DefaultApiConventions))]
[Route("[controller]")]
[Asp.Versioning.ApiVersion(2.0)]`your text`
public class ThingsController : ControllerBase
{
// controller logic
}
}
I get this exception:
Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches:
Things.Service.Controllers.V2.ThingsController.GetAllAsync (Things.Service)
Things.Service.Controllers.V1.ThingsController.GetAllAsync (Things.Service)
This is happening because you are missing
AddMvc. Don't let the name fool you, this adds MVC Core, not the full MVC stack. Starting in6.0, the new setup pivots onIApiVersioningBuilderso that all of the setup is in one place and, hopefully, easier to follow. If you're coming from earlier versions (e.g. <=5.x), this might be a surprise. This change was necessary becauseAddApiVersioningis now the foundation for Minimal APIs, which doesn't include MVC Core or controller support.AddMvcadds those features.Since you're using MVC Core and controllers, you do not need
EnableApiVersionBinding. MVC Core has support for Model Binders.AddMvcwill register all those services. If you want to receive the incomingApiVersionin your controller action, you need only add a parameter of typeApiVersionwith the name of your choice. For example:Minimal APIs do not have a way to support this type of model binding.
EnableApiVersionBindingprovides a way to make it work. It won't hurt anything if you've added it, but it's unnecessary.Finally, it looks like you have included a version number in your namespaces. If this is indeed your setup, you might consider using the
VersionByNamespaceConvention. This would negate the need to decorate controllers with[ApiVersion]. The API version would be derived from the namespace itself. For additional details, see the Version By Namespace Convention documentation.