使用路由属性和查询参数时 Web api2 的 Swagger 文档
Swagger Documentation for Web api2 when using route attributes and query paramaters
我有一个简单的 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; }
}
这提供了以下文档:
但是,我希望能够在 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; }
}
这给出了以下不正确的文档:
此 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);
}
}
}
}
根据我关于使用 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
我有一个简单的 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; }
}
这提供了以下文档:
但是,我希望能够在 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; }
}
这给出了以下不正确的文档:
此 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);
}
}
}
}
根据我关于使用 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