RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.76k stars 1.29k forks source link

Controllers not included in specification when using minimalAPI #3794

Open Bleialf opened 2 years ago

Bleialf commented 2 years ago

I'm trying to setup NSwagStudio (v13.15.4.0) with a net6 webapplication using the minimal API template. It seems that the Legacy controllers are not included in the specification. I also tried the NSwag.Sample.NET60Minimal which shows the same behavior (doesn't map the controller included in the program.cs file).

Is this behavior expected at this point or am I missing something? I want to force myself to use the new template but I still want to use the legacy Controllers.

jaumemilian commented 2 years ago

We are facing the same issue trying to generate clients using MsBuild But also checked that with the Npm Tool it neither works properly

RicoSuter commented 2 years ago

It seems that the controllers are only added to the pipeline and API explorer when the middlewares are executed.

However the CLI does not execute the middlewares but only the service registrations and thus they do not show up. I do not know whether this is a bug in ASP.NET or something NSwag can fix...

does someone know whether this works with Swashbuckle and its CLI?

/cc @bradygaster can you help here?

dylanvdmerwe commented 2 years ago

Confirming that using a minimal API in net6, running nswag from command line (13.15.5) generates a blank TS file. No controllers seem to be generated.

RicoSuter commented 2 years ago

If you run the app and check Swagger UI and the spec is generated via the HTTP pipeline then controllers are picked up, so i conclude that controllers picked up by API explorer in the HTTP middlewares/pipeline and not in the services.

dylanvdmerwe commented 2 years ago

If you browse to the swagger endpoint when running the site, all controllers and methods show up correctly. There must be a way for nswag to pick up the API explorer from the HTTP middleware?

RicoSuter commented 2 years ago

If you browse to the swagger endpoint when running the site, all controllers and methods show up correctly

This is also generated by NSwag (so it picks up in this case).

nswag to pick up the API explorer from the HTTP middleware

The problem is that the CLI does not really start the app but only runs the DI setup (ConfigureServices) and somehow in this scenario the controllers are not added to API Explorer... no idea how to fix that. I would expect that AddControllers (DI) registers the controllers which are picked up by API Explorer (without starting the middlewares etc).

/cc @pranavkm can you give us some insights here? Is this something which needs to be fixed in ASP.NET Core minimal API handling?

dylanvdmerwe commented 2 years ago

So are we saying that new .NET 6 projects (or migrated ones) that move to the minimal API for Program.cs is not supported by NSwag?

Note that adding builder.Services.AddEndpointsApiExplorer(); before builder.Services.AddSwaggerDocument does not help.

RicoSuter commented 2 years ago

So are we saying that new .NET 6 projects (or migrated ones) that move to the minimal API for Program.cs is not supported by NSwag?

Correct, currently this is not supported and you should use standard Startup.cs with controllers for now... no clue whether this can be fixed actually or whether it's a limitation of ASP.NET Core... does Swashbuckle support that already? Talking about CLI support - Swagger UI 3 works with controllers and minimal APIs also with NSwag.

Powerz commented 2 years ago

Hi @RicoSuter, is there any chance this PR could be merged in foreseeable future?

https://github.com/RicoSuter/NSwag/pull/3814

ranouf commented 2 years ago

Hi,

I saw that the PR has been merged, so I guess the last version of nswag studio (13.15.5.0 installed today) is supposed to handle .net 6.0 without startup file?

Currently when I try to generate the angular api.service.ts, the generated file is empty.

Do I need to add a specific thing in my cs files to make it work?

Thanks

lahma commented 2 years ago

The PR was merged three days ago and 13.15.5 was released a month ago so it won't appear in old release. You can always use a version from MyGet feed (NuGet packages, see README) or download the latest artifacts if you need studio: https://github.com/RicoSuter/NSwag/actions/runs/1746617320 ( at the bottom of the page).

ranouf commented 2 years ago

Excellent! I will try that

ranouf commented 2 years ago

@lahma I installed your suggested version, and I have an infinite loading, I created a git to be able to reproduce it: https://github.com/ranouf/net60withnswag/tree/main

ranouf commented 2 years ago

there is more and more .Net Host process instanciate every second I can see on task manager: image

ranouf commented 2 years ago

Is there a way to see to live log somewhere? I'm interested to know where it's freezing

syska commented 2 years ago

@ranouf

It's not very clear how you run it ...

But i had a similar issue ... because i used the MSBuildTask ... i needed to set the noBuild to true in the nswag file. Else it would start a build, but because it was started with a build, it would continue in a loop ...

But it's a crazy wild guess ... since I have no idea how you run it.

ranouf commented 2 years ago

there is two ways I run it:

let me know if it helps you to find to help me?

RicoSuter commented 2 years ago

is supposed to handle .net 6.0 without startup file

I hope/think this PR will fix this scenario https://github.com/RicoSuter/NSwag/pull/3814

RicoSuter commented 2 years ago

But i had a similar issue ... because i used the MSBuildTask ... i needed to set the noBuild to true in the nswag file. Else it would start a build, but because it was started with a build, it would continue in a loop ...

Yes, this infinite process loop happens usually if you generate the spec as build task and do not set nobuild to true, because if it's false each build will start another build...

lahma commented 2 years ago

