我有一个用 C# 编写的相当简单的 Web API,使用 EF。这个想法基本上是一个待办事项应用程序,具体关系是:一个用户可以有许多待办事项列表,每个待办事项列表可以有许多待办事项。
这是我的数据模型:
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 有对用户的引用,但我需要这两种方式的引用,因为它们是外键。
我还在网上遇到了这个解决方案,添加了这些行:
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();
或者更好地全局应用
ReferenceHandler.Preserve
设置:
builder.Services.AddControllers()
.AddJsonOptions(options =>
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve);
了解更多 - 避免或控制 Entity Framework Core 中的循环引用 .