asp.netasp.net-coreasp.net-web-apiodata

Conflicting method/name for an OData Endpoint


My program.cs looks like below:

.
.

builder.Services.AddControllers()
.AddOData(options =>
{
    options.Select().Count().AddRouteComponents(WeatherEDM.GetEdmModel());
});
.
.
.
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

WeatherEDM:

public class WeatherEDM
    {
        public static IEdmModel GetEdmModel()
        {
            var builder = new ODataConventionModelBuilder();
            builder.Namespace = "Weather NS";
            builder.ContainerName = "Weather Container";

            builder.EntitySet<WeatherForecast>("WeatherForecast");

            return builder.GetEdmModel();
        }

WeatherForecastController.cs:

[Route("[controller]")]
public class WeatherForecastController : ODataController
     .
     .
     .
     [HttpGet]
     [EnableQuery]
     public IQueryable<WeatherForecast> Get()
     {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
          Id = index,
          Date = DateTime.Now.AddDays(index),
          TemperatureC = Random.Shared.Next(-20, 55),
          Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        }).AsQueryable();
      }

When I am trying to run the API, the Swagger is throwing an error like this:

An unhandled exception has occurred while executing the request. Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Conflicting method/path combination "GET WeatherForecast" for actions - Weather.Controllers.WeatherForecastController.Get (Weather),Weather.Controllers.WeatherForecastController.Get (Weather). Actions require a unique method/path combination for Swagger/OpenAPI 3.0. Use ConflictingActionsResolver as a workaround

Although when I remove Route[..] attribute from the controller, the app loads without errors.

Can someone please tell what is going wrong here on adding Route[..] attribute.


Solution

  • @Mrityu

    This error makes sense to me since you have builder.EntitySet<WeatherForecast>("WeatherForecast"); in your model builder.

    OData library will try to build the endpoint for all actions within WeatherForecastController, (be noted, the controller convention is 'entitysetname' + Controller).

    public IQueryable<WeatherForecast> Get() methods follow up query entity set convention. So, OData builds HttpGet /WeatherForecastController endpoint.

    Meanwhile, you have [Route("[controller]")] on your controller, it goes to normal asp.net core attribute routing, that is ASP.NET Core builds the same endpoint for Get() method.

    So, you got the "conflicting method". Remove Route[..] should work. If you want to get odata and non-odata responses both from one controller/action, you should make the route template distinguish. One option is add a prefix when calling AddRouteComponent. Hope it can help.