我在C#中Asp.Net的Web API 5.2项目,并生成文档与Swashbuckle。如何在使用Swashbuckle的Swagger API文档中包含子类?
我有一个包含继承像从动物抽象类,狗和猫类,从中获得具有动物属性模型。
Swashbuckle只显示Animal类的模式,所以我尝试使用ISchemaFilter(也是他们的建议),但我无法使其工作,也找不到合适的示例。
任何人都可以帮忙吗?
我在C#中Asp.Net的Web API 5.2项目,并生成文档与Swashbuckle。如何在使用Swashbuckle的Swagger API文档中包含子类?
我有一个包含继承像从动物抽象类,狗和猫类,从中获得具有动物属性模型。
Swashbuckle只显示Animal类的模式,所以我尝试使用ISchemaFilter(也是他们的建议),但我无法使其工作,也找不到合适的示例。
任何人都可以帮忙吗?
看来Swashbuckle没有正确实现多态性,我理解作者关于子类作为参数的观点(如果一个动作需要一个Animal类并且行为不同,如果你用一个狗对象或猫对象调用它,那么你应该有2个不同的动作..)但作为返回类型,我相信返回Animal是正确的,并且对象可以是Dog或Cat类型。
因此,为了描述我的API并根据正确的指导方针产生一个合适的JSON模式(请注意我描述disciminator的方式,如果您有自己的鉴别器,您可能需要更改该部分),我使用文档和模式滤波器如下:
SwaggerDocsConfig configuration;
.....
configuration.DocumentFilter<PolymorphismDocumentFilter<YourBaseClass>>();
configuration.SchemaFilter<PolymorphismSchemaFilter<YourBaseClass>>();
.....
public class PolymorphismSchemaFilter<T> : ISchemaFilter
{
private readonly Lazy<HashSet<Type>> derivedTypes = new Lazy<HashSet<Type>>(Init);
private static HashSet<Type> Init()
{
var abstractType = typeof(T);
var dTypes = abstractType.Assembly
.GetTypes()
.Where(x => abstractType != x && abstractType.IsAssignableFrom(x));
var result = new HashSet<Type>();
foreach (var item in dTypes)
result.Add(item);
return result;
}
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
{
if (!derivedTypes.Value.Contains(type)) return;
var clonedSchema = new Schema
{
properties = schema.properties,
type = schema.type,
required = schema.required
};
//schemaRegistry.Definitions[typeof(T).Name]; does not work correctly in SwashBuckle
var parentSchema = new Schema { @ref = "#/definitions/" + typeof(T).Name };
schema.allOf = new List<Schema> { parentSchema, clonedSchema };
//reset properties for they are included in allOf, should be null but code does not handle it
schema.properties = new Dictionary<string, Schema>();
}
}
public class PolymorphismDocumentFilter<T> : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, System.Web.Http.Description.IApiExplorer apiExplorer)
{
RegisterSubClasses(schemaRegistry, typeof(T));
}
private static void RegisterSubClasses(SchemaRegistry schemaRegistry, Type abstractType)
{
const string discriminatorName = "discriminator";
var parentSchema = schemaRegistry.Definitions[SchemaIdProvider.GetSchemaId(abstractType)];
//set up a discriminator property (it must be required)
parentSchema.discriminator = discriminatorName;
parentSchema.required = new List<string> { discriminatorName };
if (!parentSchema.properties.ContainsKey(discriminatorName))
parentSchema.properties.Add(discriminatorName, new Schema { type = "string" });
//register all subclasses
var derivedTypes = abstractType.Assembly
.GetTypes()
.Where(x => abstractType != x && abstractType.IsAssignableFrom(x));
foreach (var item in derivedTypes)
schemaRegistry.GetOrRegister(item);
}
}
什么以前的代码实现指定here,在节段“模式与多态支持它基本上会产生类似以下内容:
{
"definitions": {
"Pet": {
"type": "object",
"discriminator": "petType",
"properties": {
"name": {
"type": "string"
},
"petType": {
"type": "string"
}
},
"required": [
"name",
"petType"
]
},
"Cat": {
"description": "A representation of a cat",
"allOf": [
{
"$ref": "#/definitions/Pet"
},
{
"type": "object",
"properties": {
"huntingSkill": {
"type": "string",
"description": "The measured skill for hunting",
"default": "lazy",
"enum": [
"clueless",
"lazy",
"adventurous",
"aggressive"
]
}
},
"required": [
"huntingSkill"
]
}
]
},
"Dog": {
"description": "A representation of a dog",
"allOf": [
{
"$ref": "#/definitions/Pet"
},
{
"type": "object",
"properties": {
"packSize": {
"type": "integer",
"format": "int32",
"description": "the size of the pack the dog is from",
"default": 0,
"minimum": 0
}
},
"required": [
"packSize"
]
}
]
}
}
}
'SchemaIdProvider'必须是你自己的类?我想通了,你可以通过添加一个'使用Swashbuckle.Swagger',然后改变该行的代码为'无功parentSchema = schemaRegistry.Definitions [abstractType.FriendlyId]使用扬鞭的默认约定;' – wags1999
是的,这是我的课。我需要它,因为我们也有schemaId委托:configuration.SchemaId(SchemaIdProvider.GetSchemaId); –
@PaoloVigori:我用的是上Swashbuckle.AspNetCore的'PolymorphismDocumentFilter'被称为和鉴别设置代码,而不是在产生招摇定义。 “allOf”条目在那里。有任何想法吗? – Tseng
任何运气搞清楚了这出? – Craig
还没有,但我将不得不再次关注它。请让我知道,如果你发现任何东西 –