繁体   English   中英

使用NetDataContractSerializer将Guid传递给WCF服务

[英]Passing Guid to WCF service with NetDataContractSerializer

我已经创建了合同

[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

完整的源代码在这里

编辑:此问题与发送指南的效率无关,像这样 ,主要与使用NetDataContractSerializer有关。

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

因此, DataContractSerializer用于客户端。

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

您正在服务器端使用自定义序列化程序作为NetDataContractSerializer NetDataContractSerializerDataContractSerializer之间的区别在于,序列化添加了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();
        }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM