Swashbuckle.AspNetCore
Swashbuckle.AspNetCore copied to clipboard
Swashbuckle CLI does not work with the new Minimal Hosting Model in .NET 6
Swashbuckle CLI seems to skip the Program.cs file and look directly at the Startup.cs file to generate the swagger doc. However, the minimal hosting model gets rid of the Startup.cs file in favor of a single Program.cs file to register services. Because of this, I am getting errors when running "dotnet swagger tofile" command.
My use case involves pulling app settings from a key vault when the app starts. Because Swashbuckle CLI isn't aware of environment variables (which don't even exist in devops pipelines), I get the below error:
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'vault')
I noticed there is a feature request to stop running the app when the "dotnet swagger tofile" command is run here: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/2181 This feature seems a lot more important now that Microsoft has introduced this new pattern.
For anyone else who is experiencing this problem, the work around is to continue using a Startup class as described here: https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60?view=aspnetcore-6.0&tabs=visual-studio#use-startup-with-the-new-minimal-hosting-model
Is this planned to get fixed?
current CI/CD file generated by azure gives the same error.
Hi, Is the issue resolved? I am facing exactly the same issue. Please help !!!
Same issue with .NET 8...
+1 Also just encountered
Same here with .NET 8 Minimal API
I'm seeing this in a .NET6 Api with Program.cs
clas
Same here with .NET 8 Minimal API
Was this fixed ? Also .NET 8 Minimal API
Just tested, still broken.
@brennfoster you can specify environment variable yourself.
<Target Name="SwaggerToFile" AfterTargets="AfterBuild"> <Exec Condition="$(CI) != true" Command="dotnet swagger tofile --host http://example.com --output ../../../frontend/cv-ui/libs/api/src/lib/v1.json $(OutputPath)$(AssemblyName).dll v1" EnvironmentVariables="ASPNETCORE_ENVIRONMENT=Development;DOTNET_ROLL_FORWARD=LatestMajor" /> </Target>
I have working minimal API without old startup.ca
Another workaround:
The class SwaggerRunDetector
trys to detect if the swagger tool is running the app. If so I do not execute code segments which should not run when generating the specification e.g. connect to a DB. The instance can be retreived from DI to do checks:
if (app.Services.GetRequiredService<SwaggerRunDetector>().IsSwaggerToolRun())
{
// e.g. return from function or do not start service
}
using System.Reflection;
namespace TheNamespace.Util.WebApi.OpenApi;
/// <summary>
/// Detects if the current app run is triggered by swagger tool.
/// Swagger tool to generate OpenApi spec will run the application in the new hosting model
/// since it needs the DI container.
/// Starting the app or sub processes my not be possible e.g. during CI/CD.
/// see https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/2290
/// </summary>
public class SwaggerRunDetector
{
private readonly ILogger logger;
public SwaggerRunDetector(ILogger<SwaggerRunDetector> logger)
{
this.logger = logger;
}
/// <summary>
/// Detect if current app run is triggered by swagger
/// </summary>
/// <returns>True if the current execution is a swagger generation run.</returns>
public bool IsSwaggerToolRun()
{
logger.LogTrace("Detecting swagger run: GetEntryAssembly: {entryAssembly}", Assembly.GetEntryAssembly()!.FullName);
var entryAssembly = Assembly.GetEntryAssembly()?.FullName;
var isSwaggerRun = !string.IsNullOrWhiteSpace(entryAssembly) && entryAssembly.Contains("swagger", StringComparison.InvariantCultureIgnoreCase);
logger.LogTrace("Swagger run: {isSwaggerRun}", isSwaggerRun);
return isSwaggerRun;
}
}
For completeness the build target to generate the openapi.json:
<Target Name="OpenAPI" DependsOnTargets="Build">
<Exec Command="swagger tofile --output ./openapi.json $(OutputPath)$(AssemblyName).dll v1" WorkingDirectory="$(ProjectDir)" />
</Target>
It has its own problems, e.g. polluting the code with swagger specific conditions and it uses (slow?) reflection. But maybe it still helps someone.
Same issue with .NET 8...
I don't understand if this is fixed or why this issue is still open. But I am surprised some people are finding this problem with .NET 8. I created a few samples for .NET 8 https://github.com/diegosasw/sample-open-api
and a CI/CD GitHub Actions pipeline (can be tested locally, of course)
- name: Generate Swagger for WebApiOne
run: dotnet swagger tofile --output temp/web-api-one.json src/WebApiOne/bin/Release/net8.0/WebApiOne.dll web-api-one
- name: Generate Swagger for WebApiTwo
run: dotnet swagger tofile --output temp/web-api-two.json src/WebApiTwo/bin/Release/net8.0/WebApiTwo.dll web-api-two
and it's generating the open api json properly despite using minimal API and having Program.cs
but not Startup.cs
Am I missing something?
PS: I'm using this dotnet tool
{
"version": 1,
"isRoot": true,
"tools": {
"swashbuckle.aspnetcore.cli": {
"version": "6.6.2",
"commands": [
"swagger"
],
"rollForward": false
}
}
}
@diegosasw Your sample projects don't appear to be pulling any values from environment variables or configuration so they won't encounter the issue. I believe that this issue is the same (or very similar) to another that I have posted a bare-bones repro in if you're interested in seeing the error: https://github.com/dotnet/aspnetcore/issues/45025#issuecomment-2161711924