3

私のサービスには、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

サービス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内)にそのプロパティがなくなります。そのため、サービスはその例外をスローします。Web.configファイルで(KnownTypeAttributeを介して)指定した場合でも、抽象クラスTransactionItemへの参照が欠落しているようです。それを解決する方法は?

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 に答える