WCF - 通用列表(T)

时间:2009-10-09 17:14:14

标签: wcf serialization generic-list

我有一个我试图传递给WCF服务的自定义DTO列表。

我收到以下错误:

  

尝试序列化参数tcp:// localhost /:oObject时出错。 InnerException消息是'Type'System.Collections.Generic.List`1 [[TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat.HeartBeatDTO,WFCommon,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]'with data合同名称'ArrayOfHeartBeatDTO:TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat'不是预期的。将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。有关详细信息,请参阅InnerException。

我有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

更新: 这是新的错误消息:

  

尝试时出错   序列化参数   TCP://本地主机/:oObject。该   InnerException消息是'Type   'TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat.HeartBeatDTOList'   与数据合同名称   'HeartBeatDTOList:TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat'   不是预期的。不添加任何类型   静态地知道已知的名单   类型 - 例如,通过使用   KnownTypeAttribute属性或   将它们添加到已知类型列表中   传递给DataContractSerializer。'。   有关更多信息,请参阅InnerException   的信息。

1 个答案:

答案 0 :(得分:6)

如果您有自定义集合类型,则可能需要修饰具有特殊属性的类型 - 请参阅MSDN docs on CollectionDataContract

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

这可能是问题吗?


更新:好的,感谢发布界面。我不是VB.NET专家,但从我的理解和看到,你在使用OperationContract属性修饰的任何方法中实际上都没有使用“HeartbeatDTO”类型 - 对吗?

所以我想你可能还需要将其定义为“ServiceKnownType” - 试试这个:

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

这有帮助吗?

另外:您是否有任何特殊原因在整个服务合同中使用“对象”作为类型?你既不能指定HeartbeatDTOList(Of HeartbeatDTO)吗?

更新:您是否可以尝试 - 只是为了查看它是否有效 - 创建一个新的服务接口列表:

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

在这种情况下,您的服务操作是明确的数据类型,并使用HeartbeatDTO对象列表,这些对象被定义为数据协定。如果您知道为此服务合同创建客户端代理并调用该方法 - 这是否有效?

马克