Reputation: 7469
I have a list of a custom DTO that I am trying to pass across to a WCF service.
I am getting the following error:
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.
I have the DTO DataContract and DataMember set. I did an auto WCF service reference, and made sure to do advanced options to change collections to be generic lists instead of array.
What am I missing? Been through a lot of sites that do similar things, but cannot get mine to work past this error. Any ideas?
Code from sender:
<DataContract(Name:="HeartBeatDTO", Namespace:="TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat")> _
Public Class HeartBeatDTO
Public Sub IssuePatientReport()
SBClient.SendCommunication(_PatientID, _HeartBeats)
End Sub
Code at receiver:
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
My interface:
<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: Here is the new error message:
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.
Upvotes: 1
Views: 5593
Reputation: 755321
If you have custom collection types, you might need to decorate those with a special attribute - see the MSDN docs on CollectionDataContract:
[CollectionDataContract]
public class CustomerList2 : Collection<string> {}
Could that be the problem?
UPDATE: ok, thanks for the posting the interface. I'm no VB.NET expert, but from what I understand and see, you're never actually using the "HeartbeatDTO" type in any of your methods decorated with a OperationContract attribute - right?
So I would imagine you probably also have to define that as a "ServiceKnownType" - try this:
<ServiceContract(Namespace:="tcp://localhost/")> _
<ServiceKnownType(GetType(HeartBeatDTO))> _
<ServiceKnownType(GetType(List(Of HeartBeatDTO)))> _
Public Interface iOperatorCommunication
Does that help?
Also: is there any particular reason you're using "Object" as type throughout your service contract? Couldn't you specify either HeartbeatDTO
or List(Of HeartbeatDTO)
?
UPDATE: could you possibly try - just for the sake of seeing if it works - to create a new service interface list this:
<ServiceContract(Namespace:="tcp://localhost/")> _
Public Interface iOperatorCommunicationStripped
<OperationContract()> _
Sub SendCommunication(ByVal sKey As String, ByVal oObject As List(Of HeartbeatDTO))
End Interface
In this case, your service operation is explicit about its data type and uses a list of HeartbeatDTO objects which are defined as data contracts. If you know create a client proxy for this service contract and call the method - does this work??
Marc
Upvotes: 6