[英]ASP.NET Core - Swashbuckle not creating swagger.json file
[英]Add `host`, `basePath` and `schemes` to swagger.json using Swashbuckle Aspnetcore
我正在使用官方文檔逐步方法來配置 Swagger UI 並在我的 ASP.NET 核心 API 應用程序中生成 Swagger JSON 文件。
開始使用 Swashbuckle 和 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": []
}
]
}
最新版本的 Swashbuckle for .netcore 有一些變化
如果你想在 Swashbuckle 中更改請求 URL,也許你在 API 網關后面或者有自定義域附加到你的 webapp。 做這個。
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>();
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}" } };
});
});
您可以實施和注冊您自己的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>();
});
編輯 (09SEP20)以下是一些適用於 asp.netcore Swashbuckle 庫 4.xx 版的代碼片段
將來我可能會發表另一篇文章,以防下面的新版本更直接(在撰寫本文時是 5.xx 版)
示例 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
我需要根據應用程序的托管位置動態添加主機。
這是我的修復
所以在 .net 核心 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.