【问题标题】:Passing Guid to WCF service with NetDataContractSerializer使用 NetDataContractSerializer 将 Guid 传递给 WCF 服务
【发布时间】:2015-12-20 12:43:57
【问题描述】:

我已经创建了合同

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

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

属性NetDataContractAttribute 描述here。 当我打电话给PassGuid 时出现错误:

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

PassInt 可以正常调用。

完整源代码here.

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

【问题讨论】:

标签: c# .net wcf serialization netdatacontractserializer


【解决方案1】:

您在服务器端将自定义序列化程序用作NetDataContractSerializerNetDataContractSerializerDataContractSerializer的区别在于序列化增加了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();
        }

您也可以通过配置文件附加行为。

【讨论】:

    【解决方案2】:

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

    因此在客户端使用DataContractSerializer

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多