【问题标题】:How to fix infinite object nesting or set a max depth level with AutoMapper?如何修复无限对象嵌套或使用 AutoMapper 设置最大深度级别?
【发布时间】:2021-01-27 14:56:48
【问题描述】:

我正在做一个项目,我需要将特定对象的列表映射到另一个列表。您可以在下面找到对象。我需要将列表序列化为 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....

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

【问题讨论】:

  • 你使用的是最新版本的 System.Text.Json 5.0.x 吗?
  • @magicandre1981 不,我们使用 4.7.2
  • 使用最新的5.0.1 package
  • @magicandre1981 谢谢我们已经试过了。但我们无法弄清楚如何配置自定义深度量。例如,我们确实希望它是嵌套的,但要嵌套到一定数量的级别。不是无限的。这可能吗?如果是这样,它是通过 System.Text.Json 还是通过 AutoMapper 进行配置的?以及如何?
  • 版本 5 添加了循环引用支持,但我仍然使用旧的 NewtonSoft JSON。玩一下吧

标签: c# json .net-core automapper circular-reference


【解决方案1】:

我将 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","Name":"t","Products":{"$id":"6","$values":[{"$ref":"4"}]}}}]}}]}

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

这就是修复。

【讨论】:

  • 很高兴听到您使用 System.Text.Json 库的最新版本进行工作
猜你喜欢
  • 2011-08-27
  • 2019-02-12
  • 2013-08-22
  • 2015-02-20
  • 1970-01-01
  • 2020-01-07
  • 2018-04-14
  • 1970-01-01
  • 2012-11-04
相关资源
最近更新 更多