【问题标题】:Add `host`, `basePath` and `schemes` to swagger.json using Swashbuckle Aspnetcore使用 Swashbuckle Aspnetcore 将 `host`、`basePath` 和 `schemes` 添加到 swagger.json
【发布时间】:2019-05-16 13:23:48
【问题描述】:

我正在使用官方文档逐步方法来配置 Swagger UI 并在我的 ASP.NET 核心 API 应用程序中生成 Swagger JSON 文件。

Get started with Swashbuckle and 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": []
    }
  ]
}

【问题讨论】:

    标签: c# json asp.net-core swagger swashbuckle


    【解决方案1】:

    .netcore 的最新版 Swashbuckle 有一些变化

    如果您希望更改 Swashbuckle 中的请求 URL,可能您在 API 网关后面或将自定义域附加到您的 web 应用程序。这样做。

    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&lt;BasePathDocumentFilter&gt;(); 的文档过滤器

    【讨论】:

    • 谢谢!这对我帮助很大!
    • 如果我想省略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 版

      我需要根据应用的托管位置动态添加主机。

      这是我的解决方法

      1. 你的 startup.cs 将 IHttpContextAccessor 添加到你的服务中

      1. 在您的 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-16
        • 1970-01-01
        • 1970-01-01
        • 2021-07-14
        • 1970-01-01
        • 1970-01-01
        • 2020-12-02
        相关资源
        最近更新 更多