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

如何修改Swagger UI端点路由中的Swagger Server路径以简化显示?

问题分析与解决方案

你遇到的核心问题是:既要保留控制器原有路由(保证实际请求能正确匹配),又要让Swagger UI显示简化后的端点路径。之前两种方案的问题根源如下:

  • 方案1:仅设置Servers但未修改Swagger文档中的原始路径,导致Swagger将Server URL与原始路径拼接,出现重复前缀(如/api/public/api/public/v1.0/Test)。
  • 方案2:修改控制器路由后,Swagger显示路径正确,但实际路由缺少/api/public或/api前缀,无法匹配控制器,因此返回404。

正确解决思路

需要同时修改Swagger文档中的路径(去掉前缀)和配置正确的Server URL:

  1. 保留控制器原有路由(确保实际请求能被正确路由)。
  2. 通过文档过滤器移除Swagger文档中路径的/api/public或/api前缀,让UI显示简化路径。
  3. 配置Servers的URL为对应的前缀,使Swagger在发送测试请求时,自动将Server URL与简化路径拼接成正确的请求地址。

具体实现代码

1. 创建文档过滤器(移除路径前缀)

public class RemoveApiPrefixFilter : IDocumentFilter
{
    // 需要移除的前缀列表
    private readonly string[] _prefixes = { "/api/public", "/api" };

    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        var pathsToRemove = new List<string>();
        var newPaths = new Dictionary<string, OpenApiPathItem>();

        foreach (var (originalPath, pathItem) in swaggerDoc.Paths)
        {
            foreach (var prefix in _prefixes)
            {
                if (originalPath.StartsWith(prefix))
                {
                    // 生成去掉前缀的新路径
                    var simplifiedPath = originalPath.Substring(prefix.Length);
                    pathsToRemove.Add(originalPath);
                    newPaths.Add(simplifiedPath, pathItem);
                    break;
                }
            }
        }

        // 移除原始路径,添加简化后的路径
        foreach (var path in pathsToRemove)
        {
            swaggerDoc.Paths.Remove(path);
        }
        foreach (var (path, item) in newPaths)
        {
            swaggerDoc.Paths.Add(path, item);
        }
    }
}

2. 配置Swagger服务与中间件

// 注册Swagger服务
services.AddSwaggerGen(c =>
{
    // 注册API版本文档(根据你的版本配置调整)
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "API 文档", Version = "v1.0" });
    // 添加文档过滤器
    c.DocumentFilter<RemoveApiPrefixFilter>();
});

// 启用Swagger中间件
app.UseSwagger(c =>
{
    c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
    {
        // 配置Server列表,对应两种前缀
        swaggerDoc.Servers = new List<OpenApiServer>
        {
            new OpenApiServer { Url = "/api/public", Description = "公开API" },
            new OpenApiServer { Url = "/api", Description = "内部API" }
        };
    });
});

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1.0");
});

进阶:拆分公开/内部API文档

如果需要将公开和内部API分开显示,可以通过文档分组实现:

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("public-v1", new OpenApiInfo { Title = "公开API", Version = "v1.0" });
    c.SwaggerDoc("internal-v1", new OpenApiInfo { Title = "内部API", Version = "v1.0" });

    c.DocumentFilter<RemoveApiPrefixFilter>();

    // 筛选不同分组的API
    c.DocInclusionPredicate((docName, apiDesc) =>
    {
        if (docName == "public-v1")
        {
            return apiDesc.RelativePath.StartsWith("api/public");
        }
        else if (docName == "internal-v1")
        {
            return apiDesc.RelativePath.StartsWith("api") && !apiDesc.RelativePath.StartsWith("api/public");
        }
        return false;
    });
});

// Swagger UI配置
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/public-v1/swagger.json", "公开API v1.0");
    c.SwaggerEndpoint("/swagger/internal-v1/swagger.json", "内部API v1.0");
});

这样配置后,Swagger UI会显示简化后的/v1.0/Test路径,测试请求时会自动拼接Server URL,生成正确的/api/public/v1.0/Test或/api/v1.0/Internal地址,同时控制器原有路由保持不变,不会出现404问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 06:22:35