【问题标题】:Set custom path prefix in API method using Swagger in .Net Core在 .Net Core 中使用 Swagger 在 API 方法中设置自定义路径前缀
【发布时间】:2018-12-19 10:16:35
【问题描述】:

我想在 .Net Core API 方法中使用 swagger 添加我的自定义路径前缀

例如,我的 API 方法是这样声明的:

[Route("api/v1/Customer")]
[HttpGet]
public async Task<IActionResult> Customer()
{
        // some implementation
        return Ok();
}

所以目前,如果我使用 http://localhost:50523/api/v1/Customer 调用 API,它可以正常工作。

现在,我想添加一些自定义路径前缀。例如。 /some/custom/path/ 在实际 API 方法路径之前。这意味着——如果我使用 http://localhost:50523/some/custom/path/api/v1/Customer 调用 API,它应该可以工作。

我想在 .Net 核心中使用 Swagger 来实现这一点,并且我不想更改操作方法级别的 API 路径,因为我已经编写了数百个 API 方法并且我不想更改每个操作方法的 URL。

任何帮助将不胜感激。

【问题讨论】:

标签: asp.net asp.net-mvc asp.net-core .net-core swagger


【解决方案1】:

在 .Net 5.0 中

public class PathPrefixInsertDocumentFilter : IDocumentFilter
{
    private readonly string _pathPrefix;

    public PathPrefixInsertDocumentFilter(string prefix)
    {
        this._pathPrefix = prefix;
    }

    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        var paths = swaggerDoc.Paths.Keys.ToList();
        foreach (var path in paths)
        {
            var pathToChange = swaggerDoc.Paths[path];
            swaggerDoc.Paths.Remove(path);
            swaggerDoc.Paths.Add($"{_pathPrefix}{path}", pathToChange);
        }
    }
}

应用过滤器

services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new Info {Title = "MyApp", Version = "v1"});

    ...  other setup

    options.DocumentFilter<PathPrefixInsertDocumentFilter>("api");
});

【讨论】:

    【解决方案2】:

    如果添加 DocumentFilter,则可以将前缀添加到要更改的所有路径。

    public class PathPrefixInsertDocumentFilter : IDocumentFilter
    {
        private readonly string _pathPrefix;
    
        public PathPrefixInsertDocumentFilter(string prefix)
        {
            this._pathPrefix = prefix;
        }
    
        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
        {
            var paths = swaggerDoc.Paths.Keys.ToList();
            foreach (var path in paths)
            {
                var pathToChange = swaggerDoc.Paths[path];
                swaggerDoc.Paths.Remove(path);
                swaggerDoc.Paths.Add(new KeyValuePair<string, PathItem>("/" + _pathPrefix + path, pathToChange));
            }
        }
    }
    

    然后,您在 swagger 设置中添加过滤器:

            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info {Title = "MyApp", Version = "v1"});
    
                ...  other setup
    
                options.DocumentFilter<PathPrefixInsertDocumentFilter>("api");
            });
    

    这不会改变您的 API - 我们在生产环境中使用它来处理反向代理,我们使用前缀将请求路由到适当的容器,但将其剥离。

    【讨论】:

    • 如果您不想更改 Swagger UI 中显示的路径,您可以只使用 DocumentFilter 将前缀应用于 swaggerDoc.BasePath。这会使端点在 UI 中不带前缀显示,但在尝试调用它时会被使用。
    【解决方案3】:

    也许您可以在 Controller 类中使用 Route 属性,例如: [Route("/some/custom/path/")] public class CustomerController { [Route("api/v1/Customer")] [HttpGet] public async Task<IActionResult> Customer() { // some implementation return Ok(); } }

    希望对你有用

    【讨论】:

    • 谢谢,但我不能在控制器级别声明这一点,因为我的自定义路径会根据环境而改变,例如制作,舞台等。
    【解决方案4】:

    您可以在您的 api 控制器顶部使用 [Route("prefix/[controller]")]

    [Route("prefix/[controller]")]
    public class MyController : ControllerBase
    {
      [Route("api/v1/Customer")]
      [HttpGet]
       public async Task<IActionResult> Customer()
       {
        // some implementation
        return Ok();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-01
      • 1970-01-01
      • 2020-12-13
      • 1970-01-01
      • 1970-01-01
      • 2017-12-16
      • 2018-12-31
      • 2018-04-16
      相关资源
      最近更新 更多