2010-03-13 70 views
7

我有一個WCF服務,其中有一些操作接受非泛型基類作爲參數。在WCF中使用自定義的DataContractResolver,傳輸涉及泛型的繼承樹

[DataContract] 
class Foo 
{ ... } 

這個基類又繼承,通過這樣的泛型類作爲

[DataContract] 
class Bar<T> : Foo 
{ ... } 

爲了得到這個工作,我以前有註冊的Foo類KnownTypes,並有這些包括Bar的所有可能的變體(如Bar<string>,Bar<int>甚至Bar<List<string>>)。但是,使用.NET 4中的DataContractResolver,我應該能夠構建一個正確存儲(並恢復)類的解析器。

我的問題:

  1. 是否DataContractResolvers通常只用在服務端,而不是由客戶端?如果是這樣,那麼在這種情況下這將如何有用?

  2. 我寫錯了一個DataContractResolver,它序列化了泛型類型的全限定類型名稱,如Bar`1[List`1[string, mscorlib], mscorlib]?客戶端的DataContractResolver無法恢復這些類型嗎?

+0

至於第一個問題 - 當然 – EvAlex 2013-11-01 06:15:38

回答

1

我希望能夠在兩端工作,但我不確定這是一個好主意;它需要額外的配置,並且不能用於Silverlight等。但它可能適用於「完整的」.NET,每一端都有相同的位。

+1

確實兩側Silverlight 4無法訪問相同的DataContractResolver? – Benson 2010-03-13 12:02:38

0

不知道DataContractResolver的典型用例是什麼,但根據這篇文章(MSDN on DataContractResolver),應該很容易用「SharedTypeResolver」和共享包含合同的Assemblies來完成。

謹慎的一句話: 所以雖然這似乎是可能的,但我不太確定從設計的角度來看這是否是一個好主意,因爲這會削弱合同的表現力。這些類型會影響合約並破壞與其他編程語言的兼容性,如果像SOAP這樣的開放標準首先是正確的解決方案,那麼這就會產生問題。 DataContract是而不是共享程序集...

0

我以前使用過DataContractResolver;這些是我的發現:

  1. 客戶端和服務器都需要解析器;因爲序列化和反序列化發生在兩端。顯然,使用了相同的解析器。
  2. 類型名稱是DataContractSerializer生成的信息的標準部分。然而,這僅僅是類型名稱,而不是完全(組裝)限定名

基本上,自定義解析,您可以將其添加到您的WCF客戶端和服務器的行爲:

`foreach (OperationDescription operation in myWCFService.Description.Endpoints[0].Contract.Operations) 
    { 
     operation.Behaviors.Find<DataContractSerializerOperationBehavior>() 
      .DataContractResolver = new MyDataContractResolver(); 
    }` 

對於在客戶端,你做的一樣:

 `foreach (var operation in base.ChannelFactory.Endpoint.Contract.Operations) 
    { 
    operation.Behaviors.Find<DataContractSerializerOperationBehavior>() 
     .DataContractResolver = new MyDataContractResolver(); 
    }` 

我的解析器從配置的位置動態加載類型和基於某些屬性,對其進行緩存。如果你喜歡,我可以提供一些示例代碼 - 這些都很基礎。

KnownTypeAttribute(例如,使用所提供的方法以返回所有已知類型的)也可使用;但自定義解析器允許更靈活的方式,如動態加載類型(例如一個插件系統),做自己的映射(類型=>類型名稱,反之亦然)