1

我已经创建了合同

[ServiceContract]
public interface ITestService
{
    [OperationContract]
    [NetDataContract]
    void PassGuid(Guid id);

    [OperationContract]
    [NetDataContract]
    void PassInt(int id);
}

这里NetDataContractAttribute描述的属性。当我打电话时,我收到一个错误:PassGuid

附加信息:格式化程序在尝试反序列化消息时抛出异常:尝试反序列化参数http://tempuri.org/:id时出错。InnerException 消息是“XML 元素”“ http://tempuri.org/:id ”不包含预期的属性“ http://schemas.microsoft.com/2003/10/Serialization/:Type ”。反序列化器不知道要反序列化哪种类型。检查被序列化的类型是否与被反序列化的类型具有相同的合同。有关更多详细信息,请参阅 InnerException。

但是PassInt可以毫无错误地调用。

完整的源代码在这里

编辑:这个问题不是关于发送 guid 的效率,比如这个,它主要是关于使用 NetDataContractSerializer。

4

2 回答 2

2

NetDataContractSerializer您在服务器端使用自定义序列化程序。NetDataContractSerializer和的区别在于DataContractSerializer序列化增加了Types的附加信息。

例如 DatacontractsSerializer序列化为:

<Customer xmlns="http://www.contoso.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <FirstName>Zighetti</FirstName>
  <ID>101</ID>
  <LastName>Barbara</LastName>
</Customer>

NetDataContractSerializer将相同的对象序列化为:

<Customer z:Id="1" z:Type="NetDCS.Person" z:Assembly="NetDCS, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns="http://www.contoso.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
  <FirstName z:Id="2">Zighetti</FirstName>
  <ID>101</ID>
  <LastName z:Id="3">Barbara</LastName>
</Customer>

诱导更多类型特定信息。

在您的情况下,服务器知道NetDataContractSerializer但客户端不知道。您必须通过将其放入共享代码库来与客户端共享此行为。然后,您可以使用以下代码将此 enw 行为添加到客户端:

       using (var client = new TestServiceClient())
        {
            // Get the channel factory
            var factory = client.ChannelFactory;

            // Attach the behavior
            foreach (OperationDescription desc in factory.Endpoint.Contract.Operations)
            {
                DataContractSerializerOperationBehavior dcsOperationBehavior = desc.Behaviors.Find<DataContractSerializerOperationBehavior>();
                if (dcsOperationBehavior != null)
                {
                    int idx = desc.Behaviors.IndexOf(dcsOperationBehavior);
                    desc.Behaviors.Remove(dcsOperationBehavior);
                    desc.Behaviors.Insert(idx, new WcfClient.NetDataContractAttribute.NetDataContractSerializerOperationBehavior(desc));
                    //return true;

                }
            }

            // pass
            client.PassInt(0);
            // fail
            client.PassGuid(Guid.NewGuid());
            client.Close();
        }

您还可以通过配置文件使用附加行为。

于 2015-09-24T19:27:36.277 回答
1

问题是客户端自动生成的合同(见文件WcfClient\Service References\TestService\Reference.cs)没有[NetDataContract]属性。

因此DataContractSerializer在客户端使用。

为了NetDataContractSerializer在客户端和服务器上工作,您需要在客户端有正确的合同定义(通过引用服务器 DLL 或通过将合同提取到单独的 DLL 中)。然后您将不得不创建自己的代理类(继承自ClientBase<ITestService>)而不是自动生成的类(或者ChannelFactory<ITestService>根本不使用任何代理类)。

于 2015-09-24T15:04:04.147 回答