我有一个用C#编写的相当简单的Web API,使用EF.这个 idea 在很大程度上是一个待办事项应用程序,具体的关系是:一个用户可以有多个待办事项列表,每个待办事项列表可以有多个待办事项.

以下是我的数据模型:

public class User
{
    public Guid Id { get; set; }
    public string? Name { get; set; }
    public string? Email { get; set; }
    public string? Password { get; set; } // Be sure to properly hash and salt passwords
    public string? ProfilePhotoUrl { get; set; } // Store the URL to the user's profile photo
    public List<ToDoList>? ToDoLists { get; set; } // A user can have multiple to-do lists
}

public class ToDoList
{
    public Guid Id { get; set; }
    public string? Title { get; set; }
    public List<ToDo>? ToDos { get; set; } // Each to-do list contains multiple to-dos

    // Foreign Key to User
    public Guid UserId { get; set; }
    public User? User { get; set; }
}
public class ToDo
{
    public Guid Id { get; set; }
    public string? Name { get; set; }
    public string? Description { get; set; }
    public bool? InProgress { get; set; }
    public bool? IsComplete { get; set; }
    public DateTime Created { get; set; } = DateTime.Now;

    public ToDoList? ToDoList { get; set; } 
    public Guid? ToDoListId{ get; set; }
}

我有一个控制器,允许用户注册,登录等.我想做的一件事是检索每个用户可能拥有的待办事项列表.我在一个服务中有代码:

    public Task<User> GetToDoListsForUsers(Guid userId)
    {
        return _context.Users
            .Include(u => u.ToDoLists)
            .FirstOrDefaultAsync(u => u.Id == userId);
    }

然后由控制器调用:

    [HttpGet("{userId}/todolists")]
    public async Task<ActionResult<IEnumerable<ToDoList>>> GetToDoListsForUser(Guid userId)
    {
        var user = await _userService.GetToDoListsForUsers(userId);

        if (user == null)
        {
            return NotFound("User not found");
        }

        var toDoLists = user.ToDoLists;

        if (toDoLists.Count == 0)
        {
            return NotFound("user has no lists");
        }

        return Ok(toDoLists);
    }

但是,当我运行此命令时,我得到以下错误:


      An unhandled exception has occurred while executing the request.
      System.Text.Json.JsonException: 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. Path: $.User.ToDoLists.User.ToDoLists.User.ToDoLists.User.ToDoLists.User.ToDoLists.User.ToDoLists.User.ToDoLists.User.ToDoLists.User.ToDoLists.User.ToDoLists.Id.

我相信这是因为用户引用了ToDoList,而ToDoList又引用了User,但我需要双向引用这个引用,因为它们是外键.

我还在网上看到了这个解决方案,添加了以下几行:

        var jsonSettings = new JsonSerializerOptions
        {
            ReferenceHandler = ReferenceHandler.Preserve,
        };

        var serializedUser = JsonSerializer.Serialize(user, jsonSettings);
        var deserializedUser = JsonSerializer.Deserialize<User>(serializedUser, jsonSettings);

        var toDoLists = deserializedUser.ToDoLists;

添加到控制器方法,但这也不起作用.

有什么可以帮助你解决这个问题的吗?

推荐答案

Tbh找到的"解决方案"没有任何意义,使用相同的设置ReferenceHandler.Preserve只会恢复引用.

您可以只返回序列化的手动数据:

var serializedLists = JsonSerializer.Serialize(user.ToDoLists, jsonSettings);
return Content(serializedLists);

或者更好地在全局应用ReferenceHandler.Preserve设置:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
        options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve);

还有一个值得考虑的选项(我默认使用的选项)-创建DTO并映射到它们,这样就不会出现循环,响应只有必要的数据.

多读一点--Avoid or control circular references in Entity Framework Core本.

Csharp相关问答推荐

在包含空项的列表上使用具有断言T的摘要表

Microsoft.AspNetCore.Mvc. Controller Base.用户:属性或索引器Controller Base.用户无法分配给--它是只读的

实体框架核心上是否支持使用NPGSQL的字符串聚合?

MudBlazor—MudDataGrid—默认过滤器定义不允许用户修改基本过滤器

mocking对象的引发事件并作为用于调用方法的参数对象传递到那里

在调整大小的控件上绘制

Razor视图Razor页面指向同一端点时的优先级

从.Net 6 DLL注册和检索COM对象(Typelib导出:类型库未注册.(异常来自HRESULT:0x80131165))

方法从数据表中只 Select 一个条件?

Cosmos SDK和Newtonsoft对静态只读记录的可能Mutations

.NET SDK包中的官方C#编译器在哪里?

在ASP.NET Core 8 MVC中本地化共享视图

当我将`ConcurentDictionary`转换为`IDictionary`时,出现了奇怪的并发行为

C#LINQ子字符串

单元测试类型为HttpClient with Microsoft.Extensions.Http.Resilience

Azure函数正在返回值列表,但该列表在Chrome中显示为空

如何在C#中反序列化Java持续时间?

我是否以错误的方式使用了异步延迟初始化?

Unity 3D-意外轴捕捉和未知力对脉冲react 行为的影响

.NET6最小API:操作.MapGet之后的响应