使用Swashbuckle生成YAML Swagger

14

我使用Microsoft的教程在我的Web API项目中获取json文件没有遇到任何问题。

由于某些要求,我希望能够检索yaml文件。但问题是我找不到任何钩子来实现这一点。

有人知道任何解决此问题的变通方法吗?

3个回答

19

V 5.6 支持生成 YAML 文件。使用方法如下:

app.UseSwaggerUI(x => { x.SwaggerEndpoint("/swagger/v1/swagger.yaml", "Zeipt Dashboard API"); });

1
它可以工作,但我必须删除“/swagger/”: app.UseSwaggerUI(x => { x.SwaggerEndpoint("v1/swagger.yaml", "Zeipt Dashboard API"); }); - rgb

7

一种选择是向您的项目添加一个IDocumentFilter,以下是一些示例:

    private class YamlDocumentFilter : IDocumentFilter
    {
        public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
        {
            string file = AppDomain.CurrentDomain.BaseDirectory + "swagger_yaml.txt";
            if (!File.Exists(file))
            {
                var serializer = new YamlSerializer();
                serializer.SerializeToFile(file, swaggerDoc);
            }
        }
    }

...

    private class YamlDocumentFilter : IDocumentFilter
    {
        public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
        {
            string file = AppDomain.CurrentDomain.BaseDirectory + "swagger.yaml";
            if (!File.Exists(file))
            {
                var serializer = new YamlDotNet.Serialization.Serializer();
                using (var writer = new StringWriter())
                {
                    serializer.Serialize(writer, swaggerDoc);
                    var stream = new StreamWriter(file);
                    stream.WriteLine(writer.ToString());
                }
            }
        }
    }

但这取决于你的项目,如果添加一个额外的引用到YamlSerializer或YamlDotNet是可以接受的。


这似乎是正确的方法,但我还无法验证。但这可能是因为我正在部署到服务织物。 - Manny42
啊啊啊!细节中隐藏着魔鬼(Service Fabric)是的,您可能需要修改该示例或尝试使用不同的依赖项…… - Helder Sepulveda
我添加了一个使用YamlSerializer的示例,代码看起来更简单,我验证了它在Azure上可以工作:http://swashbuckletest.azurewebsites.net/swagger_yaml.txt - Helder Sepulveda
1
@HelderSepu,你能提供一个更完整的例子吗?例如库、命名空间、用法等。 - Pawel Gorczynski
@PawełG. 请看这里:https://github.com/heldersepu/Swagger-Net-Test/blob/master/Swagger_Test/App_Start/SwaggerConfig.cs#L378 - Helder Sepulveda

2

根据@HelderSepu提供的想法,我成功地使用Swashbuckle.AspNetCoreYamlDotNet生成了以下YAML,并通过https://bigstickcarpet.com/swagger-parser/www/index.html的验证。

我知道这个解决方案并不完美,但如果有人遇到同样的问题,这可能是一个起点:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.TypeInspectors;

namespace SwaggerPhun
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info
                {
                    Version = "v1",
                    Title = "File Comment API",
                    Description = "A simple example ASP.NET Core Web API",
                    //TermsOfService = "None",
                    Contact = new Contact
                    {
                        Name = "Pawel",
                        Email = "pawel@example.com",
                    },
                    License = new License
                    {
                        Name = "Use under LICX",
                        Url = "https://example.com/license"
                    },
                });
                c.DocumentFilter<YamlDocumentFilter>();

                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
            });

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();

            // Enable middleware to serve generated Swagger as a JSON endpoint.
            app.UseSwagger();

            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
            });
        }

        private class YamlDocumentFilter : IDocumentFilter
        {
            public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
            {
                var builder = new SerializerBuilder();
                builder.WithNamingConvention(new HyphenatedNamingConvention());
                builder.WithTypeInspector(innerInspector => new PropertiesIgnoreTypeInspector(innerInspector));

                var serializer = builder.Build();

                using (var writer = new StringWriter())
                {
                    serializer.Serialize(writer, swaggerDoc);

                    var file = AppDomain.CurrentDomain.BaseDirectory + "swagger_yaml.txt";
                    using (var stream = new StreamWriter(file))
                    {
                        var result = writer.ToString();
                        stream.WriteLine(result.Replace("2.0", "\"2.0\"").Replace("ref:", "$ref:"));
                    }
                }
            }
        }

        private class PropertiesIgnoreTypeInspector : TypeInspectorSkeleton
        {
            private readonly ITypeInspector _typeInspector;

            public PropertiesIgnoreTypeInspector(ITypeInspector typeInspector)
            {
                this._typeInspector = typeInspector;
            }

            public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object container)
            {
                return _typeInspector.GetProperties(type, container).Where(p => p.Name != "extensions" && p.Name != "operation-id");
            }

        }
    }
}

由于我有一点时间,我拿起了代码并制作了一个库存根,模仿了原始的Swashbuckle,但添加了一个yaml端点 - 源代码可以在以下网址找到:https://github.com/pablonautic/Swashbuckle.AspNetCore.Yaml - Pawel Gorczynski
我们能通过这种方法将swagger.json文件保存到本地吗? - Hello

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接