2009-10-09 3 views
1

У меня есть список пользовательских DTO, которые я пытаюсь передать в службу WCF.WCF - общий список (из T)

Я получаю следующее сообщение об ошибке:

There was an error while trying to serialize parameter tcp://localhost/:oObject. The InnerException message was 'Type 'System.Collections.Generic.List`1[[TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat.HeartBeatDTO, WFCommon, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' with data contract name 'ArrayOfHeartBeatDTO:TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.

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

Что мне не хватает? Был через множество сайтов, которые делают подобные вещи, но не может заставить мою работать за эту ошибку. Есть идеи?

Код от отправителя:

<DataContract(Name:="HeartBeatDTO", Namespace:="TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat")> _ 
Public Class HeartBeatDTO 

Public Sub IssuePatientReport() 
    SBClient.SendCommunication(_PatientID, _HeartBeats) 
End Sub 

код на приемнике:

Public Sub SendCommunication(ByVal sKey As String, ByVal oObject As Object) Implements iOperatorCommunication.SendCommunication 
     If _CurrentCommunicationLog.ContainsKey(sKey) Then 
      _CurrentCommunicationLog.Item(sKey) = oObject 
     Else 
      _CurrentCommunicationLog.Add(sKey, oObject) 
     End If 
    End Sub 

Мой интерфейс:

<ServiceContract(Namespace:="tcp://localhost/")> _ 
<ServiceKnownType(GetType(List(Of HeartBeatDTO)))> _ 
Public Interface iOperatorCommunication 
    <OperationContract()> _ 
    Function ReceiveCommunication(ByVal sKey As String) As Object 

    <OperationContract()> _ 
    Function ReturnCommunicationLevel() As Integer 

    <OperationContract()> _ 
    Function ReturnCommunications() As Dictionary(Of String, Object) 

    <OperationContract()> _ 
    Function ReturnCommunicationsByKeySearch(ByVal sSearch As String) As Dictionary(Of String, Object) 

    <OperationContract()> _ 
    Sub SendCommunication(ByVal sKey As String, ByVal oObject As Object) 
End Interface 

UPDATE: Вот новое сообщение об ошибке:

There was an error while trying to serialize parameter tcp://localhost/:oObject. The InnerException message was 'Type 'TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat.HeartBeatDTOList' with data contract name 'HeartBeatDTOList:TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.

ответ

6

Если у вас есть пользовательские типы сбора, что вам может понадобиться для украшения тех, кто с особым атрибутом - см MSDN docs on CollectionDataContract:

[CollectionDataContract] 
public class CustomerList2 : Collection<string> {} 

Может ли это быть проблема?


UPDATE: ОК, спасибо за размещение интерфейса. Я не эксперт VB.NET, но из того, что я понимаю и вижу, вы никогда не используете тип «HeartbeatDTO» в любом из ваших методов, украшенном атрибутом OperationContract - правильно?

Так что я предположил бы, что вы, вероятно, также необходимо определить, что в качестве «ServiceKnownType» - попробуйте это:

<ServiceContract(Namespace:="tcp://localhost/")> _ 
<ServiceKnownType(GetType(HeartBeatDTO))> _ 
<ServiceKnownType(GetType(List(Of HeartBeatDTO)))> _ 
Public Interface iOperatorCommunication 

ли это помощь?

Также: существует ли какая-либо конкретная причина, по которой вы используете «Объект» в качестве типа на протяжении всего вашего контракта на обслуживание? Не могли бы вы указать либо HeartbeatDTO, либо List(Of HeartbeatDTO)?

UPDATE: могли бы вы, возможно, попробовать - просто ради видеть, если он работает - создать новый список интерфейсов услуг это:

<ServiceContract(Namespace:="tcp://localhost/")> _ 
Public Interface iOperatorCommunicationStripped 
    <OperationContract()> _ 
    Sub SendCommunication(ByVal sKey As String, ByVal oObject As List(Of HeartbeatDTO)) 
End Interface 

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

Марк

+0

Вау ... это, конечно, похоже, что мне нужно ... добавить, что в качестве нового класса, или изменить свой класс DTO использовать что DataContract вместо тока? – RiddlerDev

+0

Nevermind ... не читал достаточно далеко, выглядит как отдельный класс. Позвольте мне попробовать это. – RiddlerDev

+0

Вот что я добавил: _ Public Class HeartBeatList Inherits List (Of HeartBeatDTO) End класса ... Но это не похоже, чтобы сделать это ... Я также пытался обновить службу контракт: _ – RiddlerDev

Смежные вопросы