问题描述
我正在处理一个项目,我需要将一个特定对象的列表映射到另一个列表。您可以在下面找到对象。我需要将列表序列化为 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 字符串之前一样。
这就是修复。