3

我的服务有一些关于 KnownType 和继承的问题。我已经阅读了几乎所有类似的问题,但我仍然没有找到解决方案。我将尝试解释:

这是我的界面:

[ServiceContract(Namespace = "MyNameSpace.Components.Web")]    
public interface ITransactionsService
{
    [OperationContract(Name = "Put")]        
    void Put(WebTransactionItem wtransactionItem);
}

这是我的数据合同:

[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 时出错。内部异常消息:类型 'Assemblyname.TransactionHeader' 合同名称为 'TransactionHeader:http://schemas.datacontract.org/2004/07/Assemblyname' 不是预期的。

现在,据我所知,当我没有在服务中指定类型TransactionHeader(继承 TransactionItem)时会发生这种情况,但我指定了(参见 Web.Config 服务的文件,我也尝试过使用 knowntypeAttribute)! !
我还注意到,在客户端项目中自动生成的Reference.cs类中,在第一种情况下(当我离开

[DataMember]
public TransactionItem items { get; set; }

财产)

被编码:

[KnownTypeAttribute(typeof(Assemblyname.TransactionHeader))]

[KnownTypeAttribute(typeof(Assemblyname.TransactionTrailer))]

在生成的部分类之上。这允许对继承的类进行序列化,但是如果我删除服务中的属性,则部分类(在 Reference.cs 中)不再具有它,这就是服务抛出该异常的原因。就像它错过了对抽象类TransactionItem的引用,即使我已经在 Web.config 文件中指定了它(也通过 KnownTypeAttribute。)。如何解决?

4

1 回答 1

0

您是否尝试过“ServiceKnownTypeAttribute”?
要序列化或反序列化一个类型,WCF 需要通过此属性或通过服务协定本身了解具体的基类。
当您的服务合同中有一个接口(或者可能还有一个抽象类)时,序列化程序在仅使用 KnownTypeAttribute 时会遗漏一些东西。
当您想从另一个程序集中注册类型时,您可能必须提供一个返回已知类型列表的方法并注册此方法:

 [ServiceKnownType("GetKnownTypes", typeof(Helper))]

请参阅http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceknowntypeattribute.aspx

于 2012-04-30T14:45:34.923 回答