Сложные типы данных в WCF?

Я столкнулся с проблемой при попытке вернуть объект, содержащий коллекцию дочерних объектов, которая снова может содержать коллекцию объектов-внуков. Я получаю сообщение об ошибке «соединение принудительно закрыто хостом».

Есть ли способ заставить это работать? В настоящее время у меня есть структура, похожая на эту:

псевдокод:

Person:
IEnumerable<Order>

Order:
IEnumerable<OrderLine>

Все три объекта имеют атрибут DataContract, а все открытые свойства, которые я хочу показать (включая IEnumerable), имеют атрибут DataMember.

У меня есть несколько OperationContract в моей службе, и все методы, возвращающие один объект ИЛИ IEnumerable объекта, работают отлично. Только когда я пытаюсь вложить IEnumerable, он становится плохим. Также в справочнике по обслуживанию клиентов я выбрал общий список в качестве типа коллекции. Я просто хочу подчеркнуть, только одна из моих операций / методов не срабатывает с этой ошибкой - остальные работают отлично.

РЕДАКТИРОВАТЬ (более подробное описание ошибки):

[SocketException (0x2746): An existing connection was forcibly closed by
the remote host]
[IOException: Unable to read data from the transport connection:
An existing connection was forcibly closed by the remote host.]
[WebException: The underlying connection was closed: An unexpected
error occurred on a receive.]
[CommunicationException: An error occurred while receiving the HTTP
response to http://myservice.mydomain.dk/MyService.svc. This could
be due to the service endpoint binding not using the HTTP protocol.
This could also be due to an HTTP request context being aborted by
the server (possibly due to the service shutting down). See server
logs for more details.]

Я пробовал искать журналы, но не могу их найти ... также я использую WSHttpBinding и конечную точку http.


person Per Hornshøj-Schierbeck    schedule 15.10.2008    source источник
comment
Есть ли в ваших объектах что-то, что неправильно сериализуется?   -  person Jeff Schumacher    schedule 15.10.2008
comment
Я не знаю. Я подумал, может быть, вложенный IEnumberable ‹T› не может сериализоваться? Но как мне узнать? Я могу отлаживать вплоть до возврата фактического OperationContract, и все в порядке, но транспорт, похоже, идет не так. У меня нет атрибута Serialize, но я использую [DataMember]   -  person Per Hornshøj-Schierbeck    schedule 15.10.2008
comment
У меня такая же ошибка, как и у вас ... мои классы также определены с помощью свойств перечисления, но я нигде не вижу в этом проблемы ... перечисления должны быть в порядке ... и что вы имеете в виду, устанавливая значение по умолчанию? это типы значений, поэтому они всегда имеют значение по умолчанию. я попытаюсь удалить свойства перечисления и посмотреть, исправит ли это это .. вот некоторая информация о поддерживаемых классах контрактов данных msdn.microsoft.com/en-us/library/ms731923.aspx   -  person Sonic Soul    schedule 29.10.2010


Ответы (13)


В качестве примечания вам необходимо научиться использовать служебные программы ведения журнала WCF:

Информация о журналах.

Config Editor (упрощает настройку).

Средство просмотра трассировки. Совершенно потрясающе. Позволяет нескольким службам (клиенту и серверу) отслеживать и может присоединяться к ним, а также помогает анализировать все детали. Позволяет очень быстро добраться до сути проблемы. (Причина в том, что при ошибке WCF сервера клиент вряд ли получит полезные данные.)

person MichaelGG    schedule 20.10.2008
comment
Где я могу найти приложение для просмотра трассировки, документация MS говорит об этом, но не упоминает, как с ним начать? - person JL.; 06.03.2010
comment
JL, он устанавливается с Windows SDK - person Artem Koshelev; 16.06.2010
comment
+1 для Trace Viewer ... это действительно отличный инструмент! Просто решил для меня проблему, над которой я мучился со вчерашнего дня. - person w4ik; 04.01.2011
comment
средство просмотра трассировки = наконец, мне не нужно предполагать снижение производительности, когда я пишу приложения WCF - person Jake; 12.01.2011
comment
Я не знал о редакторе конфигураций или программе просмотра трассировки. Они просто избавили меня от огромной головной боли. Спасибо! - person Odrade; 05.04.2011
comment
Теперь я знаю, почему так много людей поддерживают это предложение. Для любого пользователя WCF, когда вы получаете неоднозначную ошибку, например, Существующее соединение было принудительно закрыто ..., SvcTraceViewer спасает жизнь. - person Anand; 04.11.2011
comment
Да, Trace Viewer - ваш лучший друг при устранении неясных ошибок WCF. - person MrDustpan; 21.01.2012

Хорошо, я наконец нашел настоящую проблему в моем случае. Кажется, разоблачение перечислений - не самое лучшее в мире. Мне нужно либо установить для них значение по умолчанию, либо вместо этого предоставить свойство как int или любой другой целочисленный тип, на котором основано мое перечисление.

