我在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
還沒有,但我將不得不再次關注它。請讓我知道,如果你發現任何東西 –