咨询:无需启动完整站点运行NSwag生成Swagger文档的方法及Swagger生成模式检测方案
Hey there! Let's tackle your NSwag Swagger generation issue step by step. You're running into problems because NSwag is spinning up your entire app to generate docs, which fails when it can't access resources like connection strings. Here are two solid solutions tailored to your NSwag.AspNetCore 13.11.3 setup:
The default AspNetCoreToOpenApi generator in your foobar.nswag config uses your project file to build and launch the app. Instead, you can configure it to read metadata directly from your compiled assembly, skipping app initialization entirely.
Update Your foobar.nswag Config:
Modify the documentGenerator.aspNetCoreToOpenApi section with these changes:
{ "runtime": "NetCore31", "defaultVariables": null, "documentGenerator": { "aspNetCoreToOpenApi": { "project": null, // Remove project reference "assemblyPaths": ["bin/Debug/netcoreapp3.1/Foobar.dll"], // Path to your compiled DLL (adjust for your build config) "noBuild": true, // Set to false if you want NSwag to compile the project first "createWebHostBuilderMethod": null, "startupType": null, // Keep all your existing settings (apiGroupNames, infoTitle, output, etc.) "apiGroupNames": [ "BACKEND" ], "infoTitle": "My Title", "infoVersion": "1.0.0", "output": "foobar-swagger.json", // ... rest of your original config } }, // ... rest of your codeGenerators config }
How It Works:
NSwag will load your compiled assembly directly via reflection to extract API metadata, instead of launching the app. Just make sure your project is compiled first (or set noBuild: false to let NSwag handle compilation automatically).
If you need to keep using the project-based generation (e.g., to capture dynamic routing or startup-specific config), you can add logic to your app to detect when NSwag is generating docs and skip resource-heavy initialization steps.
Option A: Use a Custom Environment in NSwag Config
This is the simplest approach. Update your foobar.nswag to use a unique environment for doc generation:
"aspNetCoreEnvironment": "SwaggerGenerate", // Replace "Development" with this custom environment
Then in your Startup.cs, check for this environment to skip resource setup:
public void ConfigureServices(IServiceCollection services, IWebHostEnvironment env) { // Skip database/resource registration only when generating Swagger if (env.EnvironmentName != "SwaggerGenerate") { services.AddDbContext<YourDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); // Add other resource-dependent services here } // Always register core services for API and Swagger services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("BACKEND", new OpenApiInfo { Title = "My Title", Version = "1.0.0" }); }); }
Option B: Use an Environment Variable
If you prefer not to change the environment, set an environment variable when running the NSwag command, then check for it in your startup code.
Run the NSwag command with the variable:
# Windows Command Prompt set NSWAG_GENERATE=true && node_modules/.bin/nswag run foobar.nswag /runtime:NetCore31 # PowerShell $env:NSWAG_GENERATE="true"; node_modules/.bin/nswag run foobar.nswag /runtime:NetCore31 # Linux/macOS NSWAG_GENERATE=true node_modules/.bin/nswag run foobar.nswag /runtime:NetCore31
Then in Startup.cs:
public void ConfigureServices(IServiceCollection services) { bool isGeneratingSwagger = Environment.GetEnvironmentVariable("NSWAG_GENERATE") == "true"; if (!isGeneratingSwagger) { // Register resource-dependent services like databases services.AddDbContext<YourDbContext>(...); } // Core services for API and Swagger services.AddControllers(); services.AddSwaggerGen(...); }
内容的提问来源于stack exchange,提问作者mortenbock

