Циркулярная ссылка означает, что у вас есть объект a
, который ссылается на b
(например, a.B = b
), но каким-то образом b
ссылается a
назад (например, b.A = a
).
К сожалению, не всегда два объекта указывают друг на друга. Ваша цепь, которая приводит к округлости, может быть длиннее (например, product
указывает на другой product
, который указывает на department
, который указывает на product
).
В большинстве случаев причиной root является то, что ваша служба предоставляет необработанные объекты Entity Framework (или другие ORM), которые объединяются с использованием отношений родитель-потомок. Поскольку навигационные свойства ORM загружаются лениво, в любое время у вас есть product
, у него есть родительский элемент (например, product.Department
), но у department
есть свойство Products
, которое указывает на продукты, и один из продуктов очень тот же продукт, который вы уже посетили в начале. Вот ваш цикл.
Решение состоит в том, чтобы создать еще один набор классов, классы DTO, в которых вы поддерживаете только односторонние свойства навигации. Так, например, у ProductDTO
есть родитель, DepartmentDTO
, но у DepartmentDTO
намеренно отсутствует свойство IEnumerable<ProductDTO> Products
.
Таким образом, сериализатор, который следует вашим навигационным свойствам останавливается в какой-то момент, так как нет циклов. Ваш сервис выставляет эти классы DTO
[WebMethod]
public List<ProductDTO> GetData(int companyId, int custId)
{
return ProductService.GetCompanyData(companyId, custId).ToDTO();
}