Protobuf-net WCF响应为空

时间:2011-05-25 20:59:55

标签: wcf protobuf-net

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

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

[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源代码并运行deserialize方法,它只是创建一个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));
        }
    }
}

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

右; Mex / generation没有包含数字,但您可以添加它们。在单独的代码文件(相同的命名空间)中,添加

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

有时候WCF会有所帮助,有时候会很痛苦(如果两端都有共享的DTO程序集,请注意它很容易。)

有时WCF会在每个DataMember上给出正确的数字,但会在1之前给出 - 如果发生,那么可以使用一个调整来告诉protobuf使用带偏移的数字。