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

如何在ASP.NET Core Minimal API生成的OpenAPI规范中配置Server URL路径

问题:ASP.NET Core Minimal API Swagger Server路径配置导致404

我有一个基于C#/ASP.NET Core的Minimal API应用,通过Swagger生成OpenAPI规范。为匹配发布yml文件要求,需要把路径前缀(/api/v2)加到Swagger的Server配置中,同时移除路由组里的该前缀。

最初的Swagger配置代码如下:

.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "My API",
        Version = "2.0",
    });

    c.AddServer(new OpenApiServer
    {
        Url = "https://api.myapi.org.uk/api/v2",
        Description = "Production"
    });

    c.AddServer(new OpenApiServer
    {
        Url = "https://localhost:{port}/api/v2",
        Description = "Local",
        Variables =
        {
            new ("port", new OpenApiServerVariable
            {
                Default = "7147",
            }),
        },
    });
})

对应的路由组配置:

var builder = app.MapGroup("/needs");
builder.MapGet("/", async (CancellationToken cancellationToken) => { ... });

但用Swagger UI测试时,所有请求都返回404。如果把/api/v2移到路由组里,同时简化Server的URL配置,就能正常工作:

.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "My API",
        Version = "2.0",
    });

    c.AddServer(new OpenApiServer
    {
        Url = "https://api.myapi.org.uk/",
        Description = "Production"
    });

    c.AddServer(new OpenApiServer
    {
        Url = "https://localhost:{port}/",
        Description = "Local",
        Variables =
        {
            new ("port", new OpenApiServerVariable
            {
                Default = "7147",
            }),
        },
    });
})

// ...

var builder = app.MapGroup("/api/v2/needs");
builder.MapGet("/", async (CancellationToken cancellationToken) => { ... });

我试过多种组合都没解决问题,想知道这是OpenAPI规范的实现问题,还是有可行的解决办法?最终需要生成的OpenAPI结构如下:

openapi: 3.0.1
info:
  title: My API
  version: '2.0'
servers:
  - url: https://myapi.org.uk/api/v2
    description: Production
  - url: 'https://localhost:{port}'
    description: Local
    variables:
      port:
        default: '7147'

paths:
  /needs:
    get:
      ...

解决方案

问题根源

Swagger UI会直接把Server配置的URL和OpenAPI文档里paths中的路径拼接发起请求。初始配置中,Server URL是https://api.myapi.org.uk/api/v2,paths里的路径是/needs,所以Swagger UI会请求https://api.myapi.org.uk/api/v2/needs,但实际API并没有/api/v2前缀,因此返回404。

要同时满足OpenAPI文档结构要求和API正常响应,有两种可行方法:

方法1:配置API的PathBase前缀(推荐)

在Program.cs的路由配置前添加UsePathBase,给整个API加上/api/v2前缀:

// 在app.MapGroup之前添加
app.UsePathBase("/api/v2");

// 路由组保持不变
var builder = app.MapGroup("/needs");
builder.MapGet("/", async (CancellationToken cancellationToken) => { ... });

然后调整Swagger的Server配置,去掉URL里的/api/v2:

c.AddServer(new OpenApiServer
{
    Url = "https://api.myapi.org.uk/",
    Description = "Production"
});

c.AddServer(new OpenApiServer
{
    Url = "https://localhost:{port}/",
    Description = "Local",
    Variables =
    {
        new ("port", new OpenApiServerVariable
        {
            Default = "7147",
        }),
    },
});

如果需要paths显示为/needs而非/api/v2/needs,可以配合下面的文档过滤器调整。

方法2:用文档过滤器修改OpenAPI路径

如果不能修改API实际路由前缀,或必须让paths显示为/needs,可以自定义Swagger文档过滤器,移除生成路径中的/api/v2前缀:

首先添加过滤器类:

public class RemovePathPrefixFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        var updatedPaths = new OpenApiPaths();
        foreach (var pathEntry in swaggerDoc.Paths)
        {
            // 移除路径中的/api/v2前缀
            var cleanedPath = pathEntry.Key.Replace("/api/v2", string.Empty);
            updatedPaths.Add(cleanedPath, pathEntry.Value);
        }
        swaggerDoc.Paths = updatedPaths;
    }
}

然后在Swagger配置中注册这个过滤器:

.AddSwaggerGen(c =>
{
    // 其他配置...
    c.DocumentFilter<RemovePathPrefixFilter>();

    // Server配置保持目标结构
    c.AddServer(new OpenApiServer
    {
        Url = "https://api.myapi.org.uk/api/v2",
        Description = "Production"
    });

    c.AddServer(new OpenApiServer
    {
        Url = "https://localhost:{port}",
        Description = "Local",
        Variables =
        {
            new ("port", new OpenApiServerVariable
            {
                Default = "7147",
            }),
        },
    });
})

同时确保API实际路由前缀为/api/v2(通过UsePathBase或路由组前缀实现),这样Swagger UI拼接的请求路径就能匹配实际API路由。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:45:01