WCF Попытка получить коллекцию приводит к сбою клиента
Я играл с WCF вместе с EF и столкнулся с проблемой отправки коллекций.
Я работаю с игровой площадкой, состоящей из 2 решений, просто минимум, который мне нужен для общения по линии. Отправка строк между ними работает нормально, добавление записи в базу данных через клиента тоже работает нормально. Тем не менее, мой сервис выставляет следующий контракт:
[OperationContract]
IEnumerable<Company> GetAllCompanies();
Реализовано в моем сервисе как:
public IEnumerable<Company> GetAllCompanies()
{
using (var ctx = new InleerAppContext())
{
return ctx.Company.ToList();
}
}
Ничего необычного, и поскольку отправка объектов, казалось, работала нормально, я ожидал, что это тоже сработает. Однако при вызове GetAllCompanies() из моего клиента:
var result2 = service.GetAllCompanies();
foreach (Company c in result2)
{
Console.WriteLine(c.Name);
}
Возникает исключение CommunicationException:
Произошла ошибка при получении HTTP-ответа на http://localhost:8080/. Это может быть связано с тем, что привязка конечной точки службы не использует протокол HTTP. Это также может быть связано с тем, что сервер прерывает контекст HTTP-запроса (возможно, из-за закрытия службы). Смотрите журналы сервера для более подробной информации.
С дополнительной информацией:
в System.Net.HttpWebRequest.GetResponse()
в System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
Я уже изменил время ожидания до 30 минут как на клиенте, так и на сервере, используя настраиваемую конфигурацию привязки (которая является базовой для HttpBinding с обеих сторон):
<bindings>
<basicHttpBinding>
<binding name="longTimeoutBasicHttpBinding"
receiveTimeout="00:30:00"
sendTimeout="00:30:00">
</binding>
</basicHttpBinding>
</bindings>
Что мне здесь не хватает?
2 ответа
Скорее всего, у вас проблема с циклической ссылкой. Когда WCF пытается сериализовать ваш Company
Например, он касается каждого свойства и запускает отложенную загрузку связанной сущности, а также сериализует ее, но если сущность имеет свойство обратной навигации, она будет следовать за ней и снова сериализует компанию => сериализатор находится в бесконечном цикле.
Есть только два способа решить эту проблему:
- Отключите отложенную загрузку (или создание всего прокси) - используйте
ctx.ContextOptions
, Также не загружайте отношения сInclude
- Удалить / разрешить циклическую зависимость - это необходимо, если вы хотите также сериализовать отношения
Обычно это происходит, когда у seralizer возникают проблемы с вашим классом. Например, если компания является объектом сущности и пытается отделить одно из свойств навигации, это не сработает