swashbuckleopenapi3为动态生成的模型类编写示例和描述



我的模型属性定义来自一个json文件,因此使用反射来编写要在结果swagger页面上的schema下显示的类。

foreach (var model in Models)
{
if (!ModelTypes.ContainsKey(model.Key))
{
anyNonCompiledModel = true;
BuildModelCodeClass(modelComponentBuilder, model.Value);//Build model classes
}
}
BuildModelCodeEnd(modelComponentBuilder);
if (anyNonCompiledModel)
{
CSharpCompiler compiler = new CSharpCompiler();
compiler.AddReference(typeof(object));
compiler.AddReference(typeof(ResourceFactory));
compiler.AddReference(typeof(System.Runtime.Serialization.DataContractResolver));
compiler.AddReference(typeof(System.Runtime.Serialization.DataContractAttribute));
var types = compiler.Compiler(modelComponentBuilder.ToString()); //write model classes
foreach (var type in types)
{
ModelTypes.Add(type.Name, type);
}
}
public void BuildModelCodeClass(StringBuilder modelComponentBuilder, MetadataModelEntity model)
{

modelComponentBuilder.AppendLine($"public class {model.Name} {{");
foreach (var p in model.Data.Properties)
{
if (p.Obsoleted) continue;
if (p.Type.Type == "array")
{
modelComponentBuilder.AppendLine($" public {p.Type.ArrayType.ObjectName}[] {p.Name} {{get;set;}}");
}
else
{
//primitive types
modelComponentBuilder.AppendLine($" public {p.Type.ObjectName} {p.Name} {{get;set;}}");
}
}
modelComponentBuilder.AppendLine(
@"}
");

}

如果我提供如下描述和示例(在BuildModelCodeClass中,在循环中(,那么示例和描述就会为我显示

if (!string.IsNullOrWhiteSpace((string)p.Example))
{
modelComponentBuilder.AppendLine($" ///<example>{p.Example}</example>");
}
if (!string.IsNullOrWhiteSpace((string)p.Description))
{
modelComponentBuilder.AppendLine($" ///<description>{p.Description}</description>");
}

然而,我不想做以上的事情。

  1. 我想通过开放api而不是通过C#编译器来编写我的模型,这可能吗?

  2. 我想通过模式展示示例和描述(可能在路径下(。我该怎么做?Context提供了我的模型信息,我可以在这里与之交互。

    公共类SwaggerDocumentFilter:IDocumentFilter{SwaggerDocument _swagerDocument;公共SwaggerDocumentFilter(对象apiConfigure({_swaggerDocument=((ApiGatewayConfiguration(apiConfigure(.swaggerDocument;}

    public void Apply(OpenApiDocument document, DocumentFilterContext context)
    {
    if (document.Info.Extensions == null || !document.Info.Extensions.ContainsKey(SwaggerEndpoint.ExtensionDocName)) return;
    var openIdString = document.Info.Extensions[SwaggerEndpoint.ExtensionDocName] as OpenApiString;
    if (openIdString == null) return;
    var docName = openIdString.Value;
    SwaggerEndpoint endpoint = _swaggerDocument.SwaggerEndpoints.SingleOrDefault(x => x.Name == docName);
    if (endpoint == null) return;
    
    //Add server objects
    document.Servers = endpoint.ServerObjects;
    //Add Tags objects
    document.Tags = endpoint.Tags;
    //Set swagger paths objects
    var pathsObjects = _swaggerDocument.GetPathsObject(docName, context);
    if (pathsObjects.IsValid())
    {
    pathsObjects.ToList().ForEach(
    item => document.Paths.Add(item.Key, item.Value)
    );
    }
    //Add Schema components
    //Add Example/Examples
    }
    }
    

以下帮助https://github.com/domaindrivendev/Swashbuckle.WebApi/issues/162

添加SchemaExamples.cs

public class AddSchemaExamples : ISchemaFilter
{
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
{
if (type == typeof(Product))
{
schema.example = new Product
{
Id = 123,
Type = ProductType.Book,
Description = "Treasure Island",
UnitPrice = 10.0M
};
}
}
}

SwaggerConfig.cs

httpConfig 
.EnableSwagger(c =>
{
c.SchemaFilter<AddSchemaExamples>()
});

我对Apply-since模型的实现是动态

if (model != null)
{
schema.Description = model.Description;
foreach (var p in schema.Properties)
{
var mp = model.Data.Properties.SingleOrDefault(x => x.Name == p.Key);
if (mp != null)
{
if (!string.IsNullOrWhiteSpace(mp.Description))
{
p.Value.Description = mp.Description;
}
if(!string.IsNullOrWhiteSpace(mp.Example))
{
p.Value.Example =
new Microsoft.OpenApi.Any.OpenApiString(mp.Example.ToString());
}
}
}
}

最新更新