如何使用 AutoMapper 修复无限对象嵌套或设置最大深度级别?

问题描述

我正在处理一个项目,我需要将一个特定对象的列表映射到另一个列表。您可以在下面找到对象。我需要将列表序列化为 JSON 字符串,但它会引发下一个错误

System.Text.Json.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.'

物体(切割):

    class Class1
    {
        public string Name { get; set; }
        public List<Product> Products { get; set; } = new List<Product>();
    }

    class Product
    {
        public string Name { get; set; }
        public Class1 Class1 { get; set; }
    }

    class Class1Model
    {
        public string Name { get; set; }
        public IEnumerable<Product> Products { get; set; }
    }

    class ProductModel
    {
        public string Name { get; set; }
        public Class1Model Class1 { get; set; }
    }

这是我的映射器配置文件

public class MyMapper : Profile
{
    public MyMapper()
    {
        CreateMap<Class1,Class1Model>().MaxDepth(2);
        CreateMap<Product,ProductModel>().MaxDepth(2);
    }
}

调试时,我的映射列表显示无限嵌套对象。例如:

Class1Model
   --> Products,each Product 
        --> Class1Model
            --> Products,each Product
                 --> Class1Model
                    --> repeating....

我的 MaxDepth 中的 MapperProfile 配置无法解决此问题。我想要一个真正的最大深度,例如 2,这样我的 System.Text.Json.JsonSerializer 就不会损坏。我们故意不想使用 NewtonSoft JSON。

解决方法

我将 System.Text.Json 升级到 v5.0.1。

我创建了一个 JsonSerializerOptions 对象:

 var settings = new JsonSerializerOptions
 {
     ReferenceHandler = ReferenceHandler.Preserve
 };

序列化:

var json = JsonSerializer.Serialize(class1s,options: settings);

将对象序列化为JSON字符串时,字符串是这样构建的:

var deserializedJson = JsonSerializer.Deserialize<IEnumerable<Class1Model>>(json,options: settings);

{"$id":"1","$values":[{"$id":"2","Name":"t","Products":{"$id":"3","$values":[{"$id":"4","Name":"p","Class1":{"$id":"5","Products":{"$id":"6","$values":[{"$ref":"4"}]}}}]}}]}

不知何故,$id$values$ref 标签会记住如何在反序列化时以原始结构构建对象,就像在将其序列化为 JSON 字符串之前一样。

这就是修复。