我添加了以下行来解决JSON中的循环错误:
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
但是现在,我发现我的一些控制器返回了太多信息。
我发现了一个类似的问题,但是通读它,我无法真正弄清楚如何将其应用到我的代码中: Avoiding Circular referencing providing too much data
例如,这个简单的控制器返回我不想要的数据:
[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();
也就是说,有没有办法限制或排除我不想要的数据?
谢谢!
答案 0 :(得分:1)
您的导航道具是虚拟的,因此我假设您启用了延迟加载。当序列化程序遍历该对象时,它将为每个这些属性触发get
,这反过来将依次发出查询以回填数据,然后对数据进行序列化。假定它没有遇到循环引用,它将继续沿相关实体行进,加载并序列化每个关系。
这很好地说明了为什么从不序列化实体。实体用于处理数据库。它们不是用于也不应用于返回响应,渲染视图等。
而是创建一个视图模型/ DTO /任何您想调用的模型。在其上映射您的实体类,然后返回视图模型。这样,您可以精确控制响应是什么。