【问题标题】:Exposing a Schema that is not exposed by default with Swagger使用 Swagger 公开默认未公开的 Schema
【发布时间】:2021-05-27 15:42:43
【问题描述】:

默认情况下,Swagger 会公开任何由公开的控制器(API 端点)使用的架构。如果控制器使用模式(类),如何公开它?

例如,Swagger 显示以下 Schema:

但是,Song Schema(下)需要暴露。它没有被公开,因为它没有被控制器(API 端点)使用。

using System;
namespace ExampleNamespace
{
    public class Song
    {
        [Key][Required]
        public int SongID { get; set; }
        [Required]
        public string SongName { get; set; }
        public string SongDescription { get; set; }
        public int SongLength { get; set; } //seconds
        [Required]
        public int AlbumID { get; set; }
    }
}

如何做到这一点?

【问题讨论】:

    标签: c# swagger swagger-ui swashbuckle


    【解决方案1】:

    您可以使用 DocumentFilter 添加架构

    public class AddSongSchemaDocumentFilter : IDocumentFilter
    {
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            var songSchema = new OpenApiSchema {...};
            songSchema.Properties.Add(new KeyValuePair<string, OpenApiSchema>("songName", new OpenApiSchema { ... }));
            ...
    
            context.SchemaRepository.Schemas.Add("Song", songSchema);
        }
    }
    

    OpenApiSchema 类用于歌曲模式本身和属性模式。此类型包含许多您可以设置的文档相关属性,例如Description

    你像这样注册AddSongSchemaDocumentFilter

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwaggerGen(options =>
        {
            options.DocumentFilter<AddSongSchemaDocumentFilter>();
        });
    }
    

    如果有很多属性,这可能会有点乏味。使用反射,您可以迭代属性,甚至反射附加到这些属性的关联属性。

    var songSchema = new OpenApiSchema() { };
    var song = new Song();
    var properties = typeof(Song).GetProperties();
    
    foreach (var p in properties)
        songSchema.Properties.Add(new KeyValuePair<string, OpenApiSchema(
            p.Name,
            new OpenApiSchema()
            {
                Type = p.PropertyType.ToString(),
                Description = // get [Description] attribute from p,
                // ... etc. for other metadata such as an example if desired
            }));
    
    context.SchemaRepository.Schemas.Add("Song", songSchema);
    

    Full Swashbuckle documentation.

    【讨论】:

    • 太棒了!我能够添加架构!有没有办法在不单独指定所有属性的情况下添加 Song 类(假设我想公开 Class 上的所有属性)?
    • @CardiDeMonacoJr你可以使用反射来做到这一点。另一种方法可能是使用标准 .NET XML 文档 cmets 记录您的 Song 类,然后使用 SwaggerGenOptions.IncludeXmlComments 指示 Swashbuckle 加载这些类型。如果这些工作,我可以更新答案...
    • 添加标准 .NET XML doc cmets 似乎不会加载任何其他内容。例如,我在添加 cmets 后在歌曲上添加了 songName 属性,但我没有看到任何其他内容。反射肯定是一条有趣的路线。我可以尝试一下,因为最终会有数百个属性。如果反射有效,我将重新审视这个问题并分享我的代码。感谢您的帮助!
    • @CardiDeMonacoJr 确定!我不确定 XML 路由是否是附加的。我认为所有“正常”模式都是根据端点签名和从这些签名中的类型引用的所有类型确定的。如果它是附加的会很好......也许是一个很好的功能请求。
    • @CardiDeMonacoJr 我已将您的评论包含在内。请注意,您可以通过反映添加到 Song 的属性(例如 [Description("Name of the song")] string SongName { get; set; })的属性来使架构定义更加丰富
    猜你喜欢
    • 2013-01-17
    • 2019-08-24
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-28
    • 2019-02-04
    • 2019-09-13
    相关资源
    最近更新 更多