You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps中ASP.NET Core Web API的Swagger CI生成问题

在Azure DevOps构建阶段无依赖生成Swagger的解决方案

当前使用Swashbuckle.AspNetCore.Cli生成Swagger文档时,CLI会启动整个Web应用,触发配置文件加载(如appsettings.json)甚至数据库连接逻辑,在CI环境中容易引发依赖缺失问题。以下是几种可行的解决思路:

1. 调整配置加载逻辑,适配Swagger CLI场景

在项目的Program.cs(或Main方法)中,通过命令行参数识别Swagger CLI调用场景,允许配置文件可选,避免因缺失配置导致启动失败:

var isSwaggerCli = args.Any(arg => arg.Contains("swagger", StringComparison.OrdinalIgnoreCase));

IConfiguration Configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    // Swagger CLI调用时,允许appsettings.json不存在
    .AddJsonFile("appsettings.json", optional: isSwaggerCli, reloadOnChange: true)
    .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
    .AddEnvironmentVariables()
    .Build();

2. 跳过非必要服务的注册

生成Swagger仅需要控制器和模型的元数据,无需初始化数据库、第三方服务等依赖。在服务注册阶段判断Swagger CLI场景,跳过这些非必要服务:

var builder = WebApplication.CreateBuilder(args);
var isSwaggerCli = args.Any(arg => arg.Contains("swagger", StringComparison.OrdinalIgnoreCase));

// 仅在非Swagger场景下注册数据库等依赖服务
if (!isSwaggerCli)
{
    builder.Services.AddDbContext<AppDbContext>(options =>
        options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
}

// 始终注册Swagger生成所需服务
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Api", Version = "v1" });
});

var app = builder.Build();

// 非Swagger场景下才配置业务相关中间件
if (!isSwaggerCli)
{
    app.UseHttpsRedirection();
    app.UseAuthorization();
}

// 保留Swagger中间件以支持CLI生成
app.UseSwagger();

app.Run();

3. 脱离Web应用,直接通过代码生成Swagger文档

创建一个独立的控制台项目,利用Swashbuckle.AspNetCore.SwaggerGen从Api程序集提取元数据生成文档,无需启动Web应用:

步骤:

  1. 在解决方案中添加一个.NET控制台项目
  2. 安装NuGet包:Swashbuckle.AspNetCore.SwaggerGen、Microsoft.AspNetCore.Mvc.Core
  3. 编写生成代码:
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System.Text.Json;
using System.Reflection;

// 替换为你的Api项目程序集路径
var apiAssemblyPath = Path.Combine(Environment.GetEnvironmentVariable("SYSTEM_DEFAULTWORKINGDIRECTORY") ?? "", 
    "src/Api/bin/Release/net8.0/Api.dll");
var apiAssembly = Assembly.LoadFrom(apiAssemblyPath);

var services = new ServiceCollection();
// 添加Api程序集作为应用部件
services.AddControllers()
    .AddApplicationPart(apiAssembly);

// 配置Swagger生成
services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Api", Version = "v1" });
    // 若Api使用了XML注释,可添加以下配置
    // var xmlFile = $"{apiAssembly.GetName().Name}.xml";
    // var xmlPath = Path.Combine(Path.GetDirectoryName(apiAssemblyPath) ?? "", xmlFile);
    // c.IncludeXmlComments(xmlPath);
});

var serviceProvider = services.BuildServiceProvider();
var apiDescriptionProvider = serviceProvider.GetRequiredService<IApiDescriptionGroupCollectionProvider>();
var swaggerGenerator = serviceProvider.GetRequiredService<ISwaggerProvider>();

// 生成Swagger文档
var swaggerDoc = swaggerGenerator.GetSwagger("v1");

// 保存到构建产物目录
var outputPath = Path.Combine(Environment.GetEnvironmentVariable("BUILD_ARTIFACTSTAGINGDIRECTORY") ?? "./", "swagger.json");
using var fs = new FileStream(outputPath, FileMode.Create);
await JsonSerializer.SerializeAsync(fs, swaggerDoc, new JsonSerializerOptions { WriteIndented = true });
  1. 在Azure DevOps构建任务中,先编译该控制台项目,再运行生成命令,替换原有的CmdLine任务。

4. (备选)确保CI环境中存在必要配置文件

如果必须保留原有启动逻辑,可在Azure DevOps任务中添加文件复制步骤,将appsettings.json(或一个仅包含空配置的版本)复制到工作目录:

- task: CopyFiles@2
  displayName: 'Copy Appsettings'
  inputs:
    SourceFolder: 'src/Api'
    Contents: 'appsettings.json'
    TargetFolder: '$(System.DefaultWorkingDirectory)/Api'

内容的提问来源于stack exchange,提问作者dna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:21:12