Closed somanysteves closed 4 years ago
I'm seeing this issue as well when I tried using the 5.0 CLI tool downloaded from nuget.
I tried building the tool locally to debug, then I got a similar-but-different error:
$ swagger.exe tofile --output test.json "C:\Users\rleonar7\dev\UO.CAS.PSY.Duckling\UO.CAS.PSY.Duckling\bin\Release\netcoreapp2.2\UO.CAS.PSY.Duckling.dll" 1.0.0
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'Microsoft.AspNetCore.Hosting.Abstractions, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
at Swashbuckle.AspNetCore.Cli.Program.<>c.<Main>b__0_3(IDictionary`2 namedArgs)
at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable`1 args) in C:\Users\rleonar7\dev\Swashbuckle.AspNetCore\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 68
at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable`1 args) in C:\Users\rleonar7\dev\Swashbuckle.AspNetCore\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 59
at Swashbuckle.AspNetCore.Cli.Program.Main(String[] args) in C:\Users\rleonar7\dev\Swashbuckle.AspNetCore\src\Swashbuckle.AspNetCore.Cli\Program.cs:line 106
I've been battling with this issue myself. It appears to occur when you have dotnet 3.0 installed on your system, and you're trying to extract Open API specs out of a Startup Assembly that targets dotnet 2.*.
I assume when you invoke the swagger cli tool it's using dotnet 3.0 to host the tool, but then it has to load a dotnet 2.* startup assembly to extract the specs, and somewhere in this process it encounters assembly loading issues because of it.
That's an interesting theory. I'm planning to run this tool in Azure DevOps: I'll give it a shot and see if the tool works in the more 'vanilla' environment provided by the DevOps Agent (as opposed to my local development machine).
UPDATE: Running this in Azure DevOps still kicked-back the same exception that we were originally seeing:
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Runtime.Loader, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
at Swashbuckle.AspNetCore.Cli.Program.<>c.<Main>b__0_3(IDictionary`2 namedArgs)
at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable`1 args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 68
at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable`1 args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 68
at Swashbuckle.AspNetCore.Cli.Program.Main(String[] args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\Program.cs:line 106
I'm unsure... the Azure DevOps "vs2017 Hosted Agent" environment I am using might still have a 3.x verion(s) of the dotnet SDK installed.
I am trying to use Swashbuckle.AspNetCore.Cli --version 5.3.1
to generate the swagger document for a netcoreapp2.2
project and encounter this error. I did some quick triage and deleted system.runtime.loader
from my user's .nuget
folder then did dotnet restore
in the directory with the tool installed. Afterwards system.runtime.loader
but it contained version 4.0.0
rather than the expected 4.1.0
. I expect there is a discrepancy in the version of system.runtime.loader
in the csproj of the CLI source code and what is listed on the nuspec manifest but haven't confirmed that hypothesis.
EDIT: I confirmed that the .csproj
for Swashbuckle.AspNetCore.Cli
does reference System.Runtime.Loader
v4.3.0
It's also entirely possible that MS has diverged the assembly version and the nuget package version such that the error message for 4.1.0.0
is actually indicating that 4.3.0
is missing as there is no publically available 4.1.0 version of the package, only 4.0.0 and 4.3.0.
We see that issue occurs only with binaries created for CLI with target = netcoreapp3.0 Why do we need both? Tool is created with one version only. When I'm trying to run CLI with target = netcoreapp2.1 everything is fine.
Also, just to note, we cannot call this CLI as mentioned in readme, eg dotnet swagger, because this syntax requires command to be dotnet-swagger, not swagger.
If the command begins with the prefix dotnet-, an alternative way to invoke the tool is to use the dotnet command and omit the tool command prefix. For example, if the command is dotnet-doc, the following command invokes the tool:
I've been able to run the CLI tool successfully for applications targeting netcoreapp2.1
, netcoreapp3.0
and netcoreapp3.1
. So, if there's an issue here, the repro steps are more nuanced than running against a certain application target.
Could someone on this thread please put together a minimal application that repro's the issue and then post it to github where I can pull it down and investigate further. Without this, I won't be able help.
@domaindrivendev here is it https://github.com/Lonli-Lokli/SwaggerCLI
Please note that I have only 1 SDK installed, 3.1. It might be the reason why you do not see this error.
I just built up a simple example application using asp.net core 3.1 and did not see the issue.
I'm going to reproduce the issue in my original project and see if I can extract a simplified example. The original project targets framework netcoreapp2.2
@domaindrivendev Were you able to reproduce the issue?
Yes was able to repro. However, I don’t have bandwidth right now to explore a solution. Assistance in this area would be very helpful
I have the same issue right now. Using 5.3.1 Swashbuckle.AspNetCore.Cli, project targets netcoreapp2.2, getting:
0>Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Runtime.Loader, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
0> at Swashbuckle.AspNetCore.Cli.Program.<>c.<Main>b__0_3(IDictionary`2 namedArgs)
0> at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable`1 args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 68
0> at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable`1 args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 68
0> at Swashbuckle.AspNetCore.Cli.Program.Main(String[] args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\Program.cs:line 107
@domaindrivendev Why do we need 2 targets for this CLI, netcoreapp2.1 and netcoreapp3.1 ? This issue happens only with 3.1 version, which is actually packed as .NET CLI tool.
@domaindrivendev may I kindly ask you how to reproduce this issue locally with code build from this cloned repo and not from installed global tool? I would like to play with possible options.
Eg
I've also came accross this problem and created a minimal working example which can be used for reproducing the issue: https://github.com/nattomi/SwaggerCliFailMwe.
@domaindrivendev may I kindly ask you how to reproduce this issue locally with code build from this cloned repo and not from installed global tool? I would like to play with possible options.
As I've realized this is a more braodly impacting problem than I first thought, I've moved it up the list of priorities and have started to investigate further. @Lonli-Lokli - I'm still looking for a way to repro against source, will let you know what I come up with
@Lonli-Lokli to repro from source:
> git clone git@github.com:domaindrivendev/Swashbuckle.AspNetCore.git
> cd Swashbuckle.AspNetCore
> dotnet build
> cd test\WebSites\NetCore21
Simulate running via 2.1 SDK - works fine ...
> dotnet ..\..\..\src\Swashbuckle.AspNetCore.Cli\bin\Debug\netcoreapp2.1\dotnet-swagger.dll tofile .\bin\Debug\netcoreapp2.1\NetCore21.dll v1
Simulate running via 3.x SDK - fails ...
> dotnet ..\..\..\src\Swashbuckle.AspNetCore.Cli\bin\Debug\netcoreapp3.0\dotnet-swagger.dll tofile .\bin\Debug\netcoreapp2.1\NetCore21.dll v1
@Lonli-Lokli going back to a point you made further back up the thread - it seems I could have the CLI project target netcoreapp2.1
only and that would be enough to support all combinations of SDK and application framework versions. Doing more tests now to confirm:
@domaindrivendev Why do we need 2 targets for this CLI, netcoreapp2.1 and netcoreapp3.1 ? This issue happens only with 3.1 version, which is actually packed as .NET CLI tool.
@domaindrivendev the only thing that I see might be broken with single targetframework is possibility to install it as a local tool. Btw I've checked with DotPeek swagger cli for the netcore3 and it appears it referencing some of netcore2.1 libs, not sure why, mb because of referenced project.
@Lonli-Lokli I tested the local tool installation with the single target and it appears to work just fine. I have a preview package 5.4.0-preview-1253
sitting up on myget.org. If you get a chance, could you try uninstalling your current version of the tool and installing the preview instead, and letting me know if that works?
@domaindrivendev, I've tested my mwe with 5.4.0-preview-1253 and the Cli tool now works on the project targeting netcoreapp2.2 as well. See updated version: https://github.com/nattomi/SwaggerCliFailMwe Will test and see if it works on my real project too.
Stupid question (maybe): How to I upgrade to 5.4.0-preview-1253? This version is not on NuGet, is it?
I have updated the version in my dotnet-tools.json
and in my *.csproj
.
dotnet tool restore
error NU1102: Das Paket "swashbuckle.aspnetcore.cli" der Version (= 5.4.0-preview-1253) wurde nicht gefunden.
error NU1102: - 23 Version(en) gefunden in "nuget.org" [ Nächste Version: 5.3.3 ]
error NU1102: - 0 Version(en) gefunden in C:\Program Files\dotnet\sdk\NuGetFallbackFolder.
Das Paket "swashbuckle.aspnetcore.cli" konnte nicht wiederhergestellt werden. Ursache: Microsoft.DotNet.ToolPackage.ToolPackageException: Das Toolpaket konnte nicht wiederhergestellt werden.
at Microsoft.DotNet.Tools.Tool.Install.ProjectRestorer.Restore(FilePath project, PackageLocation packageLocation, String verbosity)
at Microsoft.DotNet.ToolPackage.ToolPackageInstaller.InstallPackageToExternalManagedLocation(PackageLocation packageLocation, PackageId packageId, VersionRange versionRange, String targetFramework, String verbosity)
at Microsoft.DotNet.Tools.Tool.Restore.ToolRestoreCommand.InstallPackages(ToolManifestPackage package, Nullable`1 configFile)
Fehler bei der Wiederherstellung.
Sorry for German output. 😅
@riker09 Add a nuget.config file like this: `<?xml version="1.0" encoding="utf-8"?>
`
Okay, I was able to add the NuGet package with this command: dotnet nuget add source --name domaindriverdev https://www.myget.org/F/domaindrivendev/api/v3/index.json
I removed ./bin
and ./obj
afterwards, then ran dotnet restore MyProject.csproj
and dotnet build MyProject.csproj
. The error described in this issue went away, however I'm facing a new one:
PS C:\Users\MyUserName\Projects\MyRepo\MyService> dotnet swagger tofile --output swagger.json .\bin\Debug\netcoreapp2.2\MyService.dll v1
Unhandled Exception: StructureMap.Building.StructureMapBuildException: Error while building type Swashbuckle.AspNetCore.SwaggerGen.ConfigureSwaggerGeneratorOptions. See the inner exception for details
1.) new ConfigureSwaggerGeneratorOptions(*Default of IOptions<SwaggerGenOptions>*, *Default of IServiceProvider*, *Default of IHostingEnvironment*)
2.) Swashbuckle.AspNetCore.SwaggerGen.ConfigureSwaggerGeneratorOptions
3.) Instance of IConfigureOptions<SwaggerGeneratorOptions> (Swashbuckle.AspNetCore.SwaggerGen.ConfigureSwaggerGeneratorOptions)
4.) All registered children for IEnumerable<IConfigureOptions<SwaggerGeneratorOptions>>
5.) Instance of IEnumerable<IConfigureOptions<SwaggerGeneratorOptions>>
6.) new OptionsFactory`1(*Default of IEnumerable<IConfigureOptions<SwaggerGeneratorOptions>>*, *Default of IEnumerable<IPostConfigureOptions<SwaggerGeneratorOptions>>*, *Default of IEnumerable<IValidateOptions<SwaggerGeneratorOptions>>*)
7.) OptionsFactory<SwaggerGeneratorOptions> ('48905920-c9cd-4ae8-ace8-eaeebb281f4f')
8.) Instance of IOptionsFactory<SwaggerGeneratorOptions> ('48905920-c9cd-4ae8-ace8-eaeebb281f4f')
9.) new OptionsManager`1(*Default of IOptionsFactory<SwaggerGeneratorOptions>*)
10.) OptionsManager<SwaggerGeneratorOptions> ('991c1d92-470e-4242-8e09-20152b229dd7')
11.) Instance of IOptions<SwaggerGeneratorOptions> ('991c1d92-470e-4242-8e09-20152b229dd7')
12.) Container.GetInstance(IOptions<SwaggerGeneratorOptions>)
13.) Lambda: Invoke(value(StructureMap.ContainerExtensions+<>c__DisplayClass9_0).descriptor.ImplementationFactory, IContext.GetInstance())
14.) Instance of Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorOptions (System.Object)
15.) new SwaggerGenerator(*Default of SwaggerGeneratorOptions*, *Default of IApiDescriptionGroupCollectionProvider*, *Default of ISchemaGenerator*)
16.) Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator
17.) Instance of Swashbuckle.AspNetCore.Swagger.ISwaggerProvider (Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator)
18.) Container.GetInstance(Swashbuckle.AspNetCore.Swagger.ISwaggerProvider)
---> System.IO.FileNotFoundException: Could not find file 'C:\Users\MyUserName\Projects\MyRepo\MyService\bin\Debug\netcoreapp2.2\dotnet-swagger.xml'.
The file dotnet-swagger.xml
does indeed not exist. My guess is that it should be MyService.xml
instead?
Full disclosure: I'm a noob regarding dotnet tooling and C# development in general. So please forgive me when I'm doing any mistakes that should be obvious. 😅
[EDIT] There is another issue regarding this: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1518, however it was closed due to no proper steps for reproduction. Well, here we are.
@riker09 could you create a minimal application that repro's your issue and post to github so I can pull down and troubleshoot? That's been the most efficient approach for getting to the bottom of these obscure issues.
That said - have you configured SB to use Xml comments? If so, I wonder if there's something wrong with the way your detecting the XML comments file name. If you could provide a snippet of your SB configuration we could rule that out first?
Okay, Swashbuckle Startup configuration first. I'll provide a repo with a minimal reproduction app afterwards.
ConfigureServices
method:
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
var title = Assembly.GetEntryAssembly().GetName().Name;
c.SwaggerDoc("v1", new OpenApiInfo { Title = title, Version = "v1" });
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{title}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});
and in Configure
method:
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
});
Okay, I have found my mistake. I'm developing a microservice architectured application and moved the Swagger boilerplate code to a support project which is then included in the API projects. Everything is a monorepo.
Like I said, I'm no C# expert and things like Assembly.GetExecutingAssembly().GetName().Name
or GetEntryAssembly()
don't play together nicely with that. This was my extension method before:
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Microsoft.Extensions.DependencyInjection
{
public static partial class ServiceCollectionExtensions
{
public static IServiceCollection AddDmforce4SwaggerSupport(this IServiceCollection @this)
{
// Register the Swagger generator, defining 1 or more Swagger documents
@this.AddSwaggerGen(c =>
{
var title = Assembly.GetEntryAssembly().GetName().Name;
c.SwaggerDoc("v1", new OpenApiInfo { Title = title, Version = "v1" });
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{title}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});
return @this;
}
}
}
And this is it after:
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using System.Linq;
namespace Microsoft.Extensions.DependencyInjection
{
public static partial class ServiceCollectionExtensions
{
public static IServiceCollection AddDmforce4SwaggerSupport(this IServiceCollection @this, string title)
{
// Register the Swagger generator, defining 1 or more Swagger documents
@this.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = title, Version = "v1" });
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{title}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});
return @this;
}
}
}
I hope this is helpful for somebody. My issue is hereby resolved.
If it helps any body you can resolve this issue by using the right version of dotnet sdk. If your project uses dotnet 2.1 as target run time, you should use the same to install the tool and also running the swagger generation command. Thats how this error resolved for me. The developers have put this as a note too in the documentation.
Expanding on tariqzafa700 answer, make sure you have a global.json file in your project so when you issue a "dotnet" cmd you are using the correct version of the SDK instead of the latest version installed in your machine. For instance, if your project is .net 5, then you must use 5.0.x SDK:
{
"sdk": {
"version": "5.0.0",
"rollForward": "latestFeature"
}
}
In my case, the dotnet version used is going to be 5.0.2 instead of 6.0.1 which is the latest I have at the moment.
More info on this here.
Hi all, great tool idea. I'm trying to get it working. Right now I have the latest 5.0 installed.
doing a dotnet publish -o ./pub swagger tofile --output .\swagger.json .\pub\bin\myfile.dll v1
And getting a: Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Runtime.Loader, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) at Swashbuckle.AspNetCore.Cli.Program.<>c.b__0_3(IDictionary
2 namedArgs) at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable
1 args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 68 at Swashbuckle.AspNetCore.Cli.CommandRunner.Run(IEnumerable`1 args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\CommandRunner.cs:line 68 at Swashbuckle.AspNetCore.Cli.Program.Main(String[] args) in C:\projects\ahoy\src\Swashbuckle.AspNetCore.Cli\Program.cs:line 106