Это было решено
Это контракт, который я не могу получить по телефону:
[DataContract]
public class myInitializationData : ClientInitializationData
{
[DataMember]
public Dictionary<string, string> CultureNameLookup { get; set; }
}
Вот это базовый тип,
[DataContract]
public class ClientInitializationData
{
[DataMember]
public List<IServiceType> ServiceTypes { get; set; }
}
IServiceType
- это интерфейс. Я понимаю, что не могу отправить интерфейс по проводам. Существует сущность EntityFramework ServiceType
, реализующая интерфейс IServiceType
:
public partial class ServiceType : IServiceType
{
//...
}
Моя цель - отправить ServiceType
сущностей по сети через myInitializationData
контракт.
Мне запрещено украшать классы myInitializationData
или ClientInitializationData
с KnownType ServiceType
, потому что эти классы совместно используются (связаны) с проектами Silverlight. Поэтому, если я украслю любой из этих классов с KnownType ServiceType
, сторона (и) Silverlight не сможет скомпилироваться.
Вместо того, чтобы декорировать классы напрямую, я заключил контракт на обслуживание с ServiceKnownType ServiceType
:
[ServiceContract]
[ServiceKnownType(typeof(ServiceType))]
public interface IService
{
[OperationContract]
myInitializationData InitializeClient();
}
Должно ли это работать?
При вызове IService.InitializeClient
я получаю следующую ошибку на клиенте:
There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).
Я включил отладку трассировки, но не нашел сообщений о сбое сериализации в трассировке для клиента или сервера.
Трассировка сервера:
- Получает сообщение, когда-либо канал
( Действие: http://tempuri.org/IService/InitializeClient)
- Кому: Выполнить
( IService.InitializeClient )
- От: Выполнить
( IService.InitializeClient )
- Отправляет сообщение по каналу.
( Действие: http://tempuri.org/IService/InitializeClientResponse)
- Внимание!
Failed System.ServiceModel.Channels.ServerSessionPreambleConnectionReader + ServerFramingDuplexSessionChannel
- Внимание!
Failed System.ServiceModel.Channels.ServiceChannel
- Ответ на операцию вызвал исключение
( Экземпляр ObjectContext был удален и больше не может использоваться для операций, требующих подключения. )
Трассировка клиента:
Если я выберу свойство ServiceTypes
из ClientInitializationData
DataContract, эта ошибка исчезнет. Поэтому я предполагаю, что это должно быть проблемой сериализации: интерфейса и KnownTypes, но WCF не претендует на наличие каких-либо проблем сериализации в трассировке, и я не уверен, что означает трассировка в этом случае.
Решение
Это не было проблемой KnownTypes. Это было результатом того, что LazyLoading был самопроизвольно включен в контексте объекта, определяющего тип ServiceType
.
Хотя в трассировке нет упоминания о чрезмерном нарушении размера сообщения или буфера (на стороне клиента или сервера), я должен предположить, что включение LazyLoading в контексте EF заставило DataContractSerializer вызвать EF для выборки много записей, что, в свою очередь, привело к (попыткам) массивного графика на проводе. Серверная сторона просто (и неоднозначно) вышла из строя канала во время записи сообщения.
Возвращение LazyLoading в отключенное состояние в контексте EF с тех пор решило эту проблему.