Search code examples
c#.net-6.0swagger-uiswashbuckleswagger-3.0

Multipe routes with same verb to .NET6 REST API controller


Has been a while since the last time with .NET Core 2 where it seemed to work without any hazzle.

But since starting with .NET6 I seem to struggle to have ApiController with multiple routes.

Relevant ConfigureServices:

     services.AddEndpointsApiExplorer();
     services.AddSwaggerGen();    
     services.AddControllers().AddApplicationPart(typeof(TestController).Assembly);

The application part is required because the controllers are in a different assembly.

Relevant ConfigureApp:

app.UseRouting();
app.MapControllers();
app.UseSwagger();
app.UseSwaggerUI();

My controller:

[ApiController]
[Route("[controller]")]
[Consumes("application/json")]
[Produces("application/json")]
public class TestController : ControllerBase
{

    [HttpGet("Test1")]
    public IActionResult GetTest1()
    {
        return Ok(Array.Empty<string>());
    }

    [HttpGet("Test2")]
    public IActionResult GetTest2()
    {
        return Ok(Array.Empty<string>());
    }

    [HttpGet("Test3")]
    public IActionResult GetTest3()
    {
        return Ok(Array.Empty<string>());
    }

}

They show up in Swagger UI as intended.

enter image description here

But when I try to execute them I always get

curl -X 'GET' \
  'http://localhost:5000/Test/Test1' \
  -H 'accept: */*'

404: Error Not Found

Addition: They are visible in the UI Wrong: but not included in the generated swagger.json in the background. Correct: Not showing up seems to be a caching issue with Edge browser.

If a create a weatherforecast sample from the templates and paste the controller into the new project it works as excpeted.

The interesting thing is it works if I change the routes:

[HttpGet("/Test1")]
[HttpGet("/Test2")]
[HttpGet("/Test3")]

It doesn't work if I manually add the controller name (seems I have to use one path from the root):

[HttpGet("/Test/Test1")]
[HttpGet("/Test/Test2")]
[HttpGet("/Test/Test3")]

Anyone knows what I am missing why this makes a differene?


Solution

  • I tried your sample starting with a new API project. You miss to call app.MapControllers().

    The AddSwaggerGen is independent from the routing, so it found endpoints based on the controller, but this endpoints are not mapped if the MapControllers method is not called.

    If you try to call the endpoint from /swagger page you will also found the 404 error.

    This is the Program.cs that works on the test project:

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    builder.Services.AddControllers();
    
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    
    // app.UseHttpsRedirection();
    // app.UseAuthorization();
    app.MapControllers();
    // app.UseRouting(); // if you enable this line and disable the previous you got the 404 error
    app.UseSwagger();
    app.UseSwaggerUI();
    
    app.Run();
    

    From Routing in ASP.NET Core: "Apps typically don't need to call UseRouting or UseEndpoints".