从 NSwag swagger 中过滤模式

Ant*_*ony 1 asp.net-web-api swagger nswag

我有一个带有 API 端点的 ASP.NET 完整框架应用程序。我正在使用 NSwag 生成一个 swagger 文档。这一切都有效。

我只需要为一小部分端点生成一个文档。路径已过滤,但架构未过滤。如何过滤架构对象以匹配路径过滤?

示例:我有这个过滤器

    public class IncludeControllersInSwagger : IOperationProcessor
    {
        public Task<bool> ProcessAsync(OperationProcessorContext context)
        {
            return Task.FromResult(
                context.ControllerType == typeof(ControllerA));
        }
    }
Run Code Online (Sandbox Code Playgroud)

这在启动时:
settings.GeneratorSettings.OperationProcessors.Add(new IncludeControllersInSwagger());

控制器是:

    public class AResponse
    {
        public string Message { get; set; }
        public bool Flag { get; set; }
    }

    public class BResponse
    {
        public string Message { get; set; }
        public int Count { get; set; }
    }

    [Route("a")]
    public class ControllerA : ApiController
    {
        [HttpGet]
        public AResponse Get()
        {
            return new AResponse
            {
                Message = "Hello from A",
                Flag = true
            };
        }
    }

    [Route("b")]
    public class ControllerB : ApiController
    {
        [HttpGet]
        public BResponse Get()
        {
            return new BResponse
            {
                Message = "Hello from B",
                Count = 42
            };
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后生成的 swagger 只包含一个路径:

  "paths": {
    "/a": {
      "get": {  .. etc
    }
  }
Run Code Online (Sandbox Code Playgroud)

就是这样,这是正确的。

模式包含两者:

 "schemas": {
      "AResponse": {
        "type": "object",
        "additionalProperties": false,
 etc
      },
      "BResponse": {
        "type": "object",
        "additionalProperties": false,
etc
        }
      }
    }
Run Code Online (Sandbox Code Playgroud)

BResponse类型不应该在那里。你如何删除它?

这个额外的数据使得 Schemas 部分变得非常冗长,在超过 10 个端点的情况下不适合公共文档,只有 2 个通过网关公开,因此以 swagger 形式记录。

有一个,ISchemaProcessor但它不像IOperationProcessor.

Ric*_*ter 8

您是否尝试过将操作过滤器添加为第一个元素?

IEOperationProcessors.Insert(0, new IncludeControllersInSwagger())

我认为这很重要,因为它将在生成 dto 模式并将其添加到文档之前过滤掉操作。


小智 5

这不是您问题的答案,因为您已经得到了一个似乎有效的答案。不过我有一个建议。我建议创建一个自定义属性,而不是检查处理器中的控制器类型:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class IncludeInSwaggerAttribute : Attribute
{
}
Run Code Online (Sandbox Code Playgroud)

然后更改您的处理器以查找此属性:

public class IncludeInSwaggerOperationProcessor : IOperationProcessor
{
    public async Task<bool> ProcessAsync(OperationProcessorContext context)
    {
        return context.ControllerType.GetCustomAttributes<IncludeInSwaggerAttribute>().Any() || 
               context.MethodInfo.GetCustomAttributes<IncludeInSwaggerAttribute>().Any();
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以将属性添加到要包含在 swagger 中的任何新控制器,而无需更改处理器。您还可以在单​​个动作上添加属性以仅包含该动作,而将控制器中的其余动作保留在 swagger 之外。