Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"dotnet swagger tofile" throws error in .net 8 with Swashbuckle v6.4 or 6.5 - says compatibility issue #2761

Closed
user-shashank-providence-org opened this issue Jan 29, 2024 · 17 comments

Comments

@user-shashank-providence-org
Copy link

I'm trying to generate swagger in postbuildevents, to do that I tried installing Swashbuckle CLI.
Project config:
dotnet --version: 8.0.101
Swashbuckle.Aspnetcore version: 6.4.0
Swashbuckle.Aspnetcore.Cli --> install fails saying:

Package 'Swashbuckle.AspNetCore.Cli 6.4.0' has a package type 'DotnetTool' that is not supported by project 'src\API'.
and
Package Swashbuckle.AspNetCore.Cli 6.4.0 is not compatible with net6.0 (.NETCoreApp,Version=v6.0). Package Swashbuckle.AspNetCore.Cli 6.4.0 supports:

  • net5.0 (.NETCoreApp,Version=v5.0) / any
  • net6.0 (.NETCoreApp,Version=v6.0) / any
  • netcoreapp2.1 (.NETCoreApp,Version=v2.1) / any
  • netcoreapp3.0 (.NETCoreApp,Version=v3.0) / any

Same issue popped when I updated the version to 6.5.0.

Also, if I don't do this via CMD and implement it in my csproj script like this:

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
	<Exec Command="dotnet tool restore"></Exec>
	<Exec Command="dotnet swagger tofile --output swagger_v1.json $(OutputPath)\$(AssemblyName).dll v1" />
</Target>

It throws this error [which is not helpful at all]:

MSB3073 The command "dotnet swagger tofile --output swagger_v1.json bin\Debug\net6.0\TestSwaggerGen.dll v1" exited with code 1.

And as per Nuget's website, I can see that Swashbuckle CLI supports .net 8 but why does it say while installing the nuget package that .net 8 is not supported?
image

@user-shashank-providence-org user-shashank-providence-org changed the title dotnet swagger tofile throws error in .net 8 with Swashbuckle v6.5 dotnet swagger tofile throws error in .net 8 with Swashbuckle v6.4 Jan 29, 2024
@user-shashank-providence-org user-shashank-providence-org changed the title dotnet swagger tofile throws error in .net 8 with Swashbuckle v6.4 dotnet swagger tofile throws error in .net 8 with Swashbuckle v6.4 or 6.5 Jan 29, 2024
@user-shashank-providence-org user-shashank-providence-org changed the title dotnet swagger tofile throws error in .net 8 with Swashbuckle v6.4 or 6.5 "dotnet swagger tofile" throws error in .net 8 with Swashbuckle v6.4 or 6.5 Jan 29, 2024
@user-shashank-providence-org user-shashank-providence-org changed the title "dotnet swagger tofile" throws error in .net 8 with Swashbuckle v6.4 or 6.5 "dotnet swagger tofile" throws error in .net 8 with Swashbuckle v6.4 or 6.5 - says compatibility issue Jan 29, 2024
@desjoerd
Copy link
Contributor

This is because the tool is compiled for .NET 7. You can fix it with DOTNET_ROLL_FORWARD=LatestMajor:

  <Target Name="openapi" AfterTargets="Build">
    <Message Text="generating openapi" Importance="high" />
    <Exec Command="dotnet tool run swagger tofile --yaml --output openapi.yaml $(OutputPath)$(AssemblyName).dll v1" EnvironmentVariables="DOTNET_ROLL_FORWARD=LatestMajor" />
  </Target>

Hope this helps!

@user-shashank-providence-org
Copy link
Author

This is because the tool is compiled for .NET 7. You can fix it with DOTNET_ROLL_FORWARD=LatestMajor:

  <Target Name="openapi" AfterTargets="Build">
    <Message Text="generating openapi" Importance="high" />
    <Exec Command="dotnet tool run swagger tofile --yaml --output openapi.yaml $(OutputPath)$(AssemblyName).dll v1" EnvironmentVariables="DOTNET_ROLL_FORWARD=LatestMajor" />
  </Target>

Hope this helps!

Hi @desjoerd, I've tried this approach already as discussed in this Github issue still it seems like swagger tofile keeps on looking for .Net version 7.0.0. Upon installing Swagger CLI from Nuget, it throws error saying it's not compatible with .Net 8/any.

Upon having a closer look at my output window (where I enabled debug mode in build properties), I noticed the following error response (entire stack trace):
1> Task "Exec"
1> Task Parameter:EnvironmentVariables=DOTNET_ROLL_FORWARD=LatestMajor
1> Task Parameter:Command=dotnet tool run swagger tofile --output swagger_patientv1.json bin\Debug\net8.0\X.API.dll patient
1> Environment Variables passed to tool:
1> DOTNET_ROLL_FORWARD=LatestMajor
1> dotnet tool run swagger tofile --output swagger_patientv1.json bin\Debug\net8.0\X.API.dll patient

