I am running into a problem with OData 8.x and attribute routing where duplicate routes are being generated to the same controller action. This duplicate route is causing Swagger / Swashbuckle to throw "Conflicting method/path combination" error.
I have been able to par this down to a slightly tweaked default Weather Forecasts template from Visual Studio 2019.
// Change name of controller to plural
// Added Route() attribute
// Changed ControllerBase to ODataController (issue happens with ControllerBase too)
[Route("api/[controller]")]
public class WeatherForecastsController : ODataController{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[HttpGet()]
public IEnumerable<WeatherForecast> Get() {
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast {
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
Adding OData was as simple as including the AddOData() call in Startup.cs
private IEdmModel GetEdmModel() {
var builder = new ODataConventionModelBuilder();
builder.EntitySet<WeatherForecast>("WeatherForecasts");
return builder.GetEdmModel();
}
public void ConfigureServices(IServiceCollection services) {
services
.AddControllers()
// Added this AddOData call
.AddOData(opt => {
opt
.Count()
.Filter()
.Select()
.OrderBy()
.SetMaxTop(20)
.AddRouteComponents("api", GetEdmModel());
});
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo { Title = "SwaggerODataTest", Version = "v1" });
});
}
As you can see there is only the single default Get() method in the controller -- i.e. ONE endpoint defined. Yet adding the Route() attribute causes the following exception
Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException:
Conflicting method/path combination "GET api/WeatherForecasts" for actions -
SwaggerODataTest.Controllers.WeatherForecastsController.Get (SwaggerODataTest),
SwaggerODataTest.Controllers.WeatherForecastsController.Get (SwaggerODataTest).
Actions require a unique method/path combination for Swagger/OpenAPI 3.0.
Use ConflictingActionsResolver as a workaround
It seems that both OData and ASP.NET Core (??) are processing the same controller twice and generating duplicate (conflicting) endpoints. Am I doing something wrong? Is there a way to tell ASP.NET Core not to parse controllers to generate routing endpoints and let OData do it?