aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

The depth of the generated JSON schema exceeds the JsonSerializerOptions.MaxDepth setting

Open niltor opened this issue 3 months ago • 5 comments

Is there an existing issue for this?

  • [x] I have searched the existing issues

Describe the bug

After some investigation, I provided the simplest reproducible content possible, a new asp.net core project, a simple api, and some class models.

When a class, such as User in the example, has more than or equal to 8 relate classes, an error of The depth of the generated JSON schema exceeds the JsonSerializerOptions.MaxDepth setting will be reported. When there are less than 8, no error will be reported.

IssueController.cs


[ApiController]
[Route("[controller]")]
public class IssueController : ControllerBase
{

    [HttpGet("test-issue")]
    public ActionResult<User> TestIssue()
    {
        var user = new User() { Name = "User" };
        return user;
    }
}

public class User
{
    public Guid Id { get; set; }
    public required string Name { get; set; }
    public ICollection<Order> Orders { get; set; } = [];
    public ICollection<Product> Products { get; set; } = [];
    public ICollection<Course> Courses { get; set; } = [];
    public ICollection<Car> Cars { get; set; } = [];
    public ICollection<Hourse> Hourses { get; set; } = [];
    public ICollection<Plan> Plans { get; set; } = [];
    public ICollection<Right> Rights { get; set; } = [];
    public ICollection<Salary> Salarys { get; set; } = [];
}

public class Order { public User? User { get; set; } }
public class Product { public User? User { get; set; } }
public class Course { public User? User { get; set; } }
public class Car { public User? User { get; set; } }
public class Hourse { public User? User { get; set; } }
public class Plan { public User? User { get; set; } }
public class Right { public User? User { get; set; } }
public class Salary { public User? User { get; set; } }

In actual projects, there are more than 8 related entities like User, and dozens of them are possible.

Expected Behavior

Swashbuckle will not throw this exception.

Maybe support Json config like:

builder.Services.AddJsonOptions(options =>
{
    options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
});

Steps To Reproduce

I have provided a reproducible sample code repository

The Issue example

Exceptions (if any)

got error: The depth of the generated JSON schema exceeds the JsonSerializerOptions.MaxDepth setting

.NET Version

.NET9 and .NET 10

Anything else?

No response

niltor avatar Sep 28 '25 09:09 niltor

The JsonSchemaExporter does not create seperate schemas for each object but it nests them and tries to create references as part of the schema it self. I think this can be solved if the JsonSchemaExporter allows exporting schemas as seperate schemas (like OpenApi components) based on CreateSchemaReferenceId. Currently this problem is super hard to solve, I played around improving this area but it involves big changes. I hope that I can help on this for .NET 11.

The only workarounds I see are:

  • Increase the MaxDepth setting
  • Change your model (what a greate workaround /s)
  • Exclude the operation with OpenApiOptions.ShouldInclude
  • Exclude the operation with the ExcludeFromDescriptionAttribute

Label should be feature-openapi.

desjoerd avatar Sep 30 '25 07:09 desjoerd

@desjoerd

  • Couldn't find the option for setting MaxDepth.
  • In the actual project, I did indeed redefine all the interfaces that previously directly returned to entities using Dto. This took me two days to search for and modify dozens of interfaces and models.
  • Exclude or [JsonIgnore] do not match my case.

In any case, a program that can run normally loses the ability of openapi doc due to the use of OpenApi, which forces me to spend a lot of time modifying the program itself. This is really rather embarrassing.

This issue should be solved ASAP.

niltor avatar Sep 30 '25 08:09 niltor

You can configure the MaxDepth on the HttpJsonOptions. They are used for the SchemaExporter AND Minimal Apis. The MaxDepth is to prevent DDOS attacks so just keep that in mind.

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.MaxDepth = 256;
});

Or you can exclude operations which have the User as a parameter with this example:

builder.Services.AddOpenApi(options =>
{
    options.ShouldInclude = (description) =>
        !description.ParameterDescriptions.Any(x => x.ModelMetadata.ModelType == typeof(User));
});

It's not ideal but this is an issue in the JsonSchemaExporter.

desjoerd avatar Sep 30 '25 09:09 desjoerd

Facing the same issue using the wolverine.http, ended up using the Swashbuckle.AspNetCore, hope MS stops lying off developers and starts fixing bugs instead of that AI BS

AndreyBespamyatnov avatar Nov 02 '25 20:11 AndreyBespamyatnov

+1 - Had to rollback to Swashbuckle.AspNetCore.SwaggerGen, Microsoft.OpenAPI doesnt support ignorying types or options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles

MauricioRodolfo avatar Dec 11 '25 13:12 MauricioRodolfo