WCF - 通用列表(T)
我有一个自定义 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您有自定义集合类型,则可能需要使用特殊属性来修饰它们 - 请参阅 关于 CollectionDataContract 的 MSDN 文档:
这可能是问题所在吗?
更新:好的,感谢您发布界面。我不是 VB.NET 专家,但根据我的理解和观察,您实际上从未在任何用 OperationContract 属性修饰的方法中使用“HeartbeatDTO”类型 - 对吧?
所以我想你可能还必须将其定义为“ServiceKnownType” - 试试这个:
这有帮助吗?
另外:您在整个服务合同中使用“对象”作为类型是否有任何特殊原因?您无法指定
HeartbeatDTO
或List(Of HeartbeatDTO)
吗?更新:您是否可以尝试 - 只是为了看看它是否有效 - 创建一个新的服务接口列表:
在这种情况下,您的服务操作对其数据类型是明确的,并使用 HeartbeatDTO 对象的列表,这些对象定义为数据合同。如果您知道为此服务合同创建客户端代理并调用该方法 - 这有效吗?
马克
If you have custom collection types, you might need to decorate those with a special attribute - see the MSDN docs on CollectionDataContract:
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:
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
orList(Of HeartbeatDTO)
?UPDATE: could you possibly try - just for the sake of seeing if it works - to create a new service interface list this:
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