我添加了这一行来解决 JSON 中的循环错误:
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
但是现在,我发现我的一些控制器返回了太多信息。
我发现了这个类似的问题,但是通读它,我真的无法弄清楚如何将其应用于我的代码: 避免循环引用提供过多数据
例如,这个简单的控制器返回我不想要的数据:
[HttpGet("{id}")]
public async Task<ActionResult<BookList>> GetBookList(string id)
{
var bookList = await _context.BookList.FindAsync(id);
return bookList;
}
以下是该数据的模型:
public partial class BookList
{
public BookList()
{
BookLinks = new HashSet<BookLinks>();
}
public string BookId { get; set; }
public Guid LibraryId { get; set; }
public string BookTitle { get; set; }
public string BookText { get; set; }
public byte? BookType { get; set; }
public virtual LibraryList Library { get; set; }
public virtual ICollection<BookLinks> BookLinks { get; set; }
}
}
因此,当我点击上面的控制器时,除了来自 BookList 的数据外,我还获得了 BookLinks 的所有不需要的数据。
我只想要基于特定 BookID 的 BookList 中的数据。
我的印象是,如果我想返回所有数据(包括 BookLinks 数据(,我必须做这样的事情:
var bookList = await _context.BookList
.Include(i => i.BookLinks)
.Where(b => b.BookId == id)
.ToListAsync();
也就是说,有没有办法限制或排除我不想要的数据?
谢谢!
您的导航道具是虚拟的,所以我假设您启用了延迟加载。当序列化程序遍历对象时,它将触发每个属性的get
,进而逐个发出查询以回填数据,然后也会序列化数据。假设它没有遇到循环引用,它将继续向下走相关实体,加载和序列化每个关系。
这完美地说明了为什么永远不应该序列化实体。实体用于处理数据库。它们不适用于也不应用于返回响应、呈现视图等。
相反,创建一个视图模型/DTO/任何你想称呼它的东西。将实体类映射到该实体类,然后改为返回视图模型。这样,您就可以准确控制响应的内容。