2009-06-10 11 views
8

タイプがあります。Data<TKey>としましょう。私はまたタイプObjectのタイプ(それはWrapperと呼ぶことができます)を受け入れるWCFサービス契約を持っています。彼らは両方のファイルをconfigの既知のタイプで構成されている一般的なconfigのWCF既知の型を指定する方法は?

[DataContract] 
public class IntData : Data<int> { /*empty*/ } 

[DataContract] 
public class LongData : Data<long> { /*empty*/ } 

[DataContract] 
public class Data<TKey> { ... } 

[DataContract] 
public class Wrapper 
{ 
    [DataMember] 
    public object DataItem { get; set; } 
} 

今私は、2つのクラスIntDataLongDataを送信しています。設定は次のようになります。

<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="Wrapper, TheirAssembly"> 
      <knownType type="IntData, MyAssembly"/> 
      <knownType type="LongData, MyAssembly"/> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
</configuration> 

この時点ですべて正常です。

しかし、私は第3のタイプを追加しようとしています。不要な空の.NETクラスIntDataLongDataが好きではありません。それらが存在するのは...

WCF設定でジェネリックタイプを指定する方法がわかりません!

このようなことをしたいのですが、正確な構文がわかりません。

<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="Wrapper, TheirAssembly"> 
      <!-- this syntax is wrong --> 
      <knownType type="Data{System.Int32}, MyAssembly"/> 
      <knownType type="Data{System.Int64}, MyAssembly"/> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
</configuration> 

正しい構文は何ですか?

(それは私のタイプではないと私はWrapper[KnownType(...)]属性を置くことができないことにも注意してください。コンフィグは唯一の方法であると思われる。)

EDIT

barettaの答え@うまく働きました。

Type 'MyAssembly.Data`1[System.Int64]' cannot be added to list of known types since another type 'MyAssembly.Data`1[System.Int32]' with the same data contract name ' http://www.mycompany.com/MyAssembly:Data ' is already present.

は、私は元の質問でそれを言及しなかったが、私のタイプは、明示的なデータコントラクト名を持っている:最初に、私はこのエラーを受け取ったことに注意してください。このような何か:私は属性からNameプロパティ値を削除するまで

[DataContract(Name = "Data")] 
public class Data<TKey> { ... } 

は、上記のエラーが発生しました。それは他の誰かを助けることを望む。私はこのシナリオでどんなフォーマットが働くか分からない。これらはそうではありませんでした:

[DataContract(Name = "Data\`1")] 
[DataContract(Name = "Data{TKey}")] 

誰でもこの方法を知っていますか?

EDIT正しい構文が実際にあることを指摘し@barettaに再び2

ありがとう:

[DataContract(Name = "Data{0}")] 
+0

ええ、私は知っている!私は私の答えを編集 – baretta

答えて

18

文字列がこのパターンに従っている場合、一般的なタイプは、文字列からインスタンス化可能である。続く「`」の文字、続い クラス名タイプパラメータの数(この場合は1)、続いて "[]"で囲まれたタイプパラメータ、型パラメータセパレータとしてコンマを使用します。

<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="Wrapper, TheirAssembly"> 
      <!-- this syntax is all good --> 
      <knownType type="Data`1[System.Int32], MyAssembly"/> 
      <knownType type="Data`1[System.Int64], MyAssembly"/> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
</configuration> 

編集:私はまた、アセンブリ情報は、(それがmscorlibでもののためのケースではありませんalthoug)タイプ・パラメータに指定する必要がある場合は、ネストされた「[]」で使用されていることを、追加される場合があります。

<knownType type="Data`1[[System.Int32, mscorlib]], MyAssembly"/> 

編集:データ契約のジェネリック型の名前を、文字列形式のパターンを使用してカスタマイズできます。デフォルトでは

[DataContract(Name = "Data{0}")] 
public class Data<TKey> 
{...} 

、データ<のInt32のために生成された名前>のタイプは「HJ67AK7Y」 は、文字列から生成されたハッシュである「DataOfInt32HJ67AK7Y」のようなもの、である「URN:デフォルト」、またはあなたの名前空間あなたが何かを持っているなら、クラス。しかし、 "データ{0}"は "DataInt32"という名前を付けます。

さらにhere。ページの下にある「汎用タイプのデータ契約名のカスタマイズ」の部分をご覧ください。

+0

ありがとうBaretta。この簡潔な答えは、name属性の問題を整理すると完全に機能しました(私の編集を参照)。 –

+0

編集していただきありがとうございます。これは素晴らしい答えです。私が2度投票することができたら、私は –

+0

DataContractの名前をカスタマイズするためのヒントを+1します。ありがとう! – Dennis

5

hereからの...

Known types can also be defined in config as shown below.

<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="MyCompany.Library.Shape`1, 
       MyAssembly, Version=2.0.0.0, Culture=neutral, 
       PublicKeyToken=XXXXXX, processorArchitecture=MSIL"> 
      <knownType type="MyCompany.Library.Circle`1, 
         MyAssembly, Version=2.0.0.0, Culture=neutral, 
         PublicKeyToken=XXXXXX, processorArchitecture=MSIL"> 
        <parameter index="0"/> 
      </knownType> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
</configuration> 

The above config specifies that the generic parameter for Circle is the same as the generic parameter for the declared type Shape. The config allows the definition of known type of arbitrary complexity. For example if it is needed to define Circle< Dictionary< string, T >> as the known type of Shape< T > (of course this is purely academic) it can be done as follows.

<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="MyCompany.Library.Shape`1, 
       MyAssembly, Version=2.0.0.0, Culture=neutral, 
       PublicKeyToken=XXXXXX, processorArchitecture=MSIL"> 
      <knownType type="MyCompany.Library.Circle`1, 
         MyAssembly, Version=2.0.0.0, Culture=neutral, 
         PublicKeyToken=XXXXXX, processorArchitecture=MSIL"> 
        <parameter type="System.Collections.Generic.Dictionary`2"> 
         <parameter type="System.String"/> 
         <parameter index="0"/> 
        </parameter>     
      </knownType> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
</configuration> 

Note the use config element “parameter” with the attributes ‘type’ and ‘index’.

関連する問題