c# - JsonException : A possible object cycle was detected which is not supported. 这可能是由于循环或对象深度大于

标签 c# api asp.net-core asp.net-core-mvc

在我的 web api 中,当我运行项目以从数据库中获取数据时出现此错误
.net 核心 3.1

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 the maximum allowed depth of 32.



这些是我的代码
我的模特
 public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string ProductText { get; set; }
    public int ProductCategoryId { get; set; }
    [JsonIgnore]
    public virtual ProductCategory ProductCategory { get; set; }
}

我的 productCategory 类是:
 public class ProductCategory
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string CatText { get; set; }
    public string ImagePath { get; set; }
    public int Priority { get; set; }
    public int Viewd { get; set; }
    public string Description { get; set; }
    public bool Active { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime ModifyDate { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}

我的 repo 是
public async Task<IList<Product>> GetAllProductAsync()
    {
        return await  _context.Products.Include(p => p.ProductCategory).ToListAsync(); 
    }

我的界面
public interface IProductRepository
{
   ...
    Task<IList<Product>> GetAllProductAsync();
 ...
}

这是我在 api 项目中的 Controller
 [Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
    private readonly IProductRepository _productRepository;

    public ProductsController(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }
    [HttpGet]
    public ActionResult Get()
    {
        return Ok(_productRepository.GetAllProduct());
    }
}

当我运行 api 项目并输入此 url 时:https://localhost:44397/api/products
我得到了那个错误,
我无法解决它

最佳答案

发生这种情况是因为您的数据有一个引用循环。
例如

// 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 ...
新的System.Text.Json无法处理引用循环的情况然而(netcore 3.1.1)除非你完全忽略一个引用并且它总是不是一个好主意。 (使用 [JsonIgnore] 属性)
但是你有两个选择来解决这个问题。
  • 您可以使用 Newtonsoft.Json 在您的项目中而不是 System.Text.Json (我为你链接了一篇文章)
  • 下载 System.Text.Json预览包版本5.0.0-alpha.1.20071.1来自 dotnet5 库(通过 Visual Studio 的 NuGet 客户端):

  • 选项 1 用法:
    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(...);
    
    选项 2 用法:
    // 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  
                });
    
    这些序列化程序有 ReferenceLoopHandling特征。
  • 编辑: ReferenceHandling 改为 ReferenceHandler在 DotNet 5

  • 但如果您决定忽略一个引用,请使用 [JsonIgnore]在这些属性之一。但即使您没有引用循环,它也会导致该字段的 API 响应为空结果。
    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;}
    }
    

    关于c# - JsonException : A possible object cycle was detected which is not supported. 这可能是由于循环或对象深度大于,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60197270/

    相关文章:

    API 设计 - 最佳实践以及如何支持多个版本

    java - 将 API 暴露给 Tapestry 网络应用程序

    java - 中间件 API 的最佳实践是什么?

    asp.net-core - ASP.NET Core 2.x OnConfiguring 从 appsettings.json 获取连接字符串

    c# - ASP.NET 应用程序体系结构

    c# - Visual Studio 2019 导致调试缓慢和内存使用率高

    c# - 为什么我预期的空对象不为空?

    c# - 从操作方法返回最具体或最通用的类​​型更好吗?

    .net - 如何将 signalR 与 Redux-observable 一起使用?

    asp.net-core - api 不活动后,asp.net 核心托管服务休眠