1>    Unhandled exception. System.ArgumentException: Format of the initialization string does not conform to specification starting at index 0.
1>       at Microsoft.Data.Common.DbConnectionOptions.GetKeyValuePair(String connectionString, Int32 currentPosition, StringBuilder buffer, Boolean useOdbcRules, String& keyname, String& keyvalue)
1>       at Microsoft.Data.Common.DbConnectionOptions.ParseInternal(Dictionary`2 parsetable, String connectionString, Boolean buildChain, Dictionary`2 synonyms, Boolean firstKey)
1>       at Microsoft.Data.Common.DbConnectionOptions..ctor(String connectionString, Dictionary`2 synonyms)
1>       at Microsoft.Data.SqlClient.SqlConnectionString..ctor(String connectionString)
1>       at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous)
1>       at Microsoft.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions)
1>       at Microsoft.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key)
1>       at Microsoft.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
1>       at Microsoft.Data.SqlClient.SqlConnection..ctor(String connectionString)
1>       at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerConnection.CreateDbConnection()
1>       at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.get_DbConnection()
1>       at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
1>       at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.<>c__DisplayClass18_0.<Exists>b__0(DateTime giveUp)
1>       at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0`2.<Execute>b__0(DbContext _, TState s)
1>       at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
1>       at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation, Func`2 verifySucceeded)
1>       at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists(Boolean retryOnNotExists)
1>       at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists()
1>       at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
1>       at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
1>       at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade)
1>       at X.Modules.Patients.Infrastructure.Persistence.Extensions.ServiceCollectionExtensions.AddDatabaseContext(IServiceCollection services, IConfiguration config) in C:\S2\repo\X-API\src\Modules\Patients\X.Modules.Patients.Infrastructure\Persistence\Extensions\ServiceCollectionExtensions.cs:line 38
1>       at X.Modules.Patients.Infrastructure.Persistence.Extensions.ServiceCollectionExtensions.AddPersistentServices(IServiceCollection services, IConfiguration config) in C:\S2\repo\X-API\src\Modules\Patients\X.Modules.Patients.Infrastructure\Persistence\Extensions\ServiceCollectionExtensions.cs:line 15
1>       at X.Modules.Patients.Infrastructure.PatientsModuleStartup.AddPatientsModule(IServiceCollection services, IConfiguration configuration) in C:\S2\repo\X-API\src\Modules\Patients\X.Modules.Patients.Infrastructure\PatientsModuleStartup.cs:line 29
1>       at Program.<>c__DisplayClass0_0.<<Main>$>g__InitializeModules|1() in C:\S2\repo\X-API\src\API\X.API\Program.cs:line 72
1>       at Program.<>c__DisplayClass0_0.<<Main>$>g__ConfigureServices|0() in C:\S2\repo\X-API\src\API\X.API\Program.cs:line 66
1>       at Program.<Main>$(String[] args) in C:\S2\repo\X-API\src\API\X.API\Program.cs:line 17
1>       at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
1>       at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
1>    --- End of stack trace from previous location ---
1>       at Microsoft.Extensions.Hosting.HostFactoryResolver.HostingListener.CreateHost() in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\HostFactoryResolver.cs:line 271
1>       at Microsoft.Extensions.Hosting.HostFactoryResolver.<>c__DisplayClass8_0.<ResolveHostFactory>b__0(String[] args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\HostFactoryResolver.cs:line 75
1>       at Swashbuckle.AspNetCore.Cli.HostingApplication.GetServiceProvider(Assembly assembly) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\HostingApplication.cs:line 72
1>       at Swashbuckle.AspNetCore.Cli.Program.GetServiceProvider(Assembly startupAssembly) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\Program.cs:line 152
1>       at Swashbuckle.AspNetCore.Cli.Program.<>c.<Main>b__0_4(IDictionary`2 namedArgs) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\Program.cs:line 82
1>       at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable`1 args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 68
1>       at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable`1 args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 59
1>       at Swashbuckle.AspNetCore.Cli.Program.Main(String[] args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\Program.cs:line 121

1> C:\S2\repo\API\src\API\X.API\X.API.csproj(50,3): error MSB3073: The command "dotnet tool run swagger tofile --output swagger_patientv1.json bin\Debug\net8.0\X.API.dll patient" exited with code -532462766.

@user-shashank-providence-org
Copy link
Author

Hi @desjoerd,
I forked the Swashbuckle.Aspnetcore project and ran locally and found that this same exact error as mentioned above appears from ...Cli.HostFacoryResolver file. I tried adding support for .net8.0 in <TargetFramework> for this project and packing it, but as soon as I pack this custom-swashbuckle project, it runs into the above error.

@desjoerd
Copy link
Contributor

desjoerd commented Feb 1, 2024

It looks like you're running migrations in AddDbContext -> at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade)
This happens because the tool actually run's your startup/program.cs logic.

A way to workaround this is to set the dotnet environment to for example openapi or any name you want. And do an if check with builder.Environment.IsEnvironment("openapi").

You should also do this for any IHostedService you register (basically you skip registering it for openapi generation). This is because it actually starts up the app (including the hosted services).

@user-shashank-providence-org
Copy link
Author

It looks like you're running migrations in AddDbContext -> at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade) This happens because the tool actually run's your startup/program.cs logic.

Ohh... news to me. And here I thought that the tool used to pickup the SwaggerDoc files. Thanks for this info.

A way to workaround this is to set the dotnet environment to for example openapi or any name you want. And do an if check with builder.Environment.IsEnvironment("openapi").

You should also do this for any IHostedService you register (basically you skip registering it for openapi generation). This is because it actually starts up the app (including the hosted services).

Question:
If I add an exception to these services with "openapi" env settings, then this might throw an error during runtime (which it does) as it's unable to find those services.
I basically kept the ASPNETCORE_ENVIRONMENT value as Development in launch settings but added a new EnvironmentVariables in my target element saying: ASPNETCORE_ENVIRONMENT=openapi

For some weird reason it seems the command dotnet swagger tofile isn't replacing the env variables from appsettings.development.json, which in my prev experience with .net 6 did work fine. I say dotnet swagger tofile coz if I remove the <target> element from .csproj then the solution runs fine and opens up the swagger UI. I'm not sure whether this is a .net-8 issue or with swagger cli
Another reason why I say the above is:
I tried replacing all the appsettings variables from my appsettings.json with their original values and it worked fine.
Example: instead of "DbConnectionString": "#{DbConnectionString}#", I did something like: "DbConnectionString": "Data Source=....", and voila, it worked fine.

Any idea why the above would occur?

@haexyh
Copy link

haexyh commented Feb 6, 2024

Is a major release planned to fix this issue?

@user-shashank-providence-org
Copy link
Author

Is a major release planned to fix this issue?

The workaround suggested by @desjoerd worked for me.
I had to set the environment variables as mentioned above (DOTNET_ROLL_FORWARD=LatestMajor and ASPNETCORE_ENVIRONMENT=openapi) and then enclose all my services in an if condition to skip during post-build and only generate swagger file.
The issue still exists if we install Swagger CLI via nuget or in target command:
The fix to above I found is:
[Local Build]: I had to install CLI globally using CMD then run the swagger tofile command.
[On Server]: On my build pipeline, I added a task that installed CLI separately and another task to run the swagger tofile.

@BrettMillerDealX
Copy link

Confirming adding ENV DOTNET_ROLL_FORWARD=LatestMajor when running on docker mcr.microsoft.com/dotnet/sdk:8.0 worked for me.

@d4kine
Copy link

d4kine commented Feb 13, 2024

Is a major release planned to fix this issue?

@haexyh more like a minor release like for the .NET 7 issue: #2539

Got the same issue while compiling with Debian 12 and fixed it with the environment var.
I'd also appreciated a fix for this tho :)

@Havunen
Copy link

Havunen commented Feb 13, 2024

My fork has native support for .NET 8 as well as many fixes for it.
https://github.com/Havunen/DotSwashbuckle
https://www.nuget.org/packages/DotSwashbuckle.AspNetCore

@user-shashank-providence-org
Copy link
Author

I tried again today by deploying my new .net 8 app with swagger tofile target to an AKS cluster which only had .net 8 SDK installed and it threw the same error.

My fork has native support for .NET 8 as well as many fixes for it. https://github.com/Havunen/DotSwashbuckle https://www.nuget.org/packages/DotSwashbuckle.AspNetCore

Adding a task beforehand to install this package was helpful but only with version 3.0.0. For 3.0.3 it throws another exception.
Just an update: Installing above package with version number 3.0.0 works best.

@Havunen
Copy link

Havunen commented Feb 20, 2024

Just an update: Installing above package with version number 3.0.0 works best.

Can you report the exception you are seeing with the latest version here https://github.com/Havunen/DotSwashbuckle/issues please.

@AnderssonPeter
Copy link

It would be nice if a version was released that also targeted .net 8, currently my pipelines have to install both 7 and 8.

@Havunen
Copy link

Havunen commented Apr 12, 2024

DotSwashbuckle targets only .NET 8

@AnderssonPeter
Copy link

@Havunen sorry if I'm writing in the wrong github project, but the following is not built for .net 8 https://www.nuget.org/packages/Swashbuckle.AspNetCore.Cli/6.5.0#supportedframeworks-body-tab

@martincostello
Copy link
Collaborator

We will be adding net8.0 support in a forthcoming release.

@martincostello
Copy link
Collaborator

I'm going to close this in favour of #2792, as going through triaging the open issues I'm spotting a common theme and it's easier to manage one issue. Please track that issue for further updates.

If this issue isn't resolved once we have added support for net8.0, please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants