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

如何在单个C# ASP.NET Core应用中为私有与公有API部署独立路径的Swagger UI

在ASP.NET Core中为公有/私有API部署独立的Swagger UI

我刚好做过一模一样的需求,你现在的问题主要是原来的配置把两个文档塞到了同一个Swagger UI里,只要调整两处配置就能实现完全独立的两个UI,具体步骤如下:

第一步:修复Swagger文档生成的注册逻辑

你之前两次调用AddSwaggerGen会覆盖掉第一次的配置,正确的做法是在同一个AddSwaggerGen里注册两个文档,同时让你的过滤器能区分处理对应的文档。

首先修改你的过滤器(以PublicAPISwaggerFilter为例),让它只处理公有文档:

public class PublicAPISwaggerFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        // 只处理标题为"Public API"的文档
        if (swaggerDoc.Info.Title != "Public API") return;

        // 遍历所有API路径,移除私有API
        foreach (var pathEntry in swaggerDoc.Paths.ToList())
        {
            var apiDesc = context.ApiDescriptions.FirstOrDefault(d => 
                d.RelativePath.Equals(pathEntry.Key.TrimStart('/'), StringComparison.OrdinalIgnoreCase));
            
            // 这里根据你标记私有API的方式判断,比如检查是否有[PrivateApi]特性
            if (apiDesc?.ControllerAttributes().Any(a => a is PrivateApiAttribute) == true ||
                apiDesc?.ActionAttributes().Any(a => a is PrivateApiAttribute) == true)
            {
                swaggerDoc.Paths.Remove(pathEntry.Key);
            }
        }
    }
}

对应的PrivateApiSwaggerFilter也做类似调整,只处理标题为"Private API"的文档,移除公有API。

然后在ConfigureServices里合并Swagger的注册:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSwaggerGen(c => 
    {
        // 注册公有API文档
        c.SwaggerDoc("v0.1_public", new OpenApiInfo { Title = "Public API", Version = "v0.1" });
        // 注册私有API文档
        c.SwaggerDoc("v0.1_private", new OpenApiInfo { Title = "Private API", Version = "v0.1" });
        
        // 添加两个过滤器,它们会自动处理对应文档
        c.DocumentFilter<PublicAPISwaggerFilter>();
        c.DocumentFilter<PrivateApiSwaggerFilter>();
    });
    ...
}

第二步:配置两个独立的Swagger UI

在Configure方法里,你需要多次调用UseSwaggerUI,每个指定不同的路由前缀,并且只加载对应的文档:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ...
    // 先启用Swagger JSON文档服务(这一步只需要调用一次)
    app.UseSwagger();

    // 配置公有API的Swagger UI,访问路径:/public/swagger
    app.UseSwaggerUI(c =>
    {
        c.RoutePrefix = "public/swagger";
        // 只加载公有API的JSON文档
        c.SwaggerEndpoint("/swagger/v0.1_public/swagger.json", "Public API v0.1");
        // 可选:隐藏Models面板,如果你的API不需要展示模型
        c.DefaultModelsExpandDepth(-1);
    });

    // 配置私有API的Swagger UI,访问路径:/private/swagger
    app.UseSwaggerUI(c =>
    {
        c.RoutePrefix = "private/swagger";
        // 只加载私有API的JSON文档
        c.SwaggerEndpoint("/swagger/v0.1_private/swagger.json", "Private API v0.1");
    });
    ...
}

补充:API标记建议

为了更清晰地区分公有和私有API,建议自定义两个特性:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class PublicApiAttribute : Attribute { }

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class PrivateApiAttribute : Attribute { }

然后在你的控制器/Action上标记:

[ApiController]
[Route("api/public/[controller]")]
[PublicApi]
public class PublicDataController : ControllerBase
{
    // 这里的方法都会被归为公有API
}

[ApiController]
[Route("api/private/[controller]")]
[PrivateApi]
public class InternalDataController : ControllerBase
{
    // 这里的方法都会被归为私有API
}

这样你的过滤器逻辑会更可靠,不会误过滤API。

现在启动应用测试:

  • 访问 https://localhost:port/public/swagger:只能看到公有API的文档,没有下拉菜单
  • 访问 https://localhost:port/private/swagger:只能看到私有API的文档,完全独立

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:47:40