首页 > 解决方案 > Swagger / Swashbuckle 参考循环问题

问题描述

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

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

招摇UI

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

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

大摇大摆的json:"createdBy": { "$ref": "#/definitions/User" },

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

标签: asp.net-coreswaggerswagger-uiswashbuckle

解决方案


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

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; }
}

推荐阅读