Спасибо за помощь, у вас не было возможности узнать об этом - я нашел перечисления на 3-м уровне в моей структуре, и систематическое удаление камер данных по одной - вот способ, которым я узнал. Похоже, я не единственный, кто столкнулся с этой проблемой - у этого парня явно были похожие проблемы :)

http://zianet.dk/blog/2007/11/24/serializing-enums-in-wcf/

person Per Hornshøj-Schierbeck    schedule 15.10.2008

Если вы работаете с WCF + (EF + POCO), попробуйте установить,

ObjectContext.ContextOptions.LazyLoadingEnabled = false;
ObjectContext.ContextOptions.ProxyCreationEnabled = false;
person indiPy    schedule 29.10.2010
comment
Большое Вам спасибо. Ты спас меня от застрела! - person Dragan; 15.10.2011
comment
Или используйте AutoMapper, и в этом случае вы не решите только симптомы. - person Mathias Lykkegaard Lorenzen; 06.10.2014

Добавьте эту строку в <system.web/>:

<httpRuntime maxRequestLength="102400" executionTimeout="3600" />
person Thoại Nguyễn    schedule 19.03.2010

Перечисления получают атрибут DataContract, как и любой класс, но значения перечисления не должны иметь атрибутов DataMember.

Измените их на EnumMember, и вы перестанете получать эту непостижимую ошибку.

person Brandon Roberson    schedule 09.01.2011

это фактически та же информация, что и ваше первое описание исключения. Было бы интересно, какова была первоначальная причина sockeexception. это должна быть какая-то ошибка в самой службе. Вы можете определить, где именно происходит исключение?

у меня были аналогичные ошибки при попытке вернуть обычные IEnumerables, которые были перезаписаны (они были помечены как виртуальные) NHibernate и заменены GenericPersistentBag, который не сериализуемый. Вы отметили свои датамембраны IEnumerable как виртуальные из-за nhibernate или чего-то подобного? это могло объяснить вашу ошибку.

Кстати. Исключения wcf часто бессмысленны (что может сильно расстраивать при отслеживании ошибки;)

person Joachim Kerschbaumer    schedule 15.10.2008
comment
Это вся информация об исключениях, которую я могу получить. Я получаю такое же исключение (если включаю трассировку стека) при отладке. Мы используем Linq2Sql, но фактически преобразуем этот объект в более легкие объекты, которые содержат только простые типы данных, за исключением этих вложенных коллекций. - person Per Hornshøj-Schierbeck; 15.10.2008
comment
Я имею в виду, что объекты, на которых есть DataContract, не являются частью чего-либо еще в проекте - они в значительной степени являются DTO, за исключением хранения коллекций других DTO. - person Per Hornshøj-Schierbeck; 15.10.2008

У меня тоже была такая же проблема (.Net 3.5). Оказывается, в моем базовом классе DataContract отсутствовал известный тип. К сожалению, ошибка WCF не была более описательной.

person Kyle Lahnakoski    schedule 22.01.2010

вы указали в своей конфигурации поведения службы? похоже, что в этой трассировке стека отсутствует какая-то информация.

можете ли вы захватить исключение на стороне сервера (например, в режиме отладки Visual Studio или с помощью библиотеки журналов, такой как log4net).

пробовали ли вы вызвать другие методы (например, простой helloworld ()) в той же службе, чтобы убедиться, что сама конфигурация службы работает? такое исключение может также указывать на некоторые проблемы с сериализацией. какие типы вы хотите отправить по сети? вы где-нибудь используете KnownType?

person Joachim Kerschbaumer    schedule 15.10.2008
comment
Я очень рад любой помощи, которую могу получить, поэтому спасибо за ответ! Но, пожалуйста, прочтите мой вопрос еще раз - только один из моих методов не срабатывает с этой ошибкой. Также об исключении я могу опубликовать полную трассировку стека, но это просто раздувает вопрос? Тогда выложу в ответ :) - person Per Hornshøj-Schierbeck; 15.10.2008

Я не знаю, почему это может случиться. но у меня тоже были похожие проблемы.

Я изменил свои перечисления. Удалил индексы (например, ASNOrder = 1, -> ASNOrder,), и никаких ошибок не произошло.

person Community    schedule 28.11.2008

Не возвращайте буквальный IEnumerable в контракте, существует знаменитый WCF IEnumerable ошибка

person Chris O    schedule 22.01.2010

Попробуйте установить [OperationBehavior()] над своей реализацией метода интерфейса.

person trkll    schedule 13.08.2010

У меня была эта ошибка при использовании yield return для создания перечисления объектов, сопоставленных с моим типом DataContract.

Вызов ToList / ToArray по результатам урожайности устранил проблему, и вызов службы работал правильно.

person Rob Willis    schedule 25.10.2010

Да, у меня была та же проблема, и это было связано с возвращением объектов, в которых были значения перечисления. Изменил DataMember на int, и все заработало.

person Tiny122    schedule 23.04.2010