【问题标题】:A possible object cycle was detected when serializing entity-model to JSON将实体模型序列化为 JSON 时检测到可能的对象循环
【发布时间】:2021-12-03 21:42:22
【问题描述】:

我有一个使用 C# 编写并构建在 ASP.NET Core/5 框架之上的 webapi 项目。

API 返回 JSON 数据。

这是一个端点的示例

[HttpGet]
public async Task<ActionResult<TModel[]>> QueryAsync(
   [FromQuery(Name = "filter")] string filter = null,
   [FromQuery(Name = "expand")] string expand = null)
{
    IQueryable<TModel> query = GetQuery(filter, expand);

    var models = await query.ToArrayAsync();

    return Ok(models);
}

在上述请求中,expand 将告诉服务器要扩展哪些导航属性。当用户请求扩展属性时,我收到以下错误

A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles

按照错误的指示,我在 Startup 类中添加了以下内容

services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    // added this
    options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
});

上述更改确实解决了问题!然而,它引入了另一个问题。新的问题是它改变了输出的结构。

输出来自这样的东西

{
  // properties
 
  "relations": [
     {
         // relation 1
         "parent": null
     },
     {
         // relation 2
         "parent": null
     }
   ]
}

这样的事情

{
  "$id": "1",
  // properties
 
  "relations": {
     "$id": "2",
     "$values": [
         {
             // relation 1 properties
             "$id": "3",
             "parent": {
                 "$ref": 1
             }
         },
         {
            // relation 2 properties
            "$id": "3",
            "parent": {
                 "$ref": 1
             }
         }
     ]
   }
}

有没有办法不改变输出结构而忽略循环引用?

【问题讨论】:

    标签: c# json asp.net-core json.net asp.net-core-webapi


    【解决方案1】:

    这里有一个类似的问题,其中一个答案提到了您遇到的相同问题:.Net Core 3.0 possible object cycle was detected which is not supported

    那里提到的一些事情:

    如果您使用的是 .NET 6,则可以使用

    JsonSerializerOptions options = new()
    {
        ReferenceHandler = ReferenceHandler.IgnoreCycles,
        WriteIndented = true
    };
    

    或者,根据您需要实现的目标,您可能希望完全忽略循环属性。

    不过,正确的解决方案是找出您的引用到底在哪里循环,并从序列化中排除有问题的属性,或者以不循环的格式提供它们(例如 id 或类似的)

    【讨论】:

    • 感谢您提供的信息。确实,这似乎是我所需要的。我正在使用 .NET,所以 IgnoreCycles 不可用。和`options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore`似乎不可用。知道如何设置`options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore`?
    • 在我上面提供的链接中,Arsalan Haider 有一个解决方案,可以用 newtonsoft 替换默认的 asp.net json 序列化程序,它提供了您想要的选项。欲了解更多信息,这里有一个更详细的解决方案:thecodebuzz.com/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 2012-12-01
    • 1970-01-01
    • 2015-01-21
    相关资源
    最近更新 更多