Dot-Net

如何在配置中指定通用的 WCF 已知類型?

  • July 4, 2009

我有一個類型,我們稱之為Data<TKey>Wrapper我還有一個 WCF 服務契約,它接受具有類型屬性的類型(讓我們稱之為) Object(出於我不會討論的原因,這不是可選的)。

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

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

現在我正在發送兩個IntData課程LongData

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

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

它們都在已知類型配置文件中配置。配置類似於這樣:

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

在這一點上,一切正常。

但我即將添加第三種類型,我不喜歡不必要的空 .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>

什麼是正確的語法?

(還要注意,我不能設置[KnownType(...)]屬性,Wrapper因為它不是我的類型。配置似乎是唯一的方法。)

編輯

@baretta 的回答效果很好。但是請注意,最初我收到此錯誤:

鍵入“MyAssembly.Data”1

$$ System.Int64 $$’ 無法添加到已知類型列表,因為另一種類型 ‘MyAssembly.Data`1$$ System.Int32 $$’ 具有相同的數據契約名稱 ’ http://www.mycompany.com/MyAssembly:Data ’ 已經存在。

我在原始問題中沒有提到它,但我的類型有一個明確的數據契約名稱。像這樣的東西:

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

Name直到我從屬性中刪除了屬性值,才會出現上述錯誤。希望也能幫助別人。我不知道在這種情況下哪種格式有效。這些沒有:

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

有人知道怎麼做嗎?

編輯 2

再次感謝@baretta,他指出正確的語法實際上是:

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

如果字元串遵循以下模式,則泛型類型可以從字元串中實例化: 類名後跟一個“`”字元,然後是類型參數的數量(在本例中為 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 中的東西不是這種情況),然後嵌套“

$$ $$“ 用來。

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

編輯:您可以使用字元串格式模式自定義數據協定中通用類型的名稱。

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

預設情況下,為 Data<Int32> 類型生成的名稱類似於“DataOfInt32HJ67AK7Y”,其中“HJ67AK7Y”是從字元串“urn:default”或類的命名空間(如果有)生成的雜湊值。但是“Data{0}”會給它命名為“DataInt32”。

更多在這裡。查看頁面下方的“自定義通用類型的數據協定名稱”部分。

引用自:https://stackoverflow.com/questions/976811