2012-04-19 34 views
3

我的服務有一些問題,關於KnownType和繼承。我讀過幾乎所有類似的問題,但我仍然沒有找到解決方案。我會盡力解釋:客戶端生成不提供有關第三方知識類型的信息

這是我的接口:

[ServiceContract(Namespace = "MyNameSpace.Components.Web")]  
public interface ITransactionsService 
{ 
    [OperationContract(Name = "Put")]   
    void Put(WebTransactionItem wtransactionItem); 
} 

這是我的DataContract:

[DataContract(Namespace = "MyNameSpace.Components.Web")] 
public class WebTransactionItem 
{   
    [DataMember] 
    public TransactionItem items { get; set; } 

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

TransactionItem是一個(另一個)組件提供一個抽象類。
在客戶端項目中使用了相同的程序集,所以我在客戶端和服務器中引用了相同的類型。
在客戶端,經過一番操作(讀取文件etc.etc),我有一個從 TransactionItem繼承對象的數組,說:

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

在服務的Web.config我加入

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

當然我可以使用的 KnownTypeAttribute上的[Datacontract]裝飾器。

如果配置服務引用(在客戶端項目的服務引用)我檢查中引用組件標誌,我可以在我的代碼來寫(默認情況下選中)的重用類型:

MyNameSpace.Components.Web.WebTransactionItem wtItem = 
    new MyNameSpace.Components.Web.WebTransactionItem(){ 
     TransactionItemList = transItems} 

我可以毫無問題地致電該服務。那麼問題是什麼?
的問題是,如果我刪除

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

屬性(我不希望客戶機使用抽象類)從DataContract服務雲異常:

有而一個錯誤試圖序列化參數MyNameSpace.Components.Web:wtransactionItem。 Innerexception消息: 類型'Assemblyname.TransactionHeader'的合同名稱爲'TransactionHeader:http://schemas.datacontract.org/2004/07/Assemblyname'。

現在,據我已經明白,這種情況發生的時候,不指定服務類型 TransactionHeader(繼承TransactionItem),但我(見的Web.Config服務的文件,還我已經嘗試了knowntypeAttribute)!
另外我注意到,在 Reference.cs類自動在客戶端項目中產生,在第一種情況下(當我離開

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

屬性)

編碼:

[KnownTypeAttribute(typeof(Assemblyname.TransactionHeader))] 

[KnownTypeAttribute(typeof(Assemblyname.TransactionTrailer))] 

以上生成的部分類。這允許繼承的類的序列化,但是如果我刪除了Service中的屬性,則部分類(在Reference.cs中)不再具有它,這就是Service引發該異常的原因。這就好像它錯過了對抽象類 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

嗨Stefan,謝謝你的回答。不幸的是,我也嘗試過_ServiceKnownType_ Decorator,它們都指定了所有涉及的類型(約20種),並且正如您所建議的那樣,但結果是一樣的。我認爲就像你說的那樣:序列化程序錯過了抽象類。另外,我試過不要在客戶端代中使用相同的程序集(包含類型的程序集):這個技巧似乎可行,但我必須使用一些反射技巧,因爲生成的類型顯然不一樣(即使他們真的是;))。 – kindaska 2012-05-02 13:44:04

相關問題