代码之家  ›  专栏  ›  技术社区  ›  Paul Wild

使用路由属性和查询参数时Web api2的招摇过市文档

  •  1
  • Paul Wild  · 技术社区  · 8 年前

    我有一个简单的web API2项目,它使用swagger制作文档。

    给定一个使用路由参数和查询参数的简单GET端点,例如:

    [HttpGet]
    [Route("api/v2/items/{itemid:int}")]
    public IHttpActionResult Getv2(int itemId, [FromUri(Name ="")]DTOv1 request)
    {
        return Ok();
    }
    
    public class DTOv1
    {
        public DateTime? StartValue { get; set; }
    }
    

    这提供了以下文档: Correct Swagger documentation

    但是,我希望能够指定POCO中的所有项目。例如:

    [HttpGet]
    [Route("api/v3/items/{itemid:int}")]
    public IHttpActionResult Getv3([FromUri(Name ="")]DTOv2 request)
    {
        return Ok();
    } 
    
    public class DTOv2
    {
        public int ItemId { get; set; }
        public DateTime? StartValue { get; set; }
    }
    

    这导致以下文件不正确: Incorrect Swagger documentation

    这个GET端点的工作方式与第一个示例相同,但正如您所看到的,文档没有这样做,尝试执行一个示例将不起作用。是否可以配置swagger,以便以与第一个示例相同的方式记录,最好是以基于约定的方式记录?

    Swagger仅使用默认设置:

    GlobalConfiguration.Configuration
        .EnableSwagger(c =>
            {
                c.SingleApiVersion("v1", "TestSwagger");
                c.PrettyPrint();
            })
        .EnableSwaggerUi(c =>
            {
            });
    

    编辑:

    多亏了关于添加过滤器的回复,我编写了以下操作过滤器,在我们的用例中可以操作参数:

    private class OperationFilter : IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            if (apiDescription.HttpMethod.Method == "GET")
            {
                var pathParams = operation.parameters.Where(x => x.@in == "path");
    
                var toRemoveItems = new List<Parameter>();
                foreach(var pathParam in pathParams)
                {
                    toRemoveItems.AddRange(operation
                        .parameters
                        .Where(x => x.@in != "path" && x.name.EndsWith(pathParam.name)));                     
                }
    
                foreach(var toRemove in toRemoveItems)
                {
                    operation.parameters.Remove(toRemove);
                }
            }
        }
    }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Helder Sepulveda    8 年前

    根据关于使用 IDocumentFilter 这是一个起点:

        private class RouteTestDocumentFilter : IDocumentFilter
        {
            const string PATH = "/api/RouteTest/test/{itemid}";
    
            public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry s, IApiExplorer a)
            {
                if (swaggerDoc.paths != null && swaggerDoc.paths.ContainsKey(PATH))
                {
                    var get = swaggerDoc.paths[PATH].get;
                    if (get != null)
                    {
                        get.parameters.RemoveAt(0);
                        get.parameters[0].@in = "path";
                        get.parameters[0].required = true;
    
                        foreach (var param in get.parameters)
                        {
                            int pos = param.name.IndexOf('.');
                            if (pos > 0)
                                param.name = param.name.Substring(pos + 1);
                        }
                    }
                }
            }
        }
    

    有关更多详细信息,请参阅我的提交:
    https://github.com/heldersepu/SwashbuckleTest/commit/38a31e0ee700faf91cc38d005ae1c5f4bec3e1f3

    以下是它在UI上的外观:
    http://swashbuckletest.azurewebsites.net/swagger/ui/index?filter=RouteTest#/RouteTest/RouteTest_Get

    推荐文章