I'm using Swagger/Swashbuckle for an ASP.NET Core 3.1 API.
The Swagger.json looks fine but swaggerUI has a problem with the model references. The "example value" section is really huge, as all model references are beeing loaded.
As you can see in the picture "createdBy" references "personContactyCreatedBy" which then references "straßeNr" and so on. Looks like it also loops back to the "createdBy" as it is used in nearly any model. This issue causes the swaggerUI to be very slow. I tried redoc UI which doesn't even stop loading.
Newtonsoft Self reference loop is disabled. Is there a way to disable those large references/loops in swashbuckle and/or swaggerUI?
swaggerjson: "createdBy": {
"$ref": "#/definitions/User"
},
You can find the fullswagger.json here:Pastebin
Here is a simple workaround like below:
1.Install Swashbuckle.AspNetCore.SwaggerGen 5.0.0-rc5
2.Custom SwaggerExcludeAttribute
:
[AttributeUsage(AttributeTargets.Property)]
public class SwaggerExcludeAttribute : Attribute
{
}
3.Custom 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.Register in 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.Test my Model:
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; }
}