WebApi Core / Swagger: "failed to load API definition" error

December 16, 2020
Cover Image

I was working with some ASP.NET WebApi code and needed to test something using the Swagger UI. Usually, it's just a matter of starting the project and going to your /swagger directory. Unfortunately, in this case, I went to my swagger URL and got an error saying "Failed to load API definition -- Fetch error -- Internal Server Error /swagger/v1/swagger.json." How do you fix this error?

The Swagger UI error

I knew that it used to work but I'd just updated about a half zillion things in my code including upgrading to .NET Core 5 so I wasn't really sure what broke it. I assumed the worst.

The dev tools in Edge was showing me that it was trying to access swagger.json but it was getting an HTTP 500 error. My guess was that I had a configuration problem in Startup.cs and that the swagger.json file either wasn't being generated or it was in the wrong place. I checked a bunch of stuff and didn't find anything.

The call to get swagger.json returns HTTP 500

The call to get swagger.json was returning HTTP 500

I eventually started to figure out what was going wrong when I opened that call to swagger.json in its own tab.

The error message on that HTTP 500 to swagger.json

The actual error message says that there's an "ambiguous HTTP method for action". I wasn't really sure what that meant by helpfully the error message pointed me at the WebApi endpoint action that was causing the problem. Rather than being a problem with some kind of swagger config, the error was coming from the code that I'd just been working on.

Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Ambiguous HTTP method for action - SwaggerError.WebApi.Controllers.WeatherForecastController.Overview (SwaggerError.WebApi). Actions require an explicit HttpMethod binding for Swagger/OpenAPI 3.0
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GenerateOperations(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GeneratePaths(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
   at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwagger(String documentName, String host, String basePath)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Here's the code that's causing the problem:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [Route("/[controller]/[action]/{id}")]
    public ActionResult Overview(int? id)
    {
        return Ok(id);
    }
}

Looks pretty ordinary, right? Nothing to exciting here. So what's broken? What's "ambiguous" about this? It's missing the HttpGet attribute.

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    [Route("/[controller]/[action]/{id}")]
    public ActionResult Overview(int? id)
    {
        return Ok(id);
    }
}

As soon as I added that missing [HttpGet] attribute, the Swagger UI was working again.

Summary

In short, the problem was a problem in my code. I'd assumed that my WebApi controller action would default to HTTP GET but it seems that that doesn't agree with Swagger. As soon as I added that missing attribute, everything was fine.

I hope this helps.

-Ben

-- Looking for help on your .NET Core projects? Want some guidance on how to get going with Azure DevOps or GitHub Actions? Need a Scrum coach to help your teams get over a delivery slump? We can help. Drop us a line at info@benday.com.