2009-02-18 106 views
6

我想知道如何在WCF中配置已知類型。例如,我有一個類和僱員類。 僱員類是人類類的子類。這兩個類都標有[DataContract]屬性。WCF:配置已知類型

我不想硬編碼一個類的已知類型,比如把一個[ServiceKnownType(typeof(Employee))]放在Person類中,以便WCF知道Employee是Person的一個子類。現在

,我加入到主機的App.config下面的XML配置:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"> 
      <knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" /> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
    <system.serviceModel> 
    ....... 
    </system.serviceModel> 
</configuration> 

我編譯,運行在主機,加在客戶服務參考,並添加一些代碼,運行客戶端。但是,發生錯誤:

格式化拋出一個異常,而 試圖反序列化消息: 試圖 反序列化參數 http://www.herbertsabanal.net:person時出錯。 所述的InnerException消息是「在第1行的位置誤差 247.元素 'http://www.herbertsabanal.net:person' 包含 'http://www.herbertsabanal.net/Data:Employee' 數據契約的數據。解串器沒有任何類型的 知識,這些知識映射到此合約的 。添加對應於「僱員」到已知類型的 列表類型 - 例如,通過使用KnownTypeAttribute屬性 或通過將其添加到已知類型 傳遞給 DataContractSerializer的列表'。有關更多詳細信息,請參閱 InnerException。

下面是數據合同:

[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Person")] 
    class Person 
    { 
     string _name; 
     int _age; 

     [DataMember(Name="Name", Order=0)] 
     public string Name 
     { 
      get { return _name; } 
      set { _name = value; } 
     } 

     [DataMember(Name="Age", Order=1)] 
     public int Age 
     { 
      get { return _age; } 
      set { _age = value; } 
     } 
    } 


[DataContract(Namespace="http://www.herbertsabanal.net/Data", Name="Employee")] 
    class Employee : Person 
    { 
     string _id; 

     [DataMember] 
     public string ID 
     { 
      get { return _id; } 
      set { _id = value; } 
     } 
    } 

順便說一句,我沒有使用類庫(WCF類庫或非WCF類庫)爲我服務。我只是簡單地在主機項目中編碼。

我想在配置文件中必須有一個問題(請參閱上面的配置文件)。或者我必須錯過一些東西。任何幫助將非常感激。

+0

我懷疑只有在使用第三方庫並將其引用到服務時,該配置纔有效。我會嘗試一下,如果我找到一些答案,我會回到這個問題。 – jerbersoft 2009-02-18 08:36:51

回答

8

我猜我現在已經找到了答案。

我上面貼的配置文件看起來是這樣的:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="Person, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"> 
      <knownType type="Employee, WCFWithNoLibrary, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" /> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
    <system.serviceModel> 
    ....... 
    </system.serviceModel> 
</configuration> 

我只是說什麼,該類的命名空間和員工類。而且不需要較長的版本和文化價值....正確的配置應該是:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.runtime.serialization> 
    <dataContractSerializer> 
     <declaredTypes> 
     <add type="WCFWithNoLibrary.Person, WCFWithNoLibrary"> 
      <knownType type="WCFWithNoLibrary.Employee, WCFWithNoLibrary" /> 
     </add> 
     </declaredTypes> 
    </dataContractSerializer> 
    </system.runtime.serialization> 
    <system.serviceModel> 
    ....... 
    </system.serviceModel> 
</configuration> 

現在是更短,更有意義。但是,如果使用第三方庫,則需要添加版本,文化,publickeytokens。

+2

Upvote。你是否需要在客戶端.config上做任何事情? – granadaCoder 2013-04-10 20:15:42

+1

您將需要複製客戶端上的配置,以便它可以接收新類型。 – 2014-10-07 15:58:31

5

我知道這是很久以前的回答,但是,另一種(也許更明顯的爲未來的程序員)解決方案:

[KnownType(typeof(SubClass))] 
public class BaseClass 

斯科特

0

我在另一種情況下拿到這個漫長的錯誤信息也。我確實使用了KnownTypeAttribute,併成功部署了一個使用WCF.RIA進行生產的應用程序。在第二個版本中,我添加了一個新的子類型,並添加了必要的相應的KnownTypeAttribute(編譯器在沒有此屬性的情況下不接受它 - 很棒)。然而,編譯器接受的和我的機器上運行的東西沒有在生產環境中運行。只有在生產中,我得到了上面提到的錯誤。比較現有子類型和新子類型的所有用法,我忘記了WCF.RIA需要在方法名稱中使用子類型的名稱,例如GetMySubTypes。因此,如果在添加屬性後出現此錯誤,請參閱WCF.RIA的慣例。