JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than

后端 未结 6 927
执念已碎
执念已碎 2021-02-04 16:07

In my web api when i run project for get data from database got this error .net core 3.1

JsonException: A possible object cycle was detected which is not

相关标签:
6条回答
  • 2021-02-04 16:21

    Ensure you have [JsonIgnore] on the correct fields to avoid a circular reference.

    In this case you will need

     public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string ProductText { get; set; }
        [JsonIgnore]
        public virtual ProductCategory ProductCategory { get; set; }
    }
    

    You probably don't need the ProductCategoryId field (depends if you are using EF and code first to define your DB)

    0 讨论(0)
  • 2021-02-04 16:22

    I have the same issue, my fix was to add async and await keyword since I am calling an async method on my business logic.

    Here is my original code:

    [HttpGet]
    public IActionResult Get()
    {
       //This is async method and I am not using await and async feature .NET which triggers the error
       var results = _repository.GetAllDataAsync(); 
       return Ok(results);
    }
    

    To this one:

    HttpGet]
    public async Task<IActionResult> Get()
    {
       var results = await _repository.GetAllDataAsync();
       return Ok(results);
    }
    
    0 讨论(0)
  • 2021-02-04 16:25

    For net core 3.1 you have to add in Startup.cs:

    services.AddMvc.AddJsonOptions(o => {
    o.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
    o.JsonSerializerOptions.MaxDepth = 0;
    })
    

    and import at least this package using nuget.org include prerelease:

    <PackageReference Include="System.Text.Json" Version="5.0.0-rc.1.20451.14" />
    
    0 讨论(0)
  • 2021-02-04 16:27

    Finally fixed mine with System.Text.Json not NewtonSoft.Json using

    var options = new JsonSerializerOptions()
            {
                MaxDepth = 0,
                IgnoreNullValues = true,
                IgnoreReadOnlyProperties = true
            };
    

    Using options to serialize

    objstr = JsonSerializer.Serialize(obj,options);
    
    0 讨论(0)
  • 2021-02-04 16:38

    following code is working for me in dotnet 5.0 :

      services.AddControllersWithViews()
                            .AddJsonOptions(o => o.JsonSerializerOptions
                            .ReferenceHandler = ReferenceHandler.Preserve);
    
    0 讨论(0)
  • 2021-02-04 16:42

    this is happening because your data have a reference loop.

    e.g

    // this example creates a reference loop
    var p = new Product()
         { 
            ProductCategory = new ProductCategory() 
               { products = new List<Product>() }
         };
        p.ProductCategory.products.Add(p); // <- this create the loop
        var x = JsonSerializer.Serialize(p); // A possible object cycle was detected ...
    

    You can not handle the reference loop situation in the new System.Text.Json yet (netcore 3.1.1) unless you completely ignore a reference and its not a good idea always. (using [JsonIgnore] attribute)

    but you have two options to fix this.

    1. you can use Newtonsoft.Json in your project instead of System.Text.Json (i linked an article for you)

    2. Download the System.Text.Json preview package version 5.0.0-alpha.1.20071.1 from dotnet5 gallery (through Visual Studio's NuGet client):

    option 1 usage:

    services.AddMvc()
         .AddNewtonsoftJson(
              options => {
               options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 
          });
    // if you not using .AddMvc use these methods instead 
    //services.AddControllers().AddNewtonsoftJson(...);
    //services.AddControllersWithViews().AddNewtonsoftJson(...);
    //services.AddRazorPages().AddNewtonsoftJson(...);
    

    option 2 usage:

    // for manual serializer
    var options = new JsonSerializerOptions
    {
        ReferenceHandling = ReferenceHandling.Preserve
    };
    
    string json = JsonSerializer.Serialize(objectWithLoops, options);
    
    // -----------------------------------------
    // for asp.net core 3.1 (globaly)
     services.AddMvc()
      .AddJsonOptions(o => {
         o.JsonSerializerOptions
           .ReferenceHandling = ReferenceHandling.Preserve  
                });
    

    these serializers have ReferenceLoopHandling feature.


    but if you decide to just ignore one reference use [JsonIgnore] on one of these properties. but it causes null result on your API response for that field even when you don't have a reference loop.

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string ProductText { get; set; }
    
        public int ProductCategoryId { get; set; }
        // [JsonIgnore] HERE or
        public virtual ProductCategory ProductCategory { get; set; }
    }
    
    public class ProductCategory
    {
        public int Id { get; set; }
        // [JsonIgnore] or HERE
        public ICollection<Product> products {get;set;}
    }
    
    0 讨论(0)
提交回复
热议问题