使用路由属性和查询参数时,Web api2的Swagger文档

时间:2018-01-15 22:30:41

标签: c# asp.net asp.net-web-api2 swagger-ui swashbuckle

我有一个简单的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 个答案:

答案 0 :(得分:1)

关于使用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