Swashbuckle.AspNetCore: ODataController controllers missing from swagger UI

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

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 16
  • Comments: 30 (2 by maintainers)

Most upvoted comments

Same issue here. My regular Controllers show up in Swagger but not my OData controllers.

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<ODataOutputFormatter> outputFormatters =
                   options.OutputFormatters.OfType<ODataOutputFormatter>()
                       .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"));
              
               }

           });
       }

@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
  • Use an EDMX-to-OpenAPI transformer (like this one)
    • This is just one example, but there are others out there if you search around
    • This can be combined with a custom ISwaggerProvider
  • Use Swashbuckle.AspNetCore.OData, which works well for basic scenarios
    • I do not recommend this project if you’re using versioning; they impose their own semantics
    • This library is not compatible with API Versioning
  • If you need/want versioning with OData, API Versioning provides an API Explorer that Swagger generators like Swashbuckle are capable of consuming

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?

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.

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.

Maybe it makes sense to somehow utilize the work done over at Swashbuckle.OData

@guispre, I would start by simply reviewing the tests in ODataSwaggerConverterTest.cs.