使用 Swashbuckle Aspnetcore 将 `host`、`basePath` 和 `schemes` 添加到 swagger.json
Posted
技术标签:
【中文标题】使用 Swashbuckle Aspnetcore 将 `host`、`basePath` 和 `schemes` 添加到 swagger.json【英文标题】:Add `host`, `basePath` and `schemes` to swagger.json using Swashbuckle Aspnetcore 【发布时间】:2019-05-16 13:23:48 【问题描述】:我正在使用官方文档逐步方法来配置 Swagger UI 并在我的 ASP.NET 核心 API 应用程序中生成 Swagger JSON 文件。
Get started with Swashbuckle and ASP.NET Core
如果我查看生成的 swagger.json 文件 - 它缺少三个重要属性 host
、basePath
和 schemes
请帮助我了解我可以添加哪些代码,以便生成的 swagger.json 将具有以下提到的属性/值。
这是一个理想的 swagger.json - 如果我遵循应用程序中的文档代码,请注意 host
、basePath
和 schemes
值
"swagger": "2.0",
"info":
"version": "v1",
"title": "Demo API Title"
,
"host": "some-url-that-is-hosted-on-azure.azurewebsites.net",
"basePath": "/api",
"schemes": ["https"],
"paths":
"/Account/Test":
"post":
"tags": [
"Admin"
],
"summary": "Account test method - POST",
"operationId": "AccountTest",
"consumes": [],
"produces": [
"text/plain",
"application/json",
"text/json"
],
"parameters": [],
"responses":
"200":
"description": "Success",
"schema":
"type": "boolean"
,
"definitions":
"NumberSearchResult":
"type": "object",
"properties":
"number":
"type": "string"
,
"location":
"type": "string"
,
"securityDefinitions":
"Bearer":
"name": "Authorization",
"in": "header",
"type": "apiKey",
"description": "Authorization. Example: \"Authorization: Bearer token\""
,
"security": [
"Bearer": []
]
【问题讨论】:
【参考方案1】:.netcore 的最新版 Swashbuckle 有一些变化
如果您希望更改 Swashbuckle 中的请求 URL,可能您在 API 网关后面或将自定义域附加到您的 web 应用程序。这样做。
-
创建文档过滤器
public class BasePathDocumentFilter : IDocumentFilter public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) swaggerDoc.Servers = new List<OpenApiServer>() new OpenApiServer() Url = "hxxt://yoursite" ;
-
在您的启动文件中。在
services.AddSwaggerGen()
方法中添加像这样c.DocumentFilter<BasePathDocumentFilter>();
的文档过滤器
【讨论】:
谢谢!这对我帮助很大! 如果我想省略host和scheme怎么办?只需更改基本路径【参考方案2】:您可以实现和注册自己的IDocumentFilter
并在那里设置所需的值。
public class MyDocumentFilter : IDocumentFilter
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
swaggerDoc.Host = "some-url-that-is-hosted-on-azure.azurewebsites.net";
swaggerDoc.BasePath = "/api";
swaggerDoc.Schemes = new List<string> "https" ;
然后通过
注册services.AddSwaggerGen(options =>
options.DocumentFilter<MyDocumentFilter>();
);
【讨论】:
提及:这是针对 V2.x 之前的 OpenAPI【参考方案3】:Swagger / open api 3.0 及更高版本需要服务器对象。看: https://swagger.io/specification/#server-object
像这样在你的启动中设置它
app.UseSwagger(c =>
c.PreSerializeFilters.Add((swagger, httpReq) =>
swagger.Servers = new List<OpenApiServer> new OpenApiServer Url = $"httpReq.Scheme://httpReq.Host.Value" ;
);
);
【讨论】:
【参考方案4】:编辑 (09SEP20) 下面是一些适用于 4.x.x 版本的 asp.netcore Swashbuckle 库的代码 sn-ps
将来我可能会再发一篇文章,以防下面的新版本更简单(在撰写本文时它是版本 5.x.x)
示例 appsettings.Development.json
"Logging":
"LogLevel":
"Default": "Warning",
"Microsoft.Hosting.*": "Information"
,
"Swagger":
"ApiVersion": "localhost",
"ApiName": "v1",
"SwaggerRelativeUrl": "/swagger/v1/swagger.json",
"Title": "SalesforceLocationApi"
示例 C# 代码
namespace My.Api.Settings
public class SwaggerSettings
public string? ApiName get; set;
public string? ApiVersion get; set;
public string? SwaggerRelativeUrl get; set;
public string? Title get; set;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.Reflection;
namespace My.Api
public class Startup
private readonly IConfiguration _configuration;
public Startup(IConfiguration configuration)
_configuration = configuration;
public void ConfigureServices(IServiceCollection services)
services.AddControllers(ConfigureControllers);
services
.AddSingleton<IHttpContextAccessor, HttpContextAccessor>()
.AddSwaggerGen(SetupUpSwaggerGen);
public void Configure(IApplicationBuilder application, IWebHostEnvironment environment, ILoggerFactory loggerFactory, IMapper mapper)
if (environment.IsDevelopment())
application.UseDeveloperExceptionPage();
else
application.UseExceptionHandler();
application
.UseHttpsRedirection()
.UseSwagger()
.UseSwaggerUI(SetUpSwaggerUi)
.UseRouting()
.UseAuthorization()
.UseEndpoints(endpoints => endpoints.MapControllers());
#region Helpers
private void SetupUpSwaggerGen(SwaggerGenOptions options)
var swaggerSettings = _configuration.GetSection("Swagger").Get<SwaggerSettings>();
SwaggerConfig.SetUpSwaggerGen(options, swaggerSettings);
private void SetUpSwaggerUi(SwaggerUIOptions options)
var swaggerSettings = _configuration.GetSection("Swagger").Get<SwaggerSettings>();
SwaggerConfig.SetUpSwaggerUi(options, swaggerSettings.SwaggerRelativeUrl, swaggerSettings.ApiName);
#endregion
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace My.Api
public class SwaggerConfig
internal class SwaggerDocumentFilter : IDocumentFilter
private readonly string _swaggerDocHost;
public SwaggerDocumentFilter(IHttpContextAccessor httpContextAccessor)
var host = httpContextAccessor.HttpContext.Request.Host.Value;
var scheme = httpContextAccessor.HttpContext.Request.Scheme;
_swaggerDocHost = $"scheme://host";
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
swaggerDoc.Servers.Add(new OpenApiServer Url = _swaggerDocHost );
internal static void SetUpSwaggerGen(SwaggerGenOptions options, SwaggerSettings swaggerSettings)
options.DocumentFilter<SwaggerDocumentFilter>();
options.SwaggerDoc(swaggerSettings.ApiName, new OpenApiInfo Title = swaggerSettings.Title, Version = swaggerSettings.ApiVersion );
options.CustomSchemaIds(type => $"type?.Namespace?.Split('.').Last().type?.Name"); //E.g. Acme.Dtos.Gas.Meter.cs --> Gas.Meter
AddXmlComments(options);
internal static void SetUpSwaggerUi(SwaggerUIOptions options, string? swaggerRelativeUrl, string? apiName)
options.SwaggerEndpoint(swaggerRelativeUrl, apiName);
private static void AddXmlComments(SwaggerGenOptions options)
var xmlFile = $"Assembly.GetExecutingAssembly().GetName().Name.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath);
我正在使用 Swashbuckle.AspNetCore Nuget 4.0.1 版
我需要根据应用的托管位置动态添加主机。
这是我的解决方法
-
你的 startup.cs 将 IHttpContextAccessor 添加到你的服务中
-
在您的 swagger 配置中,添加一个 DocFilter,如下所示:
【讨论】:
这对我来说就像一个魅力的解决方案......感谢您发布此答案。我也在使用 4.0.1 版本。 如果你也分享代码而不仅仅是截图会很酷。【参考方案5】:所以在 .net core 3 和 Open Api - Nswag.AspNetCore 版本 13.3.2 nuget。
app.UseOpenApi( configure =>
configure.PostProcess = (doc, httpReq) =>
doc.Servers.Clear(); //... remove local host, added via asp .net core
doc.Servers.Add(new OpenApiServer Url = "[YOUR SERVER URL]" ); //... add server
;
);
来自这个 github 答案:https://github.com/RicoSuter/NSwag/issues/2441#issuecomment-583721522
【讨论】:
以上是关于使用 Swashbuckle Aspnetcore 将 `host`、`basePath` 和 `schemes` 添加到 swagger.json的主要内容,如果未能解决你的问题,请参考以下文章
Swashbuckle.AspNetCore3.0的二次封装与使用
使用Swashbuckle.AspNetCore生成.NetCore WEBAPI的接口文档
TS6053 构建 Swashbuckle.AspNetCore
Swashbuckle.AspNetCore.SwaggerGen 版本 5.6.X 没有 IDataContractResolver
如何使用 Swashbuckle.AspNetCore 在 Swagger 模式中将自定义泛型类型公开为字符串
Azure Functions Swashbuckle:在重建期间无法解析程序集“Microsoft.AspNetCore.Mvc.Core”