是否可以在 ASP .NET Core 中使用 Swashbuckle 在 Swagger 2.0 和 Open API 3 格式中公开相同的 Swagger JSON?
Posted
技术标签:
【中文标题】是否可以在 ASP .NET Core 中使用 Swashbuckle 在 Swagger 2.0 和 Open API 3 格式中公开相同的 Swagger JSON?【英文标题】:Is it possible to expose the same Swagger JSON in both Swagger 2.0 and Open API 3 formats with Swashbuckle in ASP .NET Core? 【发布时间】:2021-07-27 14:02:54 【问题描述】:我们有一个仅适用于 Swagger 2.0 JSON 格式的旧版应用程序。对于我们希望使用 Open API 格式的其他所有内容。
Swashbuckle .NET Core 有什么方法可以在不同的 URL 下以不同格式公开 JSON?看起来UseSwagger
方法选项中的SerializeAsV2
属性对于所有端点都是全局的。
基本上我希望以下端点包含不同格式的相同 API 数据。
/swagger/v1/openapi/swagger.json
/swagger/v1/swagger2/swagger.json
【问题讨论】:
【参考方案1】:另一种方法是拆分请求管道:
// serve v3 from /swagger/v1/swagger.json
app.UseSwagger(o => o.RouteTemplate = "swagger/documentName/swagger.json");
// serve v2 from /swagger2/v1/swagger.json
app.Map("/swagger2", swaggerApp =>
swaggerApp.UseSwagger(options =>
// note the dropped prefix "swagger/"
options.RouteTemplate = "documentName/swagger.json";
options.SerializeAsV2 = true;
)
);
【讨论】:
这真的很优雅,效果很好。谢谢!【参考方案2】:您可以将 OpenAPI 文档序列化为 V2 并自行提供。以SwaggerMiddleware
为参考:
第一次注册SwaggerGenerator
:
services.AddTransient<SwaggerGenerator>();
然后注入SwaggerGenerator
并构建文档。从端点或控制器提供它。您可以将版本作为路径参数来决定提供哪个版本。
app.UseEndpoints(e =>
// ...
e.MapGet("/swagger/documentName/swagger.version.json", context =>
var documentName = context.Request.RouteValues.GetValueOrDefault("documentName", null) as string;
var version = context.Request.RouteValues.GetValueOrDefault("version", null) as string;
if (documentName is null || version is null)
context.Response.StatusCode = StatusCodes.Status400BadRequest;
return Task.CompletedTask;
// inject SwaggerGenerator
var swaggerGenerator = context.RequestServices.GetRequiredService<SwaggerGenerator>();
var doc = swaggerGenerator.GetSwagger(documentName);
// serialize the document as json
using var writer = new StringWriter(CultureInfo.InvariantCulture);
var serializer = new OpenApiJsonWriter(writer);
if (version == "v2")
doc.SerializeAsV2(serializer);
else
doc.SerializeAsV3(serializer);
var json = writer.ToString();
// serve it as json
context.Response.ContentType = MediaTypeNames.Application.Json;
return context.Response.WriteAsync(json, new UTF8Encoding(false));
);
);
当您访问/swagger/v1/openapi.v2.json
时,您将获得序列化为 v2 的 OpenAPI 文档。
"swagger": "2.0",
"info":
"title": "ApiPlayground",
"version": "1.0"
,
"paths": ...
而/swagger/v1/openapi.v3.json
会给您序列化为 v3 的文档:
"openapi": "3.0.1",
"info":
"title": "ApiPlayground",
"version": "1.0"
,
"paths": ... ,
"components": ...
【讨论】:
我还需要调用UseSwagger()
方法吗?感谢您提供详细的示例。
不,它可以保留,也可以完全删除。但是您可能需要更新SwaggerUI
中间件配置。 app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.v2.json", "ApiPlayground v1"));
以上是关于是否可以在 ASP .NET Core 中使用 Swashbuckle 在 Swagger 2.0 和 Open API 3 格式中公开相同的 Swagger JSON?的主要内容,如果未能解决你的问题,请参考以下文章
如何在ASP.NET Core 中使用IHttpClientFactory
ASP.NET Core 2.0 - Windows Auth 与 LDAP 组到角色
在 ASP.NET Core 2.1 中使用 cookie [重复]