@ranouf there's now a new release on NuGet, hope it helps.

RicoSuter commented 2 years ago

Seems to be working now via CLI:

image

ranouf commented 2 years ago

Hi,

I just updated the nswag package on my repo: https://github.com/ranouf/net60withnswag/commit/85f7bb4d8b54bd5fca9471674e2b330b52dbdc91

I still continue to have an infinite loading, and an infinite adding of .net host process. image

I will restart my computer, maybe it could work ... :) I ll let you know.

Btw, I don't know if it could make a difference:

dotnet --version
6.0.101
ranouf commented 2 years ago

I let nswag studio runs for more than hour, still loading, here is the info from task manager image

Is there a way to access to live log somewhere? like a text file generated in tmp folder? I will be able to add more details about why I have an infinite loading.

@RicoSuter did you have an opportunity to take a look on my git? If not, you can download the code there https://github.com/ranouf/net60withnswag, and just open the nswag file at root, every thign is alrady configured, just need to click on generate files in nswag studio.

syska commented 2 years ago

I let nswag studio runs for more than hour, still loading, here is the info from task manager image

Is there a way to access to live log somewhere? like a text file generated in tmp folder? I will be able to add more details about why I have an infinite loading.

@RicoSuter did you have an opportunity to take a look on my git? If not, you can download the code there https://github.com/ranouf/net60withnswag, and just open the nswag file at root, every thign is alrady configured, just need to click on generate files in nswag studio.

You need to create the smallest possible replica ...

This does not compile, because you have an external dependency from(possibly an internal Nuget repository) ... I just tried.

ranouf commented 2 years ago

I created a lite version and I'm able to generate the typescript api services file! => https://github.com/ranouf/net60withnswag/tree/lite

But I still get an infinite loading on the main branch. Is there a way to get logs from nswagstudio to see where it blocks?

If not, what do you suggest to make it work? Remove things from startup? remove internal project references? I'm not sure where to start to reduce the complexity and find where exactly if creates the infinite loading issue.

note: Sorry for the mistake, I missed one private package when I created the repo, I updated it, so you ll be able to build it now if you want to try.

syska commented 2 years ago

I let nswag studio runs for more than hour, still loading, here is the info from task manager image

Is there a way to access to live log somewhere? like a text file generated in tmp folder? I will be able to add more details about why I have an infinite loading.

@RicoSuter did you have an opportunity to take a look on my git? If not, you can download the code there https://github.com/ranouf/net60withnswag, and just open the nswag file at root, every thign is alrady configured, just need to click on generate files in nswag studio.

Now i could compile the project, but NOT run it, because the DB fails.

Do note, the project needs to be able actually run to be able to generate the openapi specs.

When I removed the InitializeDataBasesAsync it worked. It probably tried to run the app multiple times when it kept failing.

it worked for me to generate the .ts client file.

ranouf commented 2 years ago

@syska @RicoSuter thanks a lot! It's now working.

Do note, the project needs to be able actually run to be able to generate the openapi specs.

Thanks for this explanation, I learnt something!

syska commented 2 years ago

@syska @RicoSuter thanks a lot! It's now working.

Do note, the project needs to be able actually run to be able to generate the openapi specs.

Thanks for this explanation, I learnt something!

It uses the ApiExplorer that scans the assemblies runtime. But for it to be able to do that it needs to run ... cause that its what generates the OpenApi specs. ( From my understanding ).

I'm just helping the open source projects in ways that I can. So the people like @RicoSuter also can have a life besides supporting this AWESOME project.

RicoSuter commented 2 years ago

Exacly, CLI actually runs the app but only ConfigureServices() (DI) and not Configure() (middlewares). Thats why it needs to be able to run, ie check some config and only register db in this case or you could use another config or asp environment etc (or catch the exception).

ranouf commented 2 years ago

I added the environment Development, so the appsettings.Development is correctly loaded with the needed values to make the API runs.

Not sure exactly why I didn't have to do this in the past, but it works now, that's the most important!

Thanks

RicoSuter commented 2 years ago

Tbh, this doesnt really explain the infinite loading. It should not retry infinitely, in case there is an exception on run…

JohnGalt1717 commented 7 months ago

I have a project that is using an abstracted creator at the top of the program.cs which shouldn't matter because it should just execute the program.cs file, but I get this error message.

System.InvalidOperationException: NSwag requires the assembly Contacts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null to have either an BuildWebHost or CreateWebHostBuilder/CreateHostBuilder method. See https://docs.microsoft.com/en-us/aspnet/core/fundamentals/hosting?tabs=aspnetcore2x for suggestions on ways to refactor your startup type.
   at NSwag.Commands.ServiceProviderResolver.GetServiceProvider(Assembly assembly) in /_/src/NSwag.Commands/HostApplication.cs:line 87
   at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiGeneratorCommandEntryPoint.Process(String commandContent, String outputFile, String applicationName) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/AspNetCoreToOpenApiGeneratorCommandEntryPoint.cs:line 27
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at NSwag.AspNetCore.Launcher.Program.Main(String[] args) in /_/src/NSwag.AspNetCore.Launcher/Program.cs:line 132

It appears it's trying to execute a dependant project that contains my dtos, not the actual service.

Is there a way to explicitly tell the cli how to run this properly?