【发布时间】:2020-04-04 01:41:29
【问题描述】:
最近我将我的 api 从 netcore2.1 升级到 netcore3.1
我希望不要让 api 用户重写他们的客户端。
因此我希望我需要 swagger.json 向后兼容。
在旧的 swagger.json 中,枚举看起来像
但现在看起来像
我正在使用 Swashbuckle.AspNetCore 5.2.1
我有一个名为 AddSwaggerDocumentation 的扩展程序,它会调用
services.AddSwaggerGen(c =>
{
c.EnableAnnotations();
c.ParameterFilter<SwaggerEnumParameterFilter>();
c.SchemaFilter<SwaggerEnumFilter>();
在哪里
public class SwaggerEnumFilter : ISchemaFilter
{
public void Apply(OpenApiSchema model, SchemaFilterContext context)
{
if (context.Type.IsEnum)
{
var values = Enum.GetValues(context.Type);
var valuesArr = new OpenApiArray();
foreach (var value in values)
{
var item = new OpenApiObject
{
["name"] = new OpenApiString(Enum.GetName(context.Type, value)),
["value"] = new OpenApiString(value.ToString())
};
valuesArr.Add(item);
}
model.Extensions.Add("x-ms-enum", new OpenApiObject
{
["name"] = new OpenApiString(context.Type.Name),
["modelAsString"] = new OpenApiBoolean(true),
["values"] = valuesArr
});
}
}
}
我也有
public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuilder app)
{
var basePath = "/v1";
app.UseSwagger(c =>
{
c.RouteTemplate = "api-docs/{documentName}/swagger.json";
c.SerializeAsV2 = true;
c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
{
swaggerDoc.Servers = new List<OpenApiServer> { new OpenApiServer { Url = $"{httpReq.Scheme}://{httpReq.Host.Value}{basePath}" } };
});
});
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("./v1/swagger.json", "Versioned API v1.0"); //
c.RoutePrefix = "api-docs";
});
return app;
}
和
public class SwaggerEnumParameterFilter : IParameterFilter
{
public void Apply(OpenApiParameter parameter, ParameterFilterContext context)
{
var type = context.ApiParameterDescription.Type;
if (type.IsEnum)
{
var values = Enum.GetValues(type);
var valuesArr = new OpenApiArray();
foreach (var value in values)
{
var item = new OpenApiObject
{
["name"] = new OpenApiString(Enum.GetName(type, value)),
["value"] = new OpenApiString(value.ToString())
};
valuesArr.Add(item);
}
parameter.Extensions.Add("x-ms-enum", new OpenApiObject
{
["name"] = new OpenApiString(type.Name),
["modelAsString"] = new OpenApiBoolean(true),
["values"] = valuesArr
});
}
}
}
和
public static class SwaggerGenOptionsExtensions
{
public static SwaggerGenOptions RegisterEnumSchemas(this SwaggerGenOptions options, Assembly assembly, string enumsNamespace)
{
var enums = from t in assembly.GetTypes()
where t.IsEnum && t.Namespace == enumsNamespace
select t;
foreach (var enumerate in enums)
{
var nullableEnumerate = typeof(Nullable<>).MakeGenericType(enumerate);
MapEnumType(options, enumerate, false);
MapEnumType(options, nullableEnumerate, true);
}
return options;
}
private static void MapEnumType(SwaggerGenOptions options, Type enumerate, bool nullable)
{
var underlyingEnum = nullable ? Nullable.GetUnderlyingType(enumerate) : enumerate;
options.MapType(enumerate, () => new OpenApiSchema
{
Type = "string",
Enum = underlyingEnum.GetEnumNames().Select(name => new OpenApiString(name)).Cast<IOpenApiAny>().ToList(),
Nullable = nullable
});
}
}
[更新]
尝试 BlueJayke 的建议
【问题讨论】:
标签: openapi swashbuckle.aspnetcore