Open anas2204 opened 5 years ago
Probably in the context of the generator the ConfigureServices method throws (because eg the configuration is null) - you need to check there in which context you are (generating or serving) and not throw exceptions - i.e. exclude the polly part when generating and then it should work...
@RicoSuter Thanks for the update, when I commented the code for calling Polly in ConfigureServices, it indeed worked on NSwagStudio and generated the file! The issue was the appsettings.json not being present in the same output folder (when I copied it into the folder, original code worked as well).
I had a follow up: Although this seems to be working on NSwag Studio, the Command-line or NSwag.MSBuild still doesn't work for me. I change my current directory to the location of the Output folder where the DLL is present and run:
Command: aspnetcore2openapi /assembly:TestApi.dll /documentName:OpenApi3 /output:swagger.json
But get the error I mentioned in my 1st message:
System.InvalidOperationException: The command 'aspnetcore2openapi /assembly:testapi.dll /documentname:openapi3 /output:swagger.json' could not be found.
Would you know why this happens? Also, since I explicitly mention on NSwag Studio where to get published files from ("referenced assembly files"), don't we have to do that on Command-line?
It’s best to configure with nswagstudio and save the config file in the proj dir, eg nswag.json and then run it with “nswag run nswag.json /runtime:NetCore22” etc
Thanks @RicoSuter for the suggestion. When I save the config file and run as "nswag run .. ", it works!
The NSwag.MSBuild still doesn't work when I use the same configuration file with this inserted in the ".csproj" file:
<Target Name="NSwag" AfterTargets="Build">
<Copy SourceFiles="@(ReferencePath)" DestinationFolder="$(OutDir)References" />
<Exec Command="$(NSwagExe_Core20) run nswag.json /variables:Configuration=$(Configuration)" />
<RemoveDir Directories="$(OutDir)References" />
</Target>
Error:
Error MSB3073 The command "dotnet "C:\Users\ansiddiq\.nuget\packages\nswag.msbuild\13.0.2\build\../tools/NetCore22/dotnet-nswag.dll" run nswag.json /variables:Configuration=Debug,OutDir=bin\Debug\netcoreapp2.2\" exited with code -1. CatalogApi C:\Users\ansiddiq\Source\Repos\CatalogService\Api\CatalogApi\TestApi.csproj
Also, if I put the following recommendation in the csproj file, the project crashes:
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
Let me know if you have thoughts on these issues.
Do you have a complete stack trace?
The error I posted is all I see when I try to compile.
@RicoSuter I'm also having issues with MSBuild
I have this set up using NSwag.MSBuild 13.0.4
, Ive tested the generic $(OutDir)$(TargetFileName)
and it expands to bin/Debug/netcoreapp2.2/{target assembly}l
, and have validated that that "IS" here the built {Target Assembly} resides; but when botnet build
is run it seem to repeat the bin/Debug/netcoreapp2.2/
part.
My goal is to generate the swagger.json and then build CSharp Clients for that file. Please excuse the {} placeholders in an attempt to no disclose proprietary information.
<Target Name="NSwag" AfterTargets="Build">
<Exec Command="$(NSwagExe_Core22) aspnetcore2openapi /assembly:$(OutDir)$(TargetFileName) /output:swagger.json" />
<Exec Command="$(NSwagExe_Core22) run nswag.json /variables:Configuration=$(Configuration),OutDir=$(OutDir),InputSwagger=swagger.json" />
</Target>
if I remove the $(OutDir)
part it tries to find the {Target Assembly} in the project root.
NSwag command line tool for .NET Core NetCore22, toolchain v13.0.4.0 (NJsonSchema v10.0.21.0 (Newtonsoft.Json v11.0.0.0))
Visit http://NSwag.org for more information.
NSwag bin directory: /Users/{user}/.nuget/packages/nswag.msbuild/13.0.4/tools/NetCore22
System.IO.FileNotFoundException: Could not load file or assembly '/Users/{user}/Projects/{solutions dir}/{project dir}/bin/Debug/netcoreapp2.2/bin/Debug/netcoreapp2.2/{target assembly}.dll'. The system cannot find the file specified.
File name: '/Users/{user}/Projects/{Solution Dir}/{Project Dir}/bin/Debug/netcoreapp2.2/bin/Debug/netcoreapp2.2/{Target Assembly}.dll'
at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
at NSwag.Commands.IsolatedSwaggerOutputCommandBase`1.<>c__DisplayClass10_0.<LoadAssemblies>b__0(String path) in C:\projects\nswag\src\NSwag.Commands\Commands\IsolatedSwaggerOutputCommandBase.cs:line 61
at System.Linq.Enumerable.SelectEnumerableIterator`2.ToArray()
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at NSwag.Commands.Generation.OpenApiGeneratorCommandBase`1.CreateWebHostAsync(AssemblyLoader assemblyLoader) in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\OpenApiGeneratorCommandBase.cs:line 306
at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.RunIsolatedAsync(AssemblyLoader assemblyLoader) in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiCommand.cs:line 309
at NSwag.Commands.IsolatedCommandBase`1.IsolatedCommandAssemblyLoader`1.Run(String commandType, String commandData, String[] assemblyPaths, String[] referencePaths) in C:\projects\nswag\src\NSwag.Commands\Commands\IsolatedCommandBase.cs:line 71
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
--- End of stack trace from previous location where exception was thrown ---
at NSwag.Commands.IsolatedCommandBase`1.RunIsolatedAsync(String configurationFile)
at NSwag.Commands.IsolatedSwaggerOutputCommandBase`1.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:\projects\nswag\src\NSwag.Commands\Commands\IsolatedSwaggerOutputCommandBase.cs:line 47
at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiCommand.cs:line 94
at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
at NConsole.CommandLineProcessor.Process(String[] args, Object input)
at NSwag.Commands.NSwagCommandProcessor.Process(String[] args) in C:\projects\nswag\src\NSwag.Commands\NSwagCommandProcessor.cs:line 56
However it has randomly works and then complains it can't load a referenced assembly Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer
, I guess this is because my project is somehow configured not to copy all referenced assembles to the output directory, but just wanted to validate that assumption too.
Have you tried to use /project instead of /assembly with /nobuild:true ?
@RicoSuter - Thanks!
TBH I had not previously known these options even existed as the documentation on NSwag/MSBuild does not mention them; however I tried this but got more errors:
Seems to Timeout ? I assume this in some way messes with the regular startup such that the WebApi can't start as its running from a different context that for example does not find app settings.json
etc. such the startup does not work ?
Output:
AssemblyName: {Assembly}
OutputPath: bin/Debug/netcoreapp2.2/
PlatformTarget:
Platform: AnyCPU
ProjectDepsFilePath: /Users/{user}/Projects/{Solution Dir}/{Project Dir}/bin/Debug/netcoreapp2.2/{Assembly Name}.deps.json
ProjectDir: /Users/{User}/Project/{Solution Dir}/{Project Dir}/
ProjectRuntimeConfigFilePath: /Users/{User}/Project/{Solution Dir}/{Project Dir}/bin/Debug/netcoreapp2.2/{Assembly Name}.runtimeconfig.json
TargetFileName: {Assembly Name}.dll
TargetFrameworkIdentifier: .NETCoreApp
Executing dotnet exec --depsfile /Users/{User}/Project/{Solution Dir}/{Project Dir}/bin/Debug/netcoreapp2.2/{Assembly Name}.deps.json --runtimeconfig /Users//{User}/Project/{Solution Dir}/{Project Dir}/bin/Debug/netcoreapp2.2/{Assembly Name}.runtimeconfig.json /Users/{User}/.nuget/packages/nswag.msbuild/13.0.4/tools/NetCore22/NSwag.AspNetCore.Launcher.dll /var/folders/7x/nxb_73n96rdcg6kx82k4q2180000gp/T/tmpJJDsMO.tmp /var/folders/7x/nxb_73n96rdcg6kx82k4q2180000gp/T/tmpGgpsnV.tmp {Assembly Name} /Users/{user}/.nuget/packages/nswag.msbuild/13.0.4/tools/NetCore22/
Launcher directory: /Users/{user}/.nuget/packages/nswag.msbuild/13.0.4/tools/NetCore22
System.InvalidOperationException: Process dotnet timed out.
at NSwag.Commands.Generation.AspNetCore.Exe.RunAsync(String executable, IReadOnlyList`1 args, IConsoleHost console, Nullable`1 timeout)
at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\AspNetCore\AspNetCoreToOpenApiCommand.cs:line 214
at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
at NConsole.CommandLineProcessor.Process(String[] args, Object input)
at NSwag.Commands.NSwagCommandProcessor.Process(String[] args) in C:\projects\nswag\src\NSwag.Commands\NSwagCommandProcessor.cs:line 56
I also can not even debug the API as the build steps that get triggered then block that too. Guess I'm need to do more MSBuild research to see if it's possible to only run the NSwag target when not in the context of debugging etc.
Additional hints and suggestion appreciated.
Without the NSwag MSBuild Steps this runs/debugs as expected.
<Target Name="NSwag" AfterTargets="Build">
<Exec Command="$(NSwagExe_Core22) aspnetcore2openapi /project:{Assembly Name}.csproj /nobuild:true /output:Client/swagger.json" />
<Exec Command="$(NSwagExe_Core22) run nswag.json /variables:Configuration=$(Configuration),OutDir=Client,InputSwagger=Client/swagger.json" />
</Target>
If you run with /project in an msbuild task it is important to set /nobuild to true as otherwise it will indefinitely build the project... (infinite recursion)
There are samples for this in the /samples directory I think.
Probably in the context of the generator the ConfigureServices method throws (because eg the configuration is null) - you need to check there in which context you are (generating or serving) and not throw exceptions - i.e. exclude the polly part when generating and then it should work...
@RicoSuter how do you check the context in ConfigureServices
to make such a decision?
I've tried to make use of the CaptureStartupErrors
configuration to generate OpenAPI/Swagger spec in spite of the ConfigureServices
method throws (eg StackExchange.Redis.RedisConnectionException).
CaptureStartupErrors
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<TStartup>();
webBuilder.CaptureStartupErrors(true);
});
ASPNETCORE_CAPTURESTARTUPERRORS
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<NSwagExe>dotnet nswag</NSwagExe>
</PropertyGroup>
<Target Name="InstallNSwagCli" AfterTargets="AfterPublish">
<Exec Command="dotnet tool restore" />
</Target>
<Target Name="ASPNET2OpenApi" AfterTargets="InstallNSwagCli">
<Exec EnvironmentVariables="ASPNETCORE_CAPTURESTARTUPERRORS=1" Command="$(NSwagExe) aspnetcore2openapi /configuration:$(Configuration) /project:$(AssemblyName).csproj /documentName:v87 /output:$(TargetDir)$(AssemblyName).openapi.json" />
</Target>
</Project>
Anyone tried to repro on latest NSwag? /assembly
is not legal anymore
I'm trying to generate OpenAPI document from .NET Core 2.2 Assembly files.
Setup I've installed NSwag studio so "nswag" command is directly available from Command prompt. I've also built using the following way as recommended:
dotnet build /p:CopyLocalLockFileAssemblies=true
Error: Command Line
The error I get after using AspNetCore2OpenApi command is:
Error: NSwagStudio
The error displayed is:
This error seems to be in a file where I use "Polly" library in Middleware for HTTP Retry logic. There is no problem in the code as it compiles/runs fine.
Any help is appreciated!