【问题标题】:Swagger / Swashbuckle reference loop problemSwagger / Swashbuckle 参考循环问题
【发布时间】:2020-01-03 15:22:03
【问题描述】:

我将 Swagger/Swashbuckle 用于 ASP.NET Core 3.1 API。

Swagger.json 看起来不错,但 swaggerUI 的模型引用有问题。 “示例值”部分非常庞大,因为正在加载所有模型引用。

SwaggerUI

正如您在图片中看到的那样,“createdBy”引用“personContactyCreatedBy”,然后引用“straßeNr”等等。 看起来它也循环回“createdBy”,因为它几乎用于任何模型。 此问题导致 swaggerUI 非常慢。我尝试了重做 UI,它甚至不会停止加载。

Newtonsoft 自参考循环被禁用。 有没有办法在 swashbuckle 和/或 swaggerUI 中禁用那些大型引用/循环?

swaggerjson:"createdBy": { "$ref": "#/definitions/User" },

你可以在这里找到fullswagger.json:Pastebin

【问题讨论】:

    标签: asp.net-core swagger swagger-ui swashbuckle


    【解决方案1】:

    这是一个简单的解决方法,如下所示:

    1.安装Swashbuckle.AspNetCore.SwaggerGen 5.0.0-rc5

    2.自定义SwaggerExcludeAttribute:

    [AttributeUsage(AttributeTargets.Property)]
    public class SwaggerExcludeAttribute : Attribute 
    { 
    }
    

    3.自定义SwaggerExcludeFilter:

    public class SwaggerExcludeFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (schema?.Properties == null)
            {
                return;
            }
    
            var excludedProperties =
                context.Type.GetProperties().Where(
                    t => t.GetCustomAttribute<SwaggerExcludeAttribute>() != null);
    
            foreach (var excludedProperty in excludedProperties)
            {
                var propertyToRemove =
                    schema.Properties.Keys.SingleOrDefault(
                        x => x.ToLower() == excludedProperty.Name.ToLower());
    
                if (propertyToRemove != null)
                {
                    schema.Properties.Remove(propertyToRemove);
                }
            }
        }
    }
    

    4.在Startup.cs中注册:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
            c.SchemaFilter<SwaggerExcludeFilter>();
        });
    
        services.AddDbContext<WebApi3_1Context>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("WebApi3_1Context")));            
    }
    
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseHttpsRedirection();
    
        app.UseRouting();
    
        app.UseAuthorization();
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
    

    5.测试我的模型:

    public class Test
    {
        public int Id { get; set; }
        public string Name { get; set; }
        [SwaggerExclude]
        public Item Item { get; set; }
    }
    public class Item
    {
        public int Id { get; set; }
        public string ItemName { get; set; }
        public List<Person> Person { get; set; }
    }
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    

    【讨论】:

    • 抱歉回复晚了。是的,完美。非常感谢
    【解决方案2】:

    您可以将[JsonIgnore] 添加到您不希望在模型中出现的属性中。这可能会帮助您减少这种循环。 或者,您可以尝试通过使用来限制模型的深度

    app.UseSwaggerUI(c =>
    {
        c.DefaultModelRendering(ModelRendering.Model);
        c.DefaultModelExpandDepth(1); 
    });
    

    【讨论】:

    • 谢谢。我已经试过了。这将减少模型的默认扩展,但不会减少控制器中的“示例值”。添加 JsonIgnore 时,控制器不再返回内容(我需要)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    相关资源
    最近更新 更多