如何使用 Swashbuckle 的 SwaggerUI 显示静态 swagger.json 文件而不是 SwaggerGen 的动态创建的定义?

Posted

技术标签:

【中文标题】如何使用 Swashbuckle 的 SwaggerUI 显示静态 swagger.json 文件而不是 SwaggerGen 的动态创建的定义?【英文标题】:How can I use Swashbuckle's SwaggerUI to display a static swagger.json file instead of SwaggerGen's dynamically created definiton? 【发布时间】:2019-11-27 15:53:52 【问题描述】:

我有一个面向 .NET Core 2.1 框架的 ASP.NET Core MVC 应用程序。此应用程序提供 RESTful API 并返回 JSON 数据。

使用SwaggerHub 中基于 Web 的交互式 SwaggerGen,我创建了一个 API 定义文档,并将其以 JSON 格式保存为“swagger.json”在我的 ASP.NET Core MVC 应用程序项目的一个文件夹中。

由于我已经定义了 API,我不需要在我的应用程序中运行 SwaggerGen。我只想让 SwaggerUI 显示我创建的静态“swagger.json”文件。

我已经阅读了 Swashbuckle 文档以及几个“如何开始使用 Swashbuckle”教程,但它们都假设 SwaggerGen 将用于从我的 API 动态创建 Swagger API 文档。

我已将“Swashbuckle.AspNetCore”NuGet 包添加到我的应用程序的依赖项中。

在我的应用程序 Startup.cs 类的 Configure() 方法中,我添加了 UseSwaggerUI 指令:

