Search code examples
c#jsonasp.net-coreserializationentity-framework-core

ASP.NET Core 7 + EF Core 7: A possible object cycle was detected. Maximum allowed depth of 32


I'm developing a standard application with two models "Type" and "Template" that have a "one-to-many" relationship:

public sealed class Type
{
    public int ID { get; set; }
    public string? Name { get; set; }
    public List<Template> Templates { get; set; } = new List<Template>(); 
}

AND

public sealed class Template
{
    public int ID { get; set; }
    public string? Data { get; set; }
    public int TypeID { get; set; }
    public Type? Type { get; set; }
}

When i calling the method GetAll through the TemplateController that uses the service TemplateService and method public List<Template> GetAll() => context.Templates.AsNoTracking().Include(t => t.Type).ToList(); i get the error "System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. Path: $.Type.Templates.Type.Templates.Type.Templates.Type.Templates.Type.Templates.Type.Templates.Type.Templates.Type.Templates.Type.Templates.Type.Templates.ID."

[HttpGet]
public async Task<IActionResult> GetAll()
{
    return await Task.FromResult(Ok(_templateService.GetAll()));
}
public List<Template> GetAll() => context.Templates.AsNoTracking().Include(t => t.Type).ToList();

I couldn't find anything other than an article that says about using "Newtonsoft.Json" and setting up the service: builder.Services.AddControllers().AddNewtonsoftJson(options => { options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;});

It seems to me that this is the wrong solution to the problem (although everything works). Is there a better solution to this problem than .ignor*`ing* the problem?

Thanks everyone <3 Sorry for GoogleTranslate :3


Solution

  • Straight from the docs: https://learn.microsoft.com/en-us/ef/core/querying/related-data/serialization

    Because EF Core automatically does fix-up of navigation properties, you can end up with cycles in your object graph. For example, loading a blog and its related posts will result in a blog object that references a collection of posts. Each of those posts will have a reference back to the blog.

    you can either

     .AddJsonOptions(
                options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
            );
    

    Or use [JsonIgnore]