题
我已经谷歌搜索了几个小时,我找不到任何处理我特定方案的人...
我想使用WCF服务合同中的接口来轻松地从电线两端使用的类中进行服务。这将使我们能够拥有一个仅包含服务和数据合同(只是接口)的低级组件,我们可以将其交给顾问。在电线的末端,他们可以实例化实现我们数据合同接口的数据类,将其通过电线发送给我们,然后我们的WCF服务将转换/cast/任何传入的数据 我们的 实现相同接口的数据类的版本。
这是一个例子。 IDataContract
包含我想通过电线传输的裸露信息。端点和其他WCF特定的配置都是默认内容(我的问题可能在其中,因此,如果我需要更改事物,我可以包含更多内容)。
编辑: :我包含了更多代码,并重命名了几个类,以帮助它减少混乱。 DatacontractAttributes的名称和名称空间添加以及配置文件中的两个部分是基于来自的信息的新添加 这篇博客文章. 。如果我切换到抽象基类而不是接口, 有用. 。但是,如果可能的话,我想将此与接口一起工作。
共享库(我的代码,与客户作者共享):
public interface IDataContract
{
string MyProperty { get; set; }
}
[ServiceContract]
public interface ITestService
{
[OperationContract]
IDataContract TestSharedInterface(IDataContract clientData);
}
客户代码(他们的):
[DataContract(Name = "IDataContract", Namespace = "http://services.sliderhouserules.com")]
public class ClientDataClass : IDataContract
{
[DataMember]
public string MyProperty { get; set; }
}
private static void CallTestSharedInterface()
{
EndpointAddress address = new EndpointAddress("http://localhost/ServiceContractsTest.WcfService/TestService.svc");
ChannelFactory<ITestService> factory = new ChannelFactory<ITestService>("ITestService", address);
ITestService proxy = factory.CreateChannel();
((IClientChannel)proxy).Open();
IDataContract clientData = new ClientDataClass() { MyProperty = "client data" };
IDataContract serverData = proxy.TestSharedInterface(clientData);
MessageBox.Show(serverData.MyProperty);
}
客户端配置:
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="ServiceContractsTest.Contracts.DataContracts.IDataContract, ServiceContractsTest.Contracts">
<knownType type="ServiceContractsTest.WcfClient.ClientDataClass, ServiceContractsTest.WcfClient"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
服务器代码(mine):
public class TestService : ITestService
{
public IDataContract TestSharedInterface(IDataContract clientData)
{
ServerDataClass convertedClientData = (ServerDataClass)clientData;
IDataContract serverData = new ServerDataClass() { MyProperty = convertedClientData.MyProperty + " + server data added" };
return serverData;
}
}
[DataContract(Name = "IDataContract", Namespace = "http://services.sliderhouserules.com")]
public class ServerDataClass : IDataContract
{
[DataMember]
public string MyProperty { get; set; }
}
服务器配置:
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="ServiceContractsTest.Contracts.DataContracts.IDataContract, ServiceContractsTest.Contracts">
<knownType type="ServiceContractsTest.WcfService.ServerDataClass, ServiceContractsTest.WcfService"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
我在客户呼叫上遇到序列化错误,抱怨已知类型。我只是错过了该客户端类中的一些元数据标记吗?我对甚至知道问题所在的地方感到茫然,因为我尝试了所有我能想到的搜索,而且似乎没有人处理这种特定情况。
基本上,我想要 ClientDataClass
序列化 <IDataContract><MyProperty>client data</MyProperty></IDataContract>
然后能够将其化为 ServerDataClass
实例。似乎应该有可能。
解决方案
如果您的数据合同是界面,则WCF不知道要为传入请求实例化的对象。在所有添加服务参考读取WSDL并根据WSDL中的类型信息生成新类,因此无需与服务中的类相同。
其他提示
这个博客为我提供了正确的方向,可以找到解决问题的解决方案。其实我的场景完全相同 Sliderhouserules 在他的帖子中描述。
但是在我的情况下,我不能使用任何摘要或基类来继承。因此,我使用Typeshelper类来读取Datacontractserializer after部分,并将相关类型传递给WCF服务。
namespace ExampleNamespace
{
public interface IJustAInstance { }
[ServiceContract]
[ServiceKnownType("GetKnownTypes", typeof(ExampleNamespace.TypesHelper))]
public interface ICreateInstance
{
IJustAInstance CreateInstance();
}
public static class TypesHelper
{
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
{
DataContractSerializerSection section = (DataContractSerializerSection)
ConfigurationManager.GetSection(
"system.runtime.serialization/dataContractSerializer");
if (dataContractSerializerSection != null)
{
foreach (DeclaredTypeElement item in dataContractSerializerSection.DeclaredTypes)
{
foreach (TypeElement innterItem in item.KnownTypes)
{
Type type = Type.GetType(innterItem.Type);
if (typeof(IJustAInstance).IsAssignableFrom(type ))
yield return type;
}
}
}
}
}
}
您可以创建一个基本合同,您的client Contract和ServerContract可以提供(作为属性),并且在创建客户client Contract或ServerContract的新实例时可以在相应的构造函数中使用。然后,您只需要将基本合同添加到您的共享LIB中。