【发布时间】:2018-08-05 08:38:10
【问题描述】:
我正在使用 Swashbuckle v3.0。
我不确定这是否是一个错误,但多态性并没有按应有的方式工作。我有以下课程:
BasePersonDocumentDto
{
Id,
Number
}
IdentityDto: BasePersonDocumentDto
{
}
PassportDto: BasePersonDocumentDto
{
VisaNumber
}
为了应用继承和多态,我创建了一个模式和文档过滤器。 I followed this answer 下面是我使用的代码。
public class PolymorphismSchemaFilter<T> : ISchemaFilter
{
private List<Type> derivedTypes = new List<Type>() { typeof(IdentityDto), typeof(PassportDto) };
public void Apply(Schema model, SchemaFilterContext context)
{
if (!derivedTypes.Contains(context.SystemType)) return;
var baseSchema = new Schema() { Ref = "#/definitions/" + typeof(T).Name };
var clonedBaseSchema = new Schema
{
Properties = model.Properties,
Type = model.Type,
Required = model.Required
};
model.AllOf = new List<Schema> { baseSchema, clonedBaseSchema };
//Reset properties for they are included in allOf, should be null but code does not handle it
model.Properties = new Dictionary<string, Schema>();
}
}
public class PolymorphismDocumentFilter<T> : IDocumentFilter
{
private List<Type> derivedTypes = new List<Type>() { typeof(IdentityDto), typeof(PassportDto) };
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
{
const string discriminatorName = "discriminator";
var baseSchema = context.SchemaRegistry.Definitions[typeof(T).Name];
//Discriminator property
baseSchema.Discriminator = discriminatorName;
baseSchema.Required = new List<string> { discriminatorName };
if (!baseSchema.Properties.ContainsKey(discriminatorName))
baseSchema.Properties.Add(discriminatorName, new Schema { Type = "string" });
//Register dervied classes
foreach (var item in derivedTypes)
context.SchemaRegistry.GetOrRegister(item);
}
}
生成的定义是:
//This is for BasePersonDocumentDto and for IdentityDto
"BasePersonDocumentDto":{
"required":[
"discriminator"
],
"type":"object",
"properties":{
"number":{
"type":"string"
},
"id":{
"format":"int32",
"type":"integer"
},
"discriminator":{
"type":"string"
}
},
"discriminator":"discriminator"
}
"PassportDto":{
"required":[
"discriminator"
],
"type":"object",
"properties":{
"number":{
"type":"string"
},
"id":{
"format":"int32",
"type":"integer"
},
"visaNumber":{
"type":"string"
},
"discriminator":{
"type":"string"
}
},
"discriminator":"discriminator"
}
现在进行测试,我创建了一个具有 List 属性的 InputDto。我尝试传递以下 JSON,但即使正确传递了鉴别器,两个传递的项目都显示为 BasePersonDocumentDto。这是我传递的 JSON:
{
"documentsDto":[
{
"discriminator":"IdentityDto"
},
{
"visaNumber":"RRXX323TR",
"discriminator":"PassportDto"
}
]
}
【问题讨论】:
-
我已经使用 swagger 有一段时间了,遇到了相当复杂的场景......但从来没有需要
discriminator,_你能告诉我们更多你为什么需要它的细节吗?跨度> -
我想要的只是当派生类型对象作为 Json 传递到后端时,Json 被反序列化为派生类型而不是基类。我假设因为在他们的文档中大摇大摆地声明他们支持继承和多态,这是可能的。我通过实现自定义 JsonConverter 来解决这个问题。我会尽快发布我的解决方案。
-
如果你能在 GitHub 上创建一个最小的例子,我可以看看并给你一些指导,因为听起来你的 web api 实现过于复杂了
标签: c# inheritance polymorphism swagger swashbuckle