2011-05-25 64 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