我使用
Microsoft 的教程在我的 Web API 项目中获取
json
文件没有任何问题。
由于某些要求,我希望能够检索
yaml
文件。但问题是我找不到任何钩子来实现这一点。
有人知道这个问题的任何解决方法吗?
V 5.6支持生成YAML文件。使用方法:
app.UseSwaggerUI(x => { x.SwaggerEndpoint("/swagger/v1/swagger.yaml", "Zeipt Dashboard API"); });
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 的额外引用。
Swashbuckle.AspNetCore与YamlDotNet一起生成以下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 = "[email protected]",
},
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");
}
}
}
}
UseSwagger()
函数自动同时支持json和yaml(请参阅swashbuckle源中间件类),只需导航到json url并手动将.json更改为.yaml即可。如果情况并非如此,那么您可能已经覆盖了
SwaggerOption.RouteTemplate
。在这种情况下,只需确保您覆盖的内容以
.{json|yaml}
而不是
.json
结尾。