Swashbuckle/Swagger + Asp. Net Core: "Failed to Load Api Definition"
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...
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?
26 Answers
Add Httpxxx([HttpGet], [HttpPost], ...) attribute for each Action method, or [ApiExplorerSettings(IgnoreApi = true)]
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
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:
I think this is a bug, if you are truly interested you should report it to the project
Instead of blindy guessing what could be the issue, navigate to
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
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.
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");
});
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.
In addition to Helder Sepulvedas answer and from 'Monte-Christos' answer in this github issue - Actions require unique method/path combination for Swagger
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!
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)].
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
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");
});
What worked for me is adding [NonAction] attribute to the public methods that are not API calls in my controller wrapper.
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);
}
}
Double check , if you have used same url name in your same controller. It was happened to my code
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
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:
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.
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}")]
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.
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
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
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");
});
For me the problem was having registering swagger after MapControllers middleware. Once I moved before it worked.
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>();
}
For me it was solved by adding the HttpGet attribute and removing the index methods.
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.