如何在WCF中使用接口作为数据契约
本文关键字:接口 数据 契约 WCF | 更新日期: 2023-09-27 18:07:56
我需要使用标准wsdl调用web服务操作,但客户端和服务器中的数据对象必须不同。
为公共库中的数据对象使用接口,在客户端和服务器中为其创建代理类。
然后,我使用接口声明操作契约,但是WCF不识别它。
我已经尝试使用DataContractSerializerBehavior和设置knownTypes,没有成功。
有人能帮帮我吗?我附上了一份完整的解决方案和更多的细节。
public interface Thing
{
Guid Id {get;set;}
String name {get;set;}
Thing anotherThing {get;set;}
}
[DataContract]
public class ThingAtServer: BsonDocument, Thing // MongoDB persistence
{
[DataMember]
Guid Id {get;set;}
//...
}
[DataContract]
public class ThingAtClient: Thing, INotifyPropertyChanged // WPF bindings
{
[DataMember]
Guid Id {get;set;}
//...
}
[ServiceContract]
public interface MyService
{
[OperationContract]
Thing doSomething(Thing input);
}
点击这里查看TestCases在GitHub上的样例项目
我已经创建了WCF服务与合同:
[OperationContract]
CompositeTypeServer GetDataUsingDataContract( CompositeTypeServer composite );
我的CompositeTypeServer
是这样的:
[DataContract( Namespace = "http://enes.com/" )]
public class CompositeTypeServer
{
[DataMember]
public bool BoolValue { get; set; }
[DataMember]
public string StringValue { get; set; }
}
然后我创建了类型为CompositeTypeClient
的客户端项目:
[DataContract( Namespace = "http://enes.com/" )]
public class CompositeTypeClient
{
[DataMember]
public bool BoolValue { get; set; }
[DataMember]
public string StringValue { get; set; }
}
然后我将引用添加到我的服务并选择重用类型。一切都很顺利。我可以在客户端使用CompositeTypeClient
。
因此,技巧是为DataContract指定Namespace,以便它们在客户端和服务端都匹配。
[DataContract( Namespace = "http://enes.com/" )]
p。我可以根据要求提供完整的工作VS解决方案。
基于ServiceKnownTypeAttribute
(MSDN文档),我根据情况更改了预期的类型。主要思想在XHelper
类中实现,负责根据情况返回正确的Type[]
:
public static class XHelper
{
public static Boolean? IsClient = null;
public static Type[] ClientTypes;
public static Type[] ServerTypes;
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider pProvider)
{
if (!IsClient.HasValue)
throw new Exception("Invalid value");
if (IsClient.Value)
return ClientTypes;
return ServerTypes;
}
}
您必须在具有ServiceContract
的接口中包含ServiceKnownType
标记才能知道XHelper
类。
[ServiceContract(Namespace = MyProxyProvider.MyNamespace)]
[ServiceKnownType("GetKnownTypes", typeof(XHelper))]
public interface MyService
{
[OperationContract]
Thing2 CopyThing(Thing1 input);
}
在测试单元开始时,它被告知每种情况下正确的Type[]
:
[AssemblyInitialize]
public static void TestInitialize(TestContext pContext)
{
XHelper.ClientTypes = new Type[] { typeof(Thing1ProxyAtClient), typeof(Thing2ProxyAtClient), typeof(Thing2ProxyAtClient) };
XHelper.ServerTypes = new Type[] { typeof(Thing1ProxyAtServer), typeof(Thing2ProxyAtServer), typeof(ThingNProxyAtServer) };
}
点击这里查看TestCases在GitHub上的最终代码示例项目