Swashbuckle.AspNetCore: Swagger file generated in cli missing paths, components (Swashbuckle.AspNetCore.Cli 5.1.0)

During the build process we are trying to generate the swagger.json file. We are using the following command:

dotnet swagger tofile .\bin\Debug\netcoreapp3.1\myWebService.dll v1

The output that gets generated:

{
  "openapi": "3.0.1",
  "info": {
    "title": "myWebService",
    "description": "myWebService",
    "contact": {
      "name": "John Doe",
      "email": "john.doe@example.com"
    },
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    },
    "version": "1.0"
  },
  "paths": { },
  "components": { }
}

As you can see, the paths and components are empty. There are no errors or warnings shown from the CLI tool.

However, if we take the swagger.json from the service (http://localhost:57016/swagger/v1/swagger.json), it includes all the relevant paths and components. image

Can you please clarify how can we achieve the same output in CLI as from the web service?

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 9
  • Comments: 15 (4 by maintainers)

Most upvoted comments

Hello,

I’m not sure if it will help, but let’s give it a try.

I had a similar problem, but with custom SwaggerHostFactory.CreateHost. The dotnet swagger tofile (...) returned incomplete swagger definition:

{                                                                                     
  "openapi": "3.0.1",                                                                 
  "info": {                                                                           
    "title": "(...)",                                         
    "version": "v1"                                                                   
  },                                                                                  
  "paths": { },                                                                       
  "components": {                                                                     
    "securitySchemes": {                                                              
      "Bearer": {                                                                     
        "type": "http",                                                               
        "description": "Bearer token for the API to authenticate incoming requests.", 
        "scheme": "bearer"                                                            
      }                                                                               
    }                                                                                 
  },                                                                                  
  "security": [                                                                       
    {                                                                                 
      "Bearer": [ ]                                                                   
    }                                                                                 
  ]                                                                                   
}

Everything worked just fine:

  • when I’ve accessed swagger-ui page
  • when I’ve manually called SwaggerHostFactory.CreateHost during application startup:
(...)
var host = SwaggerHostFactory.CreateHost();
var swaggerProvider = host.Services.GetRequiredService<ISwaggerProvider>();
(...)

To resolve this issue I had to set a value for application name, so finally my SwaggerHostFactory.CreateHost looks like that:

/// <summary>
/// Custom <see cref="IHost"/> factory used for API client generation.
/// </summary>
public class SwaggerHostFactory
{
    public static IHost CreateHost()
    {
        var builder = WebApplication.CreateBuilder(new WebApplicationOptions
        {
            ApplicationName = typeof(SwaggerHostFactory).Namespace // without it, actions won't be added to swagger file
        });

        builder.Services.AddControllers();
        builder.Services.AddEndpointsApiExplorer();
        
        builder.Services.AddSynergySwaggerGen(options =>
        {
            options.SwaggerDoc("v1", new() { Title = "...", Version = "v1" });
            (...)
        });
            
        var app = builder.Build();
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint(...);
            (...)
        });
        app.MapControllers();

        return app;
    }
}

Problem might be related to Microsoft.Extensions.DependencyInjection.MvcCoreServiceCollectionExtensions.GetApplicationPartManager which initializes Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager and calls void PopulateDefaultParts(string entryAssemblyName), where entryAssemblyName is set to environment?.ApplicationName. It is called only for not empty, or null values.

private static ApplicationPartManager GetApplicationPartManager(IServiceCollection services, IWebHostEnvironment? environment)
{
    var manager = GetServiceFromCollection<ApplicationPartManager>(services);
    if (manager == null)
    {
        manager = new ApplicationPartManager();

        var entryAssemblyName = environment?.ApplicationName;
        if (string.IsNullOrEmpty(entryAssemblyName))
        {
            return manager;
        }

        manager.PopulateDefaultParts(entryAssemblyName);
    }

    return manager;
}

Why do I think so?

var partManager = app.Services.GetRequiredService<ApplicationPartManager>();
var feature = new ControllerFeature();
partManager.PopulateFeature(feature);

During normal runtime, feature.Controllers has records for each controller from my project, and during dotnet swagger tofile (...) it is empty,

Cheers,

I ran across this when using Swashbuckle.AspNetCore.Cli v6.4.0, in a net7.0 API project. When using var builder = WebApplication.CreateBuilder();, this results in the following empty Open API document.

{
  "openapi": "3.0.1",
  "info": {
    "title": "My API",
    "version": "V1"
  },
  "paths": { },
  "components": { }
}

But to resolve this, simply pass args to the CreateBuilder method. I found that this results in a fully built Open API file.

var builder = WebApplication.CreateBuilder(args);

I am having the same issue. Any work-arounds for this?