簡體   English   中英

使用 Swashbuckle Aspnetcore 將 `host`、`basePath` 和 `schemes` 添加到 swagger.json

[英]Add `host`, `basePath` and `schemes` to swagger.json using Swashbuckle Aspnetcore

我正在使用官方文檔逐步方法來配置 Swagger UI 並在我的 ASP.NET 核心 API 應用程序中生成 Swagger JSON 文件。

開始使用 Swashbuckle 和 ASP.NET Core

如果我查看生成的 swagger.json 文件——它缺少三個重要的屬性hostbasePathschemes

請幫助我了解我可以添加哪些代碼,以便生成的 swagger.json 將具有以下提到的屬性/值。

這是一個理想的 swagger.json - 注意hostbasePathschemes值,如果我遵循我的應用程序中的文檔代碼,這些值會丟失

{
  "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。 做這個。

  1. 創建文檔過濾器
public class BasePathDocumentFilter: IDocumentFilter { public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { swaggerDoc.Servers = new List<OpenApiServer>() { new OpenApiServer() { Url = "hxxt://yoursite" } }; } }
  1. 在您的啟動文件中。在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

我需要根據應用程序的托管位置動態添加主機。

這是我的修復

  1. 我在您的 startup.cs 中將 IHttpContextAccessor 添加到您的服務中

  1. 在您的 swagger 配置中,添加一個 DocFilter,如下所示: 在此處輸入圖像描述 在此處輸入圖像描述

所以在 .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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM