[英]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
。 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();
}
您还可以通过配置文件使用附加行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.