我的服务有一些问题,关于KnownType和继承。我已经阅读了几乎所有类似的问题,但我仍然没有找到解决方案。我会试着解释一下:
这是我的界面:
[ServiceContract(Namespace = "MyNameSpace.Components.Web")]
public interface ITransactionsService
{
[OperationContract(Name = "Put")]
void Put(WebTransactionItem wtransactionItem);
}
这是我的DataContract:
[DataContract(Namespace = "MyNameSpace.Components.Web")]
public class WebTransactionItem
{
[DataMember]
public TransactionItem items { get; set; }
[DataMember]
public TransactionItem[] TransactionItemList { get; set; }
}
TransactionItem 是(另一个)程序集中提供的抽象类。
在客户端项目中使用相同的程序集,因此我在客户端和服务器中都引用了相同的类型。
在客户端,经过一些操作(读取文件等等),我有一个继承自 TransactionItem 的对象数组,说:
transItems[0] => TransactionHeaderObject
transItems[1] => TransactionTrailerObject
在Service Web.config中我添加了
<dataContractSerializer>
<declaredTypes>
<add type="Namespace.TransactionItem, Assemblyname, Version=1.4.1.2, Culture=neutral, PublicKeyToken=null">
<knownType type="Namespace.TransactionHeader, Assemblyname, Version=1.4.1.2, Culture=neutral, PublicKeyToken=null"/>
<knownType type="Namespace.TransactionTrailer, Assemblyname, Version=1.4.1.2, Culture=neutral, PublicKeyToken=null"/>
</add>
</declaredTypes>
</dataContractSerializer>
当然我可以在[Datacontract]装饰器上使用 KnownTypeAttribute 。
如果在配置服务参考(在客户端)项目服务参考)我检查(默认选中)引用程序集中的重用类型标志,我能够写入我的代码:
MyNameSpace.Components.Web.WebTransactionItem wtItem =
new MyNameSpace.Components.Web.WebTransactionItem(){
TransactionItemList = transItems}
我可以毫无问题地致电服务部门。那么问题是什么?
问题是,如果我删除
[DataMember]
public TransactionItem items { get; set; }
属性(我不希望客户端使用抽象类)来自DataContract服务进入异常:
尝试序列化参数MyNameSpace.Components.Web时出错:wtransactionItem。 Innerexception消息: 输入合约名称为'TransactionHeader:http://schemas.datacontract.org/2004/07/Assemblyname'的'Assemblyname.TransactionHeader'不是预期的。
现在,据我所知,当我没有在服务中指定类型 TransactionHeader (继承TransactionItem)时会发生这种情况,但我这样做(请参阅Web.Config服务的文件) ,我也尝试过使用knowntypeAttribute)!!
我也注意到在客户端项目中自动生成的 Reference.cs 类中,在第一种情况下(当我离开时)
[DataMember]
public TransactionItem items { get; set; }
属性)
编码:
[KnownTypeAttribute(typeof(Assemblyname.TransactionHeader))]
[KnownTypeAttribute(typeof(Assemblyname.TransactionTrailer))]
生成的部分类之上。这允许继承类的序列化,但是如果我删除了Service中的属性,则部分类(在Reference.cs内)不再具有它,这就是Service抛出该异常的原因。它就像是错过了对抽象类 TransactionItem 的引用,即使我已经在Web.config文件中指定了它(也通过KnownTypeAttribute。)。如何解决?
答案 0 :(得分:0)
您是否尝试过“ServiceKnownTypeAttribute”?
要序列化或反序列化类型,WCF需要通过此属性或服务合同本身了解具体的基类。
当您的服务合同中有一个接口(或者也可能是一个抽象类)时,序列化器在仅使用KnownTypeAttribute时会遗漏某些内容。
如果您想从另一个程序集注册类型,您可能必须提供一个返回已知类型列表的方法并注册此方法:
[ServiceKnownType("GetKnownTypes", typeof(Helper))]
请参阅http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceknowntypeattribute.aspx。