How do I include subclasses in Swagger API documentation/ OpenAPI specification using Swashbuckle?

前端 未结 5 742
情书的邮戳
情书的邮戳 2020-11-30 00:44

I have an Asp.Net web API 5.2 project in c# and generating documentation with Swashbuckle.

I have model that contain inheritance something like having an Animal prop

5条回答
  •  -上瘾入骨i
    2020-11-30 01:16

    To follow on from Paulo's great answer, if you're using Swagger 2.0, you'll need to modify the classes as shown:

    public class PolymorphismSchemaFilter : ISchemaFilter
    {
        private readonly Lazy> derivedTypes = new Lazy>(Init);
    
        private static HashSet Init()
        {
            var abstractType = typeof(T);
            var dTypes = abstractType.Assembly
                                     .GetTypes()
                                     .Where(x => abstractType != x && abstractType.IsAssignableFrom(x));
    
            var result = new HashSet();
    
            foreach (var item in dTypes)
                result.Add(item);
    
            return result;
        }
    
        public void Apply(Schema model, SchemaFilterContext context)
        {
            if (!derivedTypes.Value.Contains(context.SystemType)) return;
    
            var clonedSchema = new Schema
            {
                Properties = model.Properties,
                Type = model.Type,
                Required = model.Required
            };
    
            //schemaRegistry.Definitions[typeof(T).Name]; does not work correctly in SwashBuckle
            var parentSchema = new Schema { Ref = "#/definitions/" + typeof(T).Name };
    
            model.AllOf = new List { parentSchema, clonedSchema };
    
            //reset properties for they are included in allOf, should be null but code does not handle it
            model.Properties = new Dictionary();
        }
    }
    
    public class PolymorphismDocumentFilter : IDocumentFilter
    {
        private static void RegisterSubClasses(ISchemaRegistry schemaRegistry, Type abstractType)
        {
            const string discriminatorName = "discriminator";
    
            var parentSchema = schemaRegistry.Definitions[abstractType.Name];
    
            //set up a discriminator property (it must be required)
            parentSchema.Discriminator = discriminatorName;
            parentSchema.Required = new List { 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);
        }
    
        public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
        {
            RegisterSubClasses(context.SchemaRegistry, typeof(T));
        }
    }
    

提交回复
热议问题