Protobuf-net WCF 响应为空 [英] Protobuf-net WCF response is empty
问题描述
我有一个 WCF 合同,其中概述了一个测试方法,该方法仅使用 protobuf-net 在 WCF 中返回一个类的实例.我可以在测试应用程序中序列化和反序列化,但是当我通过 WCF 发出请求时,响应类实例存在,但其所有属性都为空.
I have a WCF Contract outlining a test method that just returns an instance of a class across WCF using protobuf-net. I can serialize and deserialize in a test application but when I make the request via WCF the response the class instance exists, but all its properties are null.
以下是相关的配置文件和类定义:
Here are the relevant config files and class definitions:
[ProtoContract]
public class TestClass
{
[ProtoMember(1)]
public int TestInt { get; set; }
[ProtoMember(2)]
public string TestString { get; set; }
}
...
[ServiceContract]
public interface ITestService
{
[OperationContract]
[ProtoBehavior]
TestClass RunTest(int x);
}
...
<extensions>
<behaviorExtensions>
<add name="protobuf" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=1.0.0.282, Culture=neutral, PublicKeyToken=257b51d87d2e4d67" />
</behaviorExtensions>
</extensions>
<endpointBehaviors>
<behavior name="Proto.Default.EndpointBehavior">
<protobuf />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Proto.Default.ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata />
<serviceAuthorization principalPermissionMode="None" />
<serviceThrottling maxConcurrentCalls="250"
maxConcurrentSessions="200"
maxConcurrentInstances="10" />
</behavior>
</serviceBehaviors>
...
<services>
<service name="WcfTestService" behaviorConfiguration="Proto.Default.ServiceBehavior">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ITestService" contract="ITestService" behaviorConfiguration="Proto.Default.EndpointBehavior" />
<endpoint address="mex" binding="customBinding" bindingConfiguration="myMexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:2517/TestService" />
</baseAddresses>
</host>
</service>
...
<client>
<endpoint address="net.tcp://localhost:2517/TestService"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ITestService"
contract="ITestService" name="TestService"
behaviorConfiguration="Proto.Default.EndpointBehavior">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
我可以调试服务并查看请求.创建并返回 TestClass 对象.我单步执行 protobuf-net 源代码并运行反序列化方法,它只创建一个空白的 TestClass 实例并遍历返回的数据但从未设置任何属性.
I can debug the service and see the request come across. The TestClass object is created and returned. I stepped through protobuf-net source code and the deserialize method runs and it just creates a blank instance of TestClass and iterates through the data that is returned but never sets any of the properties.
哦,我用 Mex 来生成代理.
Oh, I used Mex to generate a proxy.
编辑
这是为 TestClass 生成的 MEX 类
Here is the MEX generated class for TestClass
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="TestClass", Namespace="http://schemas.datacontract.org/2004/07/TestProject")]
[System.SerializableAttribute()]
public partial class TestClass : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {
[System.NonSerializedAttribute()]
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private int TestIntField;
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string TestStringField;
[global::System.ComponentModel.BrowsableAttribute(false)]
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
get {
return this.extensionDataField;
}
set {
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public int TestInt {
get {
return this.TestIntField;
}
set {
if ((this.TestIntField.Equals(value) != true)) {
this.TestIntField = value;
this.RaisePropertyChanged("TestInt");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string TestString {
get {
return this.TestStringField;
}
set {
if ((object.ReferenceEquals(this.TestStringField, value) != true)) {
this.TestStringField = value;
this.RaisePropertyChanged("TestString");
}
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
推荐答案
Right;Mex/generation 未包含这些数字,但您可以添加它们.在单独的代码文件(相同命名空间)中,添加
Right; Mex/generation hasn't included the numbers, but you can add them. In a separate code file (same namespace), add
[ProtoContract]
[ProtoPartialMember(1, "TestInt")]
[ProtoPartialMember(2, "TestString")]
partial class TestClass {}
有时 WCF 会有所帮助,有时会很痛苦(请注意,如果两端都有共享的 DTO 程序集,它会很容易工作).
Sometimes WCF helps, sometimes it is a pain (note it works easy if you have a shared DTO assembly at both ends).
有时 WCF 会在每个 DataMember 上给出正确的数字,但按 1 计算 - 如果 发生,您可以使用一个调整来告诉 protobuf 使用带有偏移量的这些数字.
Sometimes WCF gives the right-ish numbers on each DataMember, but off-by-1 - if that happens there's a tweak you can use to just tell protobuf to use those numbers with an offset.
这篇关于Protobuf-net WCF 响应为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!