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

.NET7 Web API如何在OpenAPI规范中保留集合资源URI的尾斜杠?

解决Swashbuckle.AspNetCore生成OpenAPI时保留集合资源URI尾斜杠的问题

Swashbuckle.AspNetCore默认会自动移除OpenAPI规范中路径末尾的斜杠,这就是为什么你在控制器Route属性里加了尾斜杠,生成的文档里却没显示的原因。要实现仅在OpenAPI文档中保留集合资源的尾斜杠,同时不影响API请求处理,可以通过自定义文档过滤器来修改生成的规范内容。

方案一:全局识别原始路由模板保留尾斜杠

创建一个实现IDocumentFilter的过滤器类,通过读取控制器的原始路由模板,判断是否需要为路径添加尾斜杠:

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

public class PreserveTrailingSlashDocumentFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        var updatedPaths = new OpenApiPaths();
        
        foreach (var pathEntry in swaggerDoc.Paths)
        {
            var apiDesc = context.ApiDescriptions.FirstOrDefault(
                desc => desc.RelativePath == pathEntry.Key.TrimStart('/'));
            
            string newPathKey = pathEntry.Key;
            // 检查原始路由模板是否以斜杠结尾,且当前路径未带斜杠
            if (apiDesc?.ActionDescriptor.AttributeRouteInfo?.Template != null 
                && apiDesc.ActionDescriptor.AttributeRouteInfo.Template.EndsWith("/") 
                && !newPathKey.EndsWith("/"))
            {
                newPathKey = $"{newPathKey}/";
            }
            
            updatedPaths.Add(newPathKey, pathEntry.Value);
        }
        
        swaggerDoc.Paths = updatedPaths;
    }
}

然后在Program.cs中注册这个过滤器:

builder.Services.AddSwaggerGen(c =>
{
    // 你的Swagger基础配置(如API信息、版本控制等)
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Your API", Version = "v1" });
    
    // 注册自定义文档过滤器
    c.DocumentFilter<PreserveTrailingSlashDocumentFilter>();
});

方案二:通过自定义属性精准控制集合资源

如果只想给特定的集合控制器/Action保留尾斜杠,可以先定义一个标记属性:

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

然后在需要的控制器上添加该属性:

[ApiController]
[Route("api/v{version:apiVersion}/schools/")]
[PreserveTrailingSlash] // 添加标记属性
public class SchoolsController : ControllerBase
{
    // GET: api/v1/schools/
    [HttpGet]
    public IActionResult GetSchools() => Ok();
    
    // POST: api/v1/schools/
    [HttpPost]
    public IActionResult CreateSchool(SchoolDto dto) => Created();
}

接着修改过滤器类,识别这个标记属性并处理路径:

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

public class PreserveTrailingSlashDocumentFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        var updatedPaths = new OpenApiPaths();
        
        // 先处理带标记属性的路径
        foreach (var apiDesc in context.ApiDescriptions)
        {
            var hasPreserveAttr = apiDesc.ActionDescriptor.ControllerTypeInfo
                                      .GetCustomAttributes<PreserveTrailingSlashAttribute>().Any()
                                  || apiDesc.ActionDescriptor.MethodInfo
                                      .GetCustomAttributes<PreserveTrailingSlashAttribute>().Any();
            
            if (hasPreserveAttr)
            {
                string originalPath = "/" + apiDesc.RelativePath;
                string newPath = originalPath.EndsWith("/") ? originalPath : $"{originalPath}/";
                
                if (swaggerDoc.Paths.TryGetValue(originalPath, out var pathItem))
                {
                    updatedPaths.Add(newPath, pathItem);
                    swaggerDoc.Paths.Remove(originalPath);
                }
            }
        }
        
        // 保留其他未标记的路径
        foreach (var pathEntry in swaggerDoc.Paths)
        {
            if (!updatedPaths.ContainsKey(pathEntry.Key))
            {
                updatedPaths.Add(pathEntry.Key, pathEntry.Value);
            }
        }
        
        swaggerDoc.Paths = updatedPaths;
    }
}

同样在Program.cs中注册这个过滤器即可。

注意事项

  • .NET Web API默认会自动兼容带或不带尾斜杠的请求,无需额外配置严格路由校验,符合你的需求。
  • 上述两种方案都会让Swagger UI中的测试链接自动带上尾斜杠,保证API使用者看到的规范符合要求。

内容的提问来源于stack exchange,提问作者exploring.cheerily.impresses

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:23:17