2012-04-19 3 views
3

KnownTypeと継承について私のサービスにいくつか問題があります。私はほとんどすべての同様の質問を読んだが、私はまだ解決策を見いださなかった。私が説明しよう:これは私のDataContractです生成されたクライアントは、第三者に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(別の)組み立てに提供する抽象クラスであります。
同じアセンブリがクライアントプロジェクトで使用されているので、クライアントとサーバーの両方で同じ型が参照されています。クライアント側では
は、いくつかの操作(。etc.etcファイルの読み込み)した後、私はTransactionItemから継承するオブジェクトの配列を持っている、と言う:サービスのWeb.configで

transItems[0] => TransactionHeaderObject 
transItems[1] => TransactionTrailerObject 

を私はしました私は[のDataContract]デコレータに KnownTypeAttributeを使用している可能性が当然の

<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> 

を追加しました。

(クライアントプロジェクトのサービス参照で)設定サービス参照に私は(はデフォルトでチェックされている)をチェックした場合、私は私のコードで書くことができるよ
フラグ、参照アセンブリでリユースタイプ:

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で試しました)!また
私は

がコーディングされている(私は

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

プロパティを離れるとき) Reference.csにクラスが自動的に最初のケースでは、クライアントプロジェクトで生成されたことに気付きました:

[KnownTypeAttribute(typeof(Assemblyname.TransactionHeader))] 

[KnownTypeAttribute(typeof(Assemblyname.TransactionTrailer))] 

生成された部分クラスの上にあります。それは継承されたクラスの直列化を可能にしますが、サービス内のプロパティを削除すると、Reference.cs内の部分クラスにはそれ以上持っていないので、サービスでその例外がスローされます。それは抽象クラス TransactionItemへの参照がWeb.configファイルで(そしてKnownTypeAttributeを介して)指定されていても、それが欠けているようです。それを解決するには?

答えて

0

「ServiceKnownTypeAttribute」を試しましたか?
型をシリアル化または逆シリアル化するには、WCFは、この属性またはサービスコントラクト自体を介して、具体的な基本クラスを認識する必要があります。
サービスコントラクトにインターフェイス(またはおそらくは抽象クラス)がある場合、シリアライザはKnownTypeAttributeのみを使用すると何かを失います。
あなたが別のアセンブリから型を登録すると、あなたはprobaly既知のタイプのリストを返すメソッドを提供し、この方法を登録する必要があります。

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

http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceknowntypeattribute.aspxを参照してください。

+0

こんにちはステファン、答えに感謝します。残念ながら、_ServiceKnownType_デコレータは、関連するすべての型(約20種類)を指定していましたが、提案したように結果は同じです。シリアライザは、抽象クラスで何かを逃しています。また、私はクライアントの世代で同じアセンブリ(型を含むもの)を使用しないようにしました。トリックはうまくいくようですが、生成される型は明らかに同じではないため、リフレクショントリックを使用する必要がありますたとえ実際にあっても)))。 – kindaska

関連する問題