我需要使用标准wsdl调用webservice操作,但客户端和服务器中的数据对象必须不同。
在公共库中使用数据对象的接口,在客户端和服务器中为它创建代理类。
然后,我正在使用接口声明操作合同,但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的Sample project on GitHub
答案 0 :(得分:2)
我用合约创建了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/" )]
PS。我可以根据要求提供完整的VS解决方案。
答案 1 :(得分:0)
根据ServiceKnownTypeAttribute
(MSDN documentation),我根据情况改变了预期的类型。主要想法在类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;
}
}
您必须在ServiceKnownType
知道ServiceContract
课程的界面中加入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的最终代码Sample project on GitHub