【问题标题】:A possible object cycle was detected which is not supported检测到不支持的可能对象循环
【发布时间】:2020-04-27 00:34:47
【问题描述】:

我知道这里有关于该特定问题的问题和答案,但我的问题有点独特(我猜)。

这是我的模型类:

public class RoleMaster
{
    [Key]
    [Required]
    public int Id { get; set; }

    [Required]
    [StringLength(20)]        
    public string Role { get; set; }
}

这是我的控制器:

public class RolesController : ControllerBase
{
    private readonly IRolesRepository _repo;


    public RolesController(IRolesRepository repo)
    {
        _repo = repo;
    }


    [HttpGet]
    public IActionResult Get()
    {
        var roles = _repo.GetRoles();
        return new JsonResult(roles);
    }
}

我的仓库:

public interface IRolesRepository
{
    Task<IEnumerable<RoleMaster>> GetRoles();
}

这里是 GetRoles 方法:

public async Task<IEnumerable<RoleMaster>> GetRoles()
    {
        try
        {
            var roles = await db.RoleMaster.AsNoTracking().ToListAsync();

            return roles;
        }
        catch (Exception)
        {
            throw;
        }
    }

这是我得到的错误:

处理请求时发生未处理的异常。 JsonException:检测到不支持的可能对象循环。这可能是由于循环或对象深度大于最大允许深度 32 造成的。 System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(int maxDepth)

从其他问题中我发现,如果您对其他表有引用,则可能会发生这种错误,但在我的情况下,没有涉及其他表。这是我创建的第一个表,正在尝试 get 方法。

【问题讨论】:

  • 您能否发布 GetRoles() 实际返回的内容,这会导致您的异常?
  • mmm 那么我会说确实有问题..堆栈跟踪还有更多吗?
  • 我认为你的问题在假设错误之后可能是 _repo.GetRoles();没有使用await 这个var roles = _repo.GetRoles(); 应该是var roles = await _repo.GetRoles();,你的混合异步和非异步,如果正确的错误帖子作为答案

标签: c# .net asp.net-core jsonexception


【解决方案1】:

_repo.GetRoles(); 没有使用await 关键字

这个var roles = _repo.GetRoles();

应该是

var roles = await _repo.GetRoles();

你的混合异步和非异步,

以下未经测试,但你应该得到 jist

  [HttpGet]
    public  async Task<IActionResult> Get()
    {
        var roles = **await** _repo.GetRoles();
        return new JsonResult(roles);
    }

原答案是:

仅供参考 - 我原来的答案实际上是正确的...... objectA 是...Task,因为那是从_repo.GetRoles(); 返回的内容

您的 objectsA 有对 objectB 的引用,而 objectB 又引用了 objectsA。

这只是以递归循环结束,基本上永远不会结束尝试 序列化。

因此可能的对象循环

另外,您没有包含可能出现异常的代码 抛出 JsonResult 所以看不到你用的是什么序列化器。

此外,如果您使用的是 newtonJson,那么对复杂的支持 对象更加有限。

进一步 - 只是一个基于 FYI 的关于 cmets 的问题 非异步版本,因为您的主(控制器)线程不是异步的 如果您不想更改它,如上所述或为了清楚起见

public List<RoleMaster> GetRoles()
{
    try
    {
        var roles =  db.RoleMaster.AsNoTracking().ToList();
        return roles;
    }
    catch (Exception)
    {
        throw;
    }
}

更新以获得更多指导

https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-3.1

【讨论】:

  • 当我查询数据库而不是尝试序列化结果时抛出异常。控制永远不会返回到 get 方法,并且在数据库查询执行时抛出异常,即这里var roles = await db.RoleMaster.AsNoTracking().ToListAsync();。这就是为什么我觉得当我在 get 方法中添加 async await 时它开始工作有点奇怪。可能我还是没看清楚这些。
  • 因为您的主要方法不是 Async 并且您此时没有等待 var roles = _repo.GetRoles(); 没有 awiat。角色等于Task&lt;IEnumerable&lt;RoleMaster&gt;&gt; 而不是IEnumerable&lt;RoleMaster&gt; 然后在尝试序列化时,它试图序列化一些包装器,即任务,如source.dot.net/#q=Task,ps 感谢https://source.dot.net 非常方便不知道它。任务操作被推迟,因为它从来没有被等待过,对数据库的实际调用没有发生,它的结果永远不会像你想要的那样同步。
  • 由于任务操作被推迟,我应该从 get 方法中删除 async 和 await 吗?如果我这样做,我的问题就会回来。你还说 db 调用从未发生,但是当我检查我的模型类时,我发现我的属性从表中分配了正确的值,因此 db 调用成功完成,并且在属性初始化后它抛出了所述异常。
  • 我的措辞不是 100% 我试图画一幅画,让您了解正在发生的事情。任务结果永远不会“冒泡”* ...所以仍然是一个任务,这并不意味着工作没有完成,它永远不会将它同步回您感兴趣的线程。所以答案你的问题是,你需要result...如果是,那么你必须await,如果没有那么你可以保持原样,在你的情况下你想序列化result所以如果你想使用async 那么是的,你必须等待,因为你想序列化 result。希望这对你有意义。
  • 好吧,你是对的,但我的问题仍然存在。您会看到建议每个数据库调用都应该是非阻塞的,即异步等待,所以我必须使用我的数据库调用函数保持异步等待,并且任务操作被延迟,所以我不想使用它。所以我该怎么做 ? :)
【解决方案2】:

我遇到了同样的问题。

这就是解决我的问题的方法:

将 JsonIgnore 属性放在引用属性上(导致无休止的序列化)

【讨论】:

    猜你喜欢
    • 2020-07-06
    • 2021-03-17
    • 2020-03-30
    • 2020-07-26
    • 2020-05-28
    • 2020-10-02
    • 2021-08-30
    • 2021-08-01
    • 2021-11-19
    相关资源
    最近更新 更多