【问题标题】:WCF - Generic List (of T)WCF - 通用列表(T)
【发布时间】:2009-10-09 17:14:13
【问题描述】:

我有一个自定义 DTO 列表,我正在尝试将其传递给 WCF 服务。

我收到以下错误:

尝试序列化参数 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://localhost/:oObject。这 InnerException 消息为“类型” 'TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat.HeartBeatDTOList' 带有数据合同名称 'HeartBeatDTOList:TEGE.ER.WorkFlowEngine.WFCommon.HeartBeat' 预计不会。添加任何类型不 静态已知到已知列表 类型 - 例如,通过使用 KnownTypeAttribute 属性或由 将它们添加到已知类型列表中 传递给 DataContractSerializer。'。 请参阅 InnerException 了解更多信息 详情。

【问题讨论】:

    标签: wcf serialization generic-list


    【解决方案1】:

    如果您有自定义集合类型,您可能需要使用特殊属性来装饰那些 - 请参阅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 对象列表。如果您知道为此服务合同创建一个客户端代理并调用该方法 - 这行得通吗??

    马克

    【讨论】:

    • 哇...这看起来确实像我需要的...我是将它添加为一个新类,还是修改我的 DTO 类以使用该 DataContract 而不是当前的?
    • 没关系...读得不够远,看起来像一个单独的课程。让我试试看。
    • 这是我添加的内容: _ Public Class HeartBeatList Inherits List(Of HeartBeatDTO) End Class ...但这似乎没有这样做...我也尝试更新服务合同: _
    • 我实际上真的希望服务是类型无知的,这就是我将接口作为对象保留的原因。我也尝试过更改界面,但这似乎没有帮助。
    • 我仍然遇到同样的错误......即使我尝试了所有这些。不知道(也仔细检查了服务参考)它在哪里得到:“不希望使用数据合同名称 'ArrayOfHeartBeatDTO:schemas.datacontract.org/2004/07/…'。”
    猜你喜欢
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多