Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition"
C#asp.net CoreSwaggerSwashbuckleC# Problem Overview
I develop an ASP.NET Core 2 application and included Swagger. Everything worked fine until I introduced a method without explicitly defining the HTTP action:
public class ErrorController : Controller
{
[Route("/error")]
public IActionResult Index()
{
return StatusCode(500, new Error("Internal error."));
}
}
When I started the app with this method, the following message showed up:
> Failed to load API definition.
>
> Errors
> Fetch error Internal Server Error /swagger/v1/swagger.json
As soon as I explicitly set e.g. [HttpGet]
the error disappears. The problem with this is, I need this method to fire for all possible HTTP operations.
Of course, I could specify all operations explicitly, but I have the feeling Swagger should be able to handle this correctly.
Why does Swagger behave this way?
Is there any configuration I can use?
C# Solutions
Solution 1 - C#
Add Httpxxx([HttpGet]
, [HttpPost]
, ...) attribute for each Action method, or [ApiExplorerSettings(IgnoreApi = true)]
Solution 2 - C#
Simply you can look into the log in the Output window. The actual error can be seen there in my case, I missed adding HTTP action on top of a methods
Solution 3 - C#
The option ResolveConflictingActions should be working on this case...
Here is the actual error:
System.NotSupportedException: Ambiguous HTTP method for action
That is coming from: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/86cc761bc4f5dda796f80ad8dfd8bc205542a6f6/src/Swashbuckle.AspNetCore.SwaggerGen/Generator/SwaggerGenerator.cs#L90
I think this is a bug, if you are truly interested you should report it to the project
Solution 4 - C#
Instead of blindy guessing what could be the issue, navigate to
http://
In my case this could have been resolved by using the c.CustomSchemaIds(x => x.FullName);
which is a horrible workaround, but might be a quick fix for someone in need. My solution was to rename and clarify the path for those endpoints
Solution 5 - C#
I don't know if this has been resolved or not but one way you can go about this is by decorating the method with:
[ApiExplorerSettings(IgnoreApi = true)]
This will ensure that the method in question is ignored by Swagger.
Solution 6 - C#
Another possible issue is that the endpoint needs to be complete from the domain root.
I had:
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "V1 Docs");
});
I had to use:
app.UseSwaggerUI(c=>
{
c.SwaggerEndpoint("/myApi/swagger/v1/swagger.json", "V1 Docs");
});
Solution 7 - C#
In ASP.NET Core, if there is a controller endpoint like:
[Route("images")]
[HttpGet("{id}")]
This can also fail with fetch failed. The solution is to have something like
[HttpGet("images/{id}")]
Same thing goes for HttpPost.
Solution 8 - C#
In addition to Helder Sepulvedas answer and from 'Monte-Christos' answer in this github issue - [Actions require unique method/path combination for Swagger][1] > I found the place to configure ResolveConflictingActions in ASP.NET > Core apps. In your Setup class, add this to the ConfigureServices() > method:
services.AddSwaggerGen(c =>
{
other configs...;
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});
This done the trick for me! [1]: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/390
Solution 9 - C#
Swagger also throws the same exception if there are public methods that are not actions in a controller. The fix is to make all of them protected
or private
or as mentioned add the attribute [ApiExplorerSettings(IgnoreApi = true)]
.
Solution 10 - C#
in my case i use this code as like as .net code
[ActionName("Login")]
[HttpPost]
now i change it for use on net core web api
[HttpPost("Login")]
And it works right
Solution 11 - C#
I was also getting this error because i created a controller which dosent have [Route("api/[controller]")]
. After putting it, the error went away.
app.UseSwagger()
.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "DOA.API V1");
});
Solution 12 - C#
What worked for me is adding [NonAction]
attribute to the public
methods that are not API calls in my controller wrapper.
Solution 13 - C#
I had the same issue. In my case, All of my controllers inherited from a BaseController. in this base class, I got a public action which returns UserId according to Claims. I set the [NonAction] attribute on the top of this action.
[ApiController]
[ApiResultFilter]
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class BaseController : ControllerBase
{
[NonAction]
public int GetCurrentUserId()
{
return int.Parse(this.User.Claims.First(p => p.Type == ClaimTypes.NameIdentifier).Value);
}
}
Solution 14 - C#
Double check , if you have used same url name in your same controller. It was happened to my code
Solution 15 - C#
I also had this problem. I checked and applied all of the solutions for swagger config but the issue still remained.
Finally, I checked the output panel and the problem was because of [DefaultValue("SYSDATETIMEOFFSET()")]
.
The answer is here: Check the output panel and you will find the answer
Solution 16 - C#
Guess what... started getting this error page "Failed to load API definition
":
By looking at the app's console or the output window in Visual Studio it told me the following:
I added a public method called Client to the Web API BaseController
and Swagger was thinking it should be included in the API.
To solve the problem: mark that method as protected:
Solution 17 - C#
I was getting a TypeLoadException
on a class that I was deleting that was unused. The fix in my case was to delete the bin/obj/Debug folder contents. Clean solution + rebuild solution did not fix for me.
Solution 18 - C#
My error reason was that same url name,
[HttpGet("get/LeaveCommand/{id}")]
I use same url and swagger cannot get them
[HttpGet("get/LeaveCommand/{id}")]
Solution 19 - C#
It happened because of Newtonsoft.Json in my case. But the thing is I was not using it. One of the packages may be depend on it but I did not have time to check.
So just check the output panenl solve the related issue.
Solution 20 - C#
If you have in your models (request or response) properties of type which inherits/implements types like System.ComponentModel
(or other types) this will throw an error
"The JSON property 'item' is defined multiple times on type"...
Try to ignore this property using [JsonIgnore]
attribute of Newtonsoft.Json
In my case i had a getter of type DataTable
Solution 21 - C#
In the Startup file you need to make sure that you add
services.AddSwaggerDocument();
before you add
app.UseOpenApi();
app.UseSwaggerUi3();
or it can result in this error
> Fetch error undefined /swagger/{documentName}/swagger.json
Solution 22 - C#
for core 3 I had the same issue and was really confused that problem was in slash.
Configuration was:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "my-API", Version = "v1" });
});
This swagger endpoint threw the message of TS:
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/v1/swagger.json", "my-API v1");
});
And finally I got it worked with removing the first slash in the URL:
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("v1/swagger.json", "my-API v1");
});
Solution 23 - C#
For me the problem was having registering swagger after MapControllers
middleware. Once I moved before it worked.
Solution 24 - C#
For me it was a very simple issue, i had 3 [HttpGet] methods which turned out i needed to change the "createOrder" method to a [HttpPost]
[HttpGet]
public async Task<ActionResult<List<Order>>> GetOrders()
{
return await _context.Orders.Include(o => o.OrderItems).Where(x => x.BuyerId == User.Identity.Name).ToListAsync();
}
[HttpGet("{id}", Name = "GetOrder")]
public async Task<ActionResult<Order>> GetOrder(int id)
{
return await _context.Orders.Include(x => x.OrderItems).Where(x => x.BuyerId == User.Identity.Name && x.Id == id).FirstOrDefaultAsync();
}
[HttpPost]
public async Task<ActionResult<int>> CreateOrder(CreateOrderDto orderDto)
{
var basket = await _context.Baskets.RetrieveBasketWithItems(User.Identity.Name).FirstOrDefaultAsync();
var items = new List<OrderItem>();
}
Solution 25 - C#
For me it was solved by adding the HttpGet attribute and removing the index methods.
Solution 26 - C#
The issue for me was caused by lazy/frustrated refactoring and I was able to determine the issue by reading the debug console when running the API in debugger mode.
Due to the bad refactoring, I ended up with two models with the same name, and Swagger was getting confused.
I had something like:
PROJECT
├───Auth
│ AutheController.cs
│ UserDto.cs
│
└───Controllers
│ MyContrller.cs
│
└───Models
UserDto.cs
Having two UserDto
models is what was confusing Swagger. Cleaning this up fixed the issues.