WCF - 通用列表(T)

发布于 2024-08-07 04:14:18 字数 2459 浏览 2 评论 0原文

我有一个自定义 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]]”,其中包含数据合同名称不应为“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 详细信息。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤者何惧 2024-08-14 04:14:18

如果您有自定义集合类型,则可能需要使用特殊属性来修饰它们 - 请参阅 关于 CollectionDataContract 的 MSDN 文档

[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 对象的列表,这些对象定义为数据合同。如果您知道为此服务合同创建客户端代理并调用该方法 - 这有效吗?

马克

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文