app.UseSwaggerUI(c => 
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");

当我在 Visual Studio 中运行我的应用程序时,我得到一个正常的空白页。

根据 Swashbuckle 文档,假设已添加 SwaggerGen 并动态生成 API 定义(文件?),则 SwaggerUI 格式的 API 文档应在相对“/swagger”路径中可用。

获取“/swagger”相对路径会产生“400 Bad Request”错误。

问:SwaggerGen 会生成自己的“swagger.json”文件吗?如果会,它将在哪里创建这个文件?

问:有没有办法告诉 SwaggerUI 在哪里可以找到并显示我手动创建的“swagger.json”API 定义文件?

谢谢!

【问题讨论】:

你为什么要这样做?重点是让 swagger.json 自动生成,因此它与您对 API 所做的更改保持同步。如果您要使用静态 swagger.json,那么您还需要记住在进行更改时重新生成它,我可以向您保证,您不会记得这样做。这是性能问题吗? JSON 仅在被请求时生成,这意味着它只会影响 API 文档,而不是整个站点。即便如此,对 gen. 嗨,@ChrisPratt。 Swagger(实际上是 SmartBear)有许多 API 优先工具,包括可以从 API 定义生成应用程序源代码的工具。如果我们从 API 定义生成代码,那么我们已经翻转了“操作顺序”并将优先级从代码更改为设计。这也保证了对 API 定义的更改永远不会被遗忘。它们是首先制作的,并且是源代码中的结果。 设计优先是一种很好的方法。但是@ChrisPratt 让我们认为Why would you want to do this? Swashbuckle 是修理瑞士手表的大锤。为什么用那个?那是“简单”的 NuGet 包选项吗? @DougWilson 我的意思是 Swagger UI 只是一个 SPA。如果您不将它与 Gen 结合使用,那么它根本不需要成为您项目的一部分。把它扔到某个地方,然后给它你的静态 JSON 文件。完成。 @ChrisPratt,我们的用例是微服务,每个都有自己的 API 定义。它们旨在在 Docker 容器中独立运行,因此自包含和自给自足很重要。我不想仅仅为了显示 SwaggerUi 文档而包含 Node 服务器,特别是因为 Swashbuckle 声称可以在 ASP.NET Core MVC 项目中执行此操作。 【参考方案1】:

您可以使用url 参数告诉任何 Swagger-UI 在哪里找到文件:

http://petstore.swagger.io/?url=https://raw.githubusercontent.com/heldersepu/hs-scripts/master/swagger/swagger.json

http://swagger-net-test.azurewebsites.net/swagger/ui/index?url=https://petstore.swagger.io/v2/swagger.json

这就是您所需要的,如果您已经使用 SwaggerHub 生成了定义,则可以使用任何 Swagger-UI 而无需安装 swashbuckle。


如果您想自己托管 Swagger-UI,只需将 dist 文件夹复制到您的网络服务器:https://github.com/swagger-api/swagger-ui/tree/master/dist

【讨论】:

谢谢,Helder,但在这种情况下,另一个服务器(位于 githubusercontent.com)被用于提供 Swagger 文档。我正在寻找一种方法让我的 ASP.NET Core MVC 应用程序为其提供服务。 @DougWilson 您正在为您的项目提供 Swagger 文档(静态 'swagger.json' 文件),对吗?只需将其传递给任何 swagger-ui http://petstore.swagger.io/?URL=https://foo.bar/path/to/your/swagger.json 托管我自己的 swagger-ui 副本以服务于我的静态 swagger.json API 定义文件是一个很好的建议。谢谢你,赫尔德! @RobMcCabe 我认为 UI 现在区分大小写,我更正了提供的示例,表明它确实有效【参考方案2】:

    在本地机器上,做一个小节点项目,安装swagger-ui-dist

    将安装的文件从 node_modules/swagger-ui-dist 复制到托管 swagger 站点的网络服务器

    将生成的 swagger.json 复制到网络服务器的同一文件夹中

    编辑 index.html 并将 url 添加到您的 json 中,例如。 '/swagger.json'

    完成

来源

https://yanhan.github.io/posts/2017-11-26-using-swagger-ui-with-any-codebase/

【讨论】:

【参考方案3】:

我想使用核心网站将外部 EDMX 转换为 OpenAPI 格式然后显示.. 所以我想通了

我能够使用 Microsoft's OData sample 并将静态 JSON 提供给 Swasbhuckle 驱动的 SwaggerUI,如下所示:

    在您的项目中创建一个目录,例如generatedjson 将您的 json (open api doc) 放入上述文件夹中 允许从此文件夹提供静态文件 在 UseSwaggerUI 中,我添加了一个新的 SwaggerUI 端点
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    if (env.IsDevelopment())
    
        app.UseDeveloperExceptionPage();
    

    app.UseSwagger();
    app.UseSwaggerUI(c =>
    
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "OData 8.x OpenAPI");
        c.SwaggerEndpoint("/generatedjson/swagger.json", "SAP Business One");
    );

    app.UseRouting();

    // Test middleware
    app.Use(next => context =>
    
        var endpoint = context.GetEndpoint();
        if (endpoint == null)
        
            return next(context);
        

        return next(context);
    );

    //app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    
        endpoints.MapControllers();
    );

    app.UseStaticFiles(new StaticFileOptions()
    
        FileProvider = new PhysicalFileProvider(
            System.IO.Path.Combine(Directory.GetCurrentDirectory(), @"generatedjson")),
        RequestPath = new PathString("/generatedjson")
    );

FWIW - 如果这就是您网站的全部功能

那么您可以随意禁用ConfigureServices中的EDM生成服务

           services.AddControllers();
                //.AddOData(opt => opt.Count().Filter().Expand().Select().OrderBy().SetMaxTop(5)
                    //.AddRouteComponents(model0)
                    //.AddRouteComponents("v1", model1)
                    //.AddRouteComponents("v2data", model2, services => services.AddSingleton<ODataBatchHandler, DefaultODataBatchHandler>())
                    //.AddRouteComponents("v3", model3)
                    //.Conventions.Add(new MyConvention())
                

            services.AddSwaggerGen();

【讨论】:

以上是关于如何使用 Swashbuckle 的 SwaggerUI 显示静态 swagger.json 文件而不是 SwaggerGen 的动态创建的定义?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swashbuckle 从关于 WebAPI 的 Swagger 文档中省略方法

如何在使用 swashbuckle 的 swagger 的发布请求描述中隐藏属性?

Swashbuckle.AspNet.Core:Swagger UI 显示空白页面 - 如何修复?

如何使用 Swashbuckle 的 SwaggerUI 显示静态 swagger.json 文件而不是 SwaggerGen 的动态创建的定义?

Swashbuckle 承载授权

如何使用 Swashbuckle.AspNetCore 在 Swagger 模式中将自定义泛型类型公开为字符串