这可能是由于循环造成的

这可能是由于循环造成的

本文介绍了JsonException:检测到可能的对象周期,但不支持该周期.这可能是由于循环造成的,或者是物体深度大于的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Web API中,当我运行用于从数据库获取数据的项目时出现此错误.net core 3.1

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

这些是我的代码我的模特

These are my codemy Model

 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类是:

my productCategory class is:

 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; }
}

我的仓库是

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

我的界面

public interface IProductRepository
{
   ...
    Task<IList<Product>> GetAllProductAsync();
 ...
}

这是我在api项目中的控制器

and this is my controller in api project

 [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项目并输入以下网址时: https://localhost:44397/api/products 我有那个错误,我无法解决

When I run api project and put this url: https://localhost:44397/api/productsI got that error ,I cant resolve it

推荐答案

之所以发生这种情况,是因为您的数据具有引用循环.

this is happening because your data have a reference loop.

例如

// 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] 属性)

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. 您可以使用项目中的 Newtonsoft.Json 而不是 System.Text.Json (我为您链接了一篇文章)

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

从dotnet5图库中下载 System.Text.Json 预览包版本 5.0.0-alpha.1.20071.1 (通过Visual Studio的NuGet客户端):

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

选项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 功能.

these serializers have ReferenceLoopHandling feature.

  • Edit : ReferenceHandling 在DotNet 5中已更改为 ReferenceHandler
  • >
  • Edit : ReferenceHandling changed to ReferenceHandler in DotNet 5

但是,如果您决定只忽略一个引用,请对其中一个属性使用 [JsonIgnore] .但即使没有参考循环,它也会在该字段的API响应上导致空结果.

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;}
}

这篇关于JsonException:检测到可能的对象周期,但不支持该周期.这可能是由于循环造成的,或者是物体深度大于的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 18:11