Ошибка циклической ссылки в ASMX со связанной таблицей - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть следующий код для ASMX service в веб-приложении. Попытка получить данные в формате XML. Я удалил некоторые данные для ясности

    /// <summary>
    /// Summary description for CompanyServices
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class CompanyServices: System.Web.Services.WebService
    {
        [WebMethod]
        public List<Product> GetData(int companyId, int custId)
        {
          return ProductService.GetCompanyData(companyId, custId).ToList();
        }

В режиме отладки все работает, но я получаю сообщение об ошибке

System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: A circular reference was detected while serializing an object of type Company

Поэтому я создал один и тот же тип и имел для каждого l oop вокруг него похоже на

foreach (Product p in ProductService.GetCompanyData(companyId, custId).ToList())
{
  Product newProd = new Product
  newProd.Name = p.Name;
  newProd.Department = p.Department;
}

Это работало до тех пор, пока я не добавил Отдел, который связан с другой таблицей (Отделов)

Погуглил, но понятия не имею, что вызывает это или как решить

1 Ответ

1 голос
/ 03 апреля 2020

Циркулярная ссылка означает, что у вас есть объект 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();
}
...