I am working on a POC with OData on AspNetCore
Microsoft.AspNetCore.OData
I am trying to add Swagger UI to document The API
I am working with this versions :
Swashbuckle.AspNetCore.Swagger 1.1
Swashbuckle.AspNetCore.SwaggerGen 1.1
Swashbuckle.AspNetCore.SwaggerGenUI 1.1
My problem is the ODataController is missing from the Swagger UI.
I have found some forum thread and the workaround was to add Annotations to the ODataController
[ApiExplorerSettings(IgnoreApi = false )]
If I do that the Api is not working since the routes are not defined .
has ApiExplorer enabled, but is using conventional routing. Only actions which use attribute routing support ApiExplorer.
so the only solution I have found to see the ODataController is to also add :
[Route("v1/api/[controller]")]
But if I do that I lose the Odata.context informations (in the json results) that are vital to give the total number of results without paging
"@odata.context": "http://localhost:29860/v1/api/$metadata#Products",
"@odata.count": 4,
What can I do to make swagger work with OdataController without loosing all Odata annotations on the results ?
Thank you by advance for your attention
+1
Maybe it makes sense to somehow utilize the work done over at Swashbuckle.OData
I think I have found some workaround on this:
.UseRouter(builder =>
{
builder.DefaultHandler = x.ApplicationServices.GetRequiredService<MvcRouteHandler>();
builder.MapODataServiceRoute(...);
})
.UseMvc()
This configuration places IRouter from OData before IRouter from Mvc.
Also I have TWO controllers - one that made all the job (derived from ODataController, invisible to swagger by default, routing through ODataRouteAttribute) and documentation-only controller (have same methods, throw NotImplementedException on all methods, annotated with attributes that made swagger generate proper documentation like RouteAttribute).
Because of routing configuration ODataController always will hit before documentation-only controller, so you have working OData and working documentation.
Thank you for your response.
I am really sorry but I have been fired by my client for budget reasons. I don't have the time to be able to test if your solution is working on my previous project.
This solution does´t work for me in AspNetCore Odata. Somebody go it?
I just hit the same issue myself and gave a cursory glance into how to get around it. I've got a minimal knowledge of how Swashbuckle does its thing, but it looks like it ultimately uses Microsoft's Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescriptionGroupCollectionProvider to gather the API endpoints (in Generator/SwaggerGenerator.cs, around line 38).
If that's the case, might the issue be that ApiDescriptionGroupCollectionProvider isn't properly gathering information related to OData endpoints?
I attempted to apply the workaround above but it had no effect in my project.
When I go to swagger I get this message "No operations defined in spec!" and when I added API Controller I get "Error Fetch" I need to use the swagger for my odata controllers, do you guys have any idea how can I solve this? Using .net core 2.1?
Same issue here. My regular Controllers show up in Swagger but not my OData controllers.
+1
+1
+1
+1
Although my answer may not be the relevant exactly to this question but i found a solution for using swagger along with OData in .NetCore. please folow https://stackoverflow.com/questions/54159987/swagger-json-paths-and-definitions-are-empty-no-operations-defined-in-spec/54167879#54167879
This is basically a duplication of #807. Since folks on this issue may not be following it, I'll repost my response. Hopefully, it will help one or more of you out.
The issue is that there is no API Explorer for OData - on Web API or ASP.NET Core. On both platforms, the default OData controller base class opts out of the API Explorer. It's possible to work around this, but it doesn't help because the default API Explorer implementations do not understand how to discover OData routes.
I see the crux of this issue being that OData simply does not have an API Explorer. That is independent of, and should be external to, Swashbuckle or any other Swagger generator. If the OData team or anyone else (like API Versioning) provided API Explorer extensions, the consumer libraries like Swashbuckle _just work_. The idea that a Swagger library such as Swashbuckle should provide this support is the wrong approach IMHO. There have been previous attempts to do this in the past. Swashbuckle already does everything required, regardless of whether you're using OData, as long as it's provided in the API Explorer.
If you don't need or want versioning, but you still want Swagger support, then the next best option might be to use the ODataSwaggerConverter provided by the OData team. It's not nearly as comprehensive as what a fully-fledged Swagger library like Swashbuckle provides, but it _might_ get you what you need. At a minimum, it might provide an initial implementation to work from. There are also libraries and other tools that transform the EDM (a la XML) to Swagger (in JSON). This may be a workable solution as well.
As long as you generate compliant Swagger documents in a manner addressable by the Swashbuckle Swagger UI, things _should_ work end-to-end.
I hope that helps.
This might help some people?
https://github.com/Microsoft/aspnet-api-versioning/tree/master/samples/aspnetcore/SwaggerODataSample
Actually it is worse - OData does not play nicely with routing in dotnetcore. If they EVER get around doing any work on dotnetcore 3.0 compatibility with the endpoint routing, they hopefully manage to work out their coding issues. Not that any work seems to happen there (last checkin: about a MONTH (!) ago at this moment, last pull request... closed 29 days ago.
+1
I keep waiting for a possible solution of this error, please @domaindrivendev can you tell me when we will have this solution ?
Swashbuckle is built on top of ApiExplorer, the metadata layer that ships with ASP.NET Core. As that DOES NOT support ODataControllers, Swashbuckle would have to generate the descriptions independently of ApiExplorer. This would take a long time and would add significant complexity to the codebase. It’s also pretty far down on the list of priorities.
To be frank, you’d be better off taking a stab at it yourself. You know ... we are talking about “free” open source software here!
If you’re interested, I would suggest a new project called Swashbuckle.AspNetCore.OData. In it you could create an implementation of ISwaggerProvider - this way you could still plug into the Swashbuckle ecosystem.
@domaindrivendev is correct; this isn't a Swashbuckle or even a Swagger problem - it's an OData problem. Solutions should be directed to the OData team on their repo.
Depending on your needs, there are at least 4 solutions out there:
@xuzhg can you help with this ?
@domaindrivendev is correct; this isn't a Swashbuckle or even a Swagger problem - it's an OData problem. Solutions should be directed to the OData team on their repo.
Depending on your needs, there are at least 4 solutions out there:
The ODataSwaggerConverter provided by the OData team
- There isn't much to the implementation so you should be able to customize it as needed
- This can be combined with a custom ISwaggerProvider
Can you provide how and where to use the ODataSwaggerConverter? Didn't find anything yet.
@guispre, I would start by simply reviewing the tests in ODataSwaggerConverterTest.cs.
Does anyone found a workaround for this?
Hi Guys, I had similar question, I am able to produce the ODataControllers in the SwaggerUI just fine after applying the solutions here, :) but when I try to produce the same swagger.json file through
dotnet swagger tofile --output $path_to_swagger_json --serializeasv2 $PATH_TO_ASSEMBLY $version_name
I don't see the ODataController paths here.
Any idea on how to tell the command-line swagger to generate the same swagger like generated by Startup.cs?
I managed to make Swagger compatible with ODataController by following the code in this repository. I had only to change SetOutputFormatters in Startup.cs in this way:
```
private static void SetOutputFormatters(IServiceCollection services)
{
services.AddMvcCore(options =>
{
IEnumerable
options.OutputFormatters.OfType
.Where(formatter => formatter.SupportedMediaTypes.Count == 0);
IEnumerable<ODataInputFormatter> inputFormatters =
options.InputFormatters.OfType<ODataInputFormatter>()
.Where(formatter => formatter.SupportedMediaTypes.Count == 0);
foreach (var outputFormatter in outputFormatters)
{
outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/odata"));
outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
foreach (var inputFormatter in inputFormatters)
{
inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/odata"));
inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
});
}
```
@hassanhabib @xuzhg this should be resolved now with AspNetCore/OData 7.4.1 right?
Swashbuckle is built on top of ApiExplorer, an API metadata provider that's part of ASP.NET Core. Unfortuntely the out-of-the-box implementation of ApiExplorer does not support OData controllers, hence why they're not documentend by Swashbuckle.
However, I believe the Microsoft.AspNetCore.Mvc.Versioning provides an implementation of ApiExplorer that _does_ support OData controllers and that is the recommended approach at this point in time. Here's the quickstart from that repo for ASP.NET Core with OData:
https://github.com/microsoft/aspnet-api-versioning/wiki/API-Documentation#aspnet-core-with-odata
Most helpful comment
Same issue here. My regular Controllers show up in Swagger but not my OData controllers.