2011-05-25 58 views
2

我有一个WCF合约概述了一个测试方法,它使用protobuf-net仅通过WCF返回一个类的实例。我可以在测试应用程序中序列化和反序列化,但是当我通过WCF发出请求时,类实例存在,但其所有属性均为null。Protobuf-net WCF响应为空

下面是相关的配置文件和类定义:

[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的空白实例,并遍历返回的数据,但从不设置任何属性。

哦,我用Mex生成一个代理。

编辑

这里是MEX生成的类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)); 
     } 
    } 
} 
+0

你能展示Mex生成的代理吗?有办法强制代理玩好,但我需要看到它。特别是,我在标记DataMember的成员之后,以及他们的属性 – 2011-05-25 23:04:20

+0

我发布了上面为TestClass生成的代码。 – 2011-05-26 15:12:42

回答

0

权利;墨西哥/一代没有包括数字,但你可以添加它们。在一个单独的代码文件(同一个命名空间),加

[ProtoContract] 
[ProtoPartialMember(1, "TestInt")] 
[ProtoPartialMember(2, "TestString")] 
partial class TestClass {} 

有时WCF帮助,有时它是一个痛苦(注意它的工作原理很容易,如果你有在两端共享DTO组装)。

有时WCF给每个数据成员右侧上下的数字,但关闭的情况的1 - 如果恰好有你可以用它来只是告诉protobuf的与偏移使用这些数字的好办法。

+0

Welllll,在这里不能指责WCF。使用自定义序列化属性(即ProtoMember vs. DataMember)意味着proto缓冲区behvior实现将负责通过实现IWsdlExportExtension为WSDL生成适当的模式细节。由于它不是,它会默认为会员的字母顺序。 – 2011-05-26 17:18:57

+0

@Drew,为了这个双重目的,protobuf-net从DataContract/DataMember属性中获得完美的工作:) – 2011-05-26 17:53:20

+0

@Drew - 然而,那个接口对我来说是一个新接口;我会看看 – 2011-05-26 17:53:56

0

我觉得你在这里打有名的互操作性问题。请看我对这篇文章的回答: At client side, return value of WCF Operation Contract is null ! Any solution?

您需要识别客户端代码所需的Soap消息,并将正确的代码与服务返回的Soap消息同步。

在这个例子中,可以识别客户期望如何按照格式化响应消息,

a. creating Service stub from WSDL using WSDL /serverInterface 
b. Create a class implimenting the Service stub 
c. Host the WebService in IIS and browse the help page 
d. Click on operation called from list. 
e. Help page shows the expected request and response soap message 
+0

在这种情况下,*不会*(完全)显示基本的预期格式...除非你可以解码/编码头部的protobufs :) – 2011-05-25 23:06:44