我们正在使用ProtoBuff.NET和我们的WCF服务。 ProtoBehavour已应用于界面,ProtoContract已应用于该类& ProtoMember已应用于这些属性。
在客户端,我们已将protobuff行为添加到app.config,如下所示,但是当客户端通过WCF服务请求对象时,我们收到错误的线路类型错误。
删除服务上的ProtoBuff行为会导致服务正常工作。
任何人都可以了解正在发生的事情或指出我们正确的方向。
我们正在使用NET TCP绑定。
客户端配置
<behaviors>
<endpointBehaviors>
<behavior name="ProtoBufBehaviorConfig">
<ProtoBufSerialization/>
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="ProtoBufSerialization" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=2.0.0.480, Culture=neutral, PublicKeyToken=257b51d87d2e4d67"/>
</behaviorExtensions>
</extensions>
示例类
<DataContract()> <ProtoBuf.ProtoContract()> _
Public Class Product
Private _ID As String
<DataMember(Order:=1)> <ProtoBuf.ProtoMember(1)> _
Public Property ID As String
Get
Return _ID
End Get
Set(value As String)
_ID = value
End Set
End Property
Private _Name As String
<DataMember(Order:=2)> <ProtoBuf.ProtoMember(2)> _
Public Property Name As String
Get
Return _Name
End Get
Set(value As String)
_Name = value
End Set
End Property
Private _Supplier As Supplier
<DataMember(Order:=3)> <ProtoBuf.ProtoMember(3)> _
Public Property Supplier As Supplier
Get
Return _Supplier
End Get
Set(value As Supplier)
_Supplier = value
End Set
End Property
Private _Income_Group As Primary_Income_Group
<DataMember(Order:=4)> <ProtoBuf.ProtoMember(4)> _
Public Property Primary_Income_Group As Primary_Income_Group
Get
Return _Income_Group
End Get
Set(value As Primary_Income_Group)
_Income_Group = value
End Set
End Property
Private _Margin_Percentage As Decimal
<DataMember(Order:=5)> <ProtoBuf.ProtoMember(5)> _
Public Property Margin_Percentage As Decimal
Get
Return _Margin_Percentage
End Get
Set(value As Decimal)
_Margin_Percentage = value
End Set
End Property
Private _Cost_Price_exGST As Decimal
<DataMember(Order:=6)> <ProtoBuf.ProtoMember(6)> _
Public Property Cost_Price_exGST As Decimal
Get
Return _Cost_Price_exGST
End Get
Set(value As Decimal)
_Cost_Price_exGST = value
End Set
End Property
Private _Retail_Price_incGST As Decimal
<DataMember(Order:=7)> <ProtoBuf.ProtoMember(7)> _
Public Property Retail_Price_incGST As Decimal
Get
Return _Retail_Price_incGST
End Get
Set(value As Decimal)
_Retail_Price_incGST = value
End Set
End Property
Private _Active As Boolean
<DataMember(Order:=8)> <ProtoBuf.ProtoMember(8)> _
Public Property Active As Boolean
Get
Return _Active
End Get
Set(value As Boolean)
_Active = value
End Set
End Property
Private _Image As String
<DataMember(Order:=9)> <ProtoBuf.ProtoMember(9)> _
Public Property Image As String
Get
Return _Image
End Get
Set(value As String)
_Image = value
End Set
End Property
Private _Secondary_Income_Group As Secondary_Income_Group
<DataMember(Order:=10)> <ProtoBuf.ProtoMember(10)> _
Public Property Secondary_Income_Group As Secondary_Income_Group
Get
Return _Secondary_Income_Group
End Get
Set(value As Secondary_Income_Group)
_Secondary_Income_Group = value
End Set
End Property
End Class
服务器配置摘录
Dim TCPBinding As NetTcpBinding = New NetTcpBinding With { _
.PortSharingEnabled = True, _
.ListenBacklog = 5000, _
.ReaderQuotas = New System.Xml.XmlDictionaryReaderQuotas With {.MaxArrayLength = Integer.MaxValue, .MaxBytesPerRead = Integer.MaxValue, .MaxDepth = Integer.MaxValue, .MaxNameTableCharCount = Integer.MaxValue, .MaxStringContentLength = Integer.MaxValue}, _
.MaxConnections = 10000, _
.TransferMode = TransferMode.Buffered, _
.MaxBufferSize = Integer.MaxValue, _
.MaxReceivedMessageSize = Integer.MaxValue, _
.ReliableSession = New System.ServiceModel.OptionalReliableSession With {.Enabled = False}, _
.Security = New System.ServiceModel.NetTcpSecurity With { _
.Mode = SecurityMode.Transport, _
.Transport = New System.ServiceModel.TcpTransportSecurity With {.ProtectionLevel = Net.Security.ProtectionLevel.Sign, .ClientCredentialType = TcpClientCredentialType.Windows} _
} _
}
.....
Dim endpoint As ServiceEndpoint = ServiceHostObject.AddServiceEndpoint(Contract, TCPBinding, "")
endpoint(New ProtoBuf.ServiceModel.ProtoEndpointBehavior)
答案 0 :(得分:0)
如果您没有按照marc answer中的建议共享服务合同程序集,那么您需要一种方法让WCF在您的客户端代码中使用ProtoBuf序列化程序而不是WCF默认序列化程序。问题是服务契约中的ProtoBuf属性标记不会位于通常用于在客户端代码中生成服务代理的WSDL文档中。
答案 1 :(得分:0)
关于Marc的评论,他说有很多方法可以与SvcUtil或“添加服务参考”VS命令一起进行protobuf-net工作,我找到this帖子,他说:
重新订单= ......,值得查看内容;如果他们提出不同的数字,有办法通过部分类来解决这个问题 - 一个丑陋的黑客,但IIRC有ProtoPartialMember(或类似的)可以应用于类,但谈论个别成员(属性) /领域)。
然后有this帖子,他说:
有两种方法可以解决这个问题;第一个(也是最简单的)是使用WCF在客户端和服务器之间共享合同程序集的能力。如果您可以共享DTO图层,那么事情就会变得简单。
第二种是在客户端添加额外的标记以给它一个线索。您可以通过部分类来完成此操作,例如在单独的代码文件中(不要编辑生成的文件):
namespace YourNamespace {
[ProtoContract(DataMemberOffset = 1)] /* shift all DataMember orders */
public partial class tbEmployee {}
}
更明确的替代方案是:
namespace YourNamespace {
[ProtoPartialMember(1, "EmployeeID")]
[ProtoPartialMember(2, "EmployeeName")]
public partial class tbEmployee {}
}