有了SwashBuckle,我们有一个项目正在为数组/列表创建内联模式:
对,它会返回如下内容:
"200": {
"description": "Success",
"schema": {
"uniqueItems": false,
"type": "array",
"items": {
"$ref": "#/definitions/SwaggerGenerationSample.Models.Response.Employee"
}
}
}
我们想要这样的东西:
"200": {
"description": "Success",
"schema": {
"$ref": "#/definitions/EmployeeArray"
}
}
...
"definitions": {
"EmployeeArray": {
"uniqueItems": false,
"type": "array",
"items": {
"$ref": "#/definitions/SwaggerGenerationSample.Models.Response.Employee"
}
}
}
我们应该在SwashBuckle中配置什么以获得上述结果?我创建了一个示例项目来重现该问题:https://github.com/mvdiemen/SwaggerArrayGenerationExample
答案 0 :(得分:1)
从Swashbuckle(此处为Override Schema for Specific Types)中获取ISchemaFilter的一般准则。
您想要的是提供自己的显式架构。对于您的示例项目,对于任何数组,我们都可以使用:
/**
* code dependencies:
* netcoreapp2.1
* Microsoft.AspNetCore.App;2.1.*
* Swashbuckle.AspNetCore;4.0.1
*/
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace SwaggerGenerationSample
{
public class ArraySchemaFilter : ISchemaFilter
{
public void Apply(Schema schema, SchemaFilterContext context)
{
// has to be changed to enumerable later on...
if (context.SystemType.IsArray && context.SystemType.HasElementType)
{
// could be generalized to any T[], for now ...
var elemType = context.SystemType.GetElementType();
if (elemType != typeof(SwaggerGenerationSample.Models.Response.Employee)) return;
var name = elemType.Name + "Array";
// add if not done already
if (!context.SchemaRegistry.Definitions.ContainsKey(name))
{
context.SchemaRegistry.Definitions.Add(
name,
new Schema
{
UniqueItems = schema.UniqueItems,
Type = schema.Type,
Items = schema.Items,
});
}
// and clear the schema for the endpoint...
schema.UniqueItems = null;
schema.Type = null;
schema.Items = null;
schema.Ref = "#/definitions/" + name;
}
}
}
}
我们需要在启动时添加过滤器。
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(config =>
{
/* your config omitted for brevity */
config.SchemaFilter<ArraySchemaFilter>();
}
}
要使其正常工作,我们需要将端点从IEnumerable<T>
“调整”到T[]
。
public class EmployeeController : ControllerBase
{
[SwaggerResponse((int)HttpStatusCode.OK, Type = typeof(Models.Response.Employee[]))]
/* other attributes omitted for brevity */
public async Task<IActionResult> GetEmployees(string companyId)
{
return Ok(GetEmployees());
}
}
运行该应用,并且swagger.json
应该包含所请求的架构。
为您准备的作业是用IEnumerable<>
替换数组限制,但是上面的代码足以作为概念证明。
如果升级到 .Net Core 3 (或更高版本),则必须更新代码-非常有可能。并使用 Swashbuckle.AspNetCore 5 即将打破的消息已经宣布[^ 1]。
[^ 1]:请参见此处的发行说明:https://github.com/domaindrivendev/Swashbuckle.AspNetCore/releases/tag/v5.0.0-rc4