【问题标题】:Client Generated doesn't provide information about knowntype with third-partyClient Generated 不向第三方提供有关 knowntype 的信息
【发布时间】:2012-05-01 00:04:51
【问题描述】:

我的服务有一些关于 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

如果在 Configure Service Reference 中(在客户端项目 Service参考)我检查(默认检查)在引用的程序集中重用类型标志,我可以在我的代码中编写:

MyNameSpace.Components.Web.WebTransactionItem wtItem = 
   new MyNameSpace.Components.Web.WebTransactionItem(){ 
       TransactionItemList = transItems}

我可以毫无问题地调用服务。那么问题是什么?
问题是,如果我删除了

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

DataContract 中的属性(我不希望客户端使用抽象类)进入异常:

尝试序列化参数 MyNameSpace.Components.Web:wtransactionItem 时出错。内部异常消息: 不应键入合同名称为“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))]

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

【问题讨论】:

    标签: c# .net wcf inheritance known-types


    【解决方案1】:

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

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

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

    【讨论】:

    • 您好 Stefan,感谢您的回答。不幸的是,我也尝试了 ServiceKnownType 装饰器,它们都指定了所有涉及的类型(大约 20 种类型),正如你所建议的,但结果是一样的。我认为正如您所说:序列化程序遗漏了抽象类的某些内容。此外,我尝试不在客户端生成中使用相同的程序集(包含类型的程序集):这个技巧似乎有效,但我必须使用一些反射技巧,因为生成的类型显然不一样(即使它们实际上是 ;) )。
    猜你喜欢
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 2021-07-30
    • 2017-05-27
    • 1970-01-01
    • 2013-09-14
    • 2012-03-07
    相关资源
    最近更新 更多