2011-02-18 59 views
4

不同的接口實現以下情況:如何反序列化與WCF

我們的軟件與業務對象,在它們與WCF發送從服務器到客戶端的時刻。

[Serializable] 
public class SomeValueBO 
{ 
    public DateTime Timestamp{ get; set; } 
} 

它們被打包在請求/響應消息中。

[DataContract] 
public class Response 
{ 
    [DataMember] 
    public List<SomeValueBO> Values { get; set; } 
} 

問題:

我們想DTO的發送到客戶端,而不是業務對象的。我聽說,可以在客戶端檢索與在服務器上發送的不同類型的實例。

例子:

public interface ISomeValue 
{ 
    DateTime Timestamp { get; set; } 
} 

[Serializable] 
public class SomeValueBO : ISomeValue 
{ 
    public DateTime Timestamp { get; set; } 
} 

[DataContract] 
public class SomeValueDTO : ISomeValue 
{ 
    [DataMember] 
    public DateTime Timestamp { get; set; } 
} 

的迴應是這樣的:

[DataContract] 
public class Response 
{ 
    [DataMember] 
    public List<ISomeValue> Values { get; set; } 
} 

在服務器上:

public class ServiceClass : IService 
{ 
    public Response HandleRequest(Request request) 
    { 
     Response response = new Response(); 
     response.Values.Add(new SomeValueBO()); 

     return response; 
    } 
} 

上的客戶端:

Response response = serviceProxy.HandleRequest(request); 
ISomeValue value = response.Values[0]; 

value is SomeValueDTO 

我試過只聲明DTO對象的已知類型和Data Contract Equivalence,但WCF仍然保持反序列化項目作爲BO實例。

我要補充,這兩種方式都上班,送BO和檢索它作爲一個BO和發送BO和檢索DTO,但當然有不同的要求。

所以我的問題是,這是可能的,如果是,我究竟做錯了什麼?

感謝您的幫助, Enyra

編輯: 我也發現了,我們使用的是NetDataSerializer,算得上是它不工作的問題?

+1

什麼是您使用的郵件協議?是否有一個原因,你不是簡單地從服務器發送dto?從長遠來看,這(你試圖做的)可能是一個維護噩夢。 – 2011-02-18 08:01:11

+0

是的,有一個原因,我們加載值> 10'000,如果我們複製它們,它會變得很慢,所以我們會用這個技巧來轉換它。 – Enyra 2011-02-18 10:49:07

回答

2

MSDN

的NetDataContractSerializer在一個 重要途徑不同 從DataContractSerializer的:在 NetDataContractSerializer包括序列化的 XML中的CLR 類型信息,而DataContractSerializer不包含此類型信息。 因此,僅當串行化和反串行化結束共享相同的CLR 類型時,纔可以使用NetDataContractSerializer 。

這就是爲什麼它目前沒有工作。

如果您改爲使用DataContractSerializer,則客戶端和服務只需要就對象狀態的序列化XML表示形式達成一致,而不是基於確切的CLR運行時類型。您需要使用DataContractAttribute來對雙方的類型進行屬性設置,以使與序列化表示形式相關聯的XML名稱空間在兩側都相同。顯然,數據合約在序列化結構方面必須是等價的。

也就是說,你要做的事應該可以與DataContractSerializer一起使用。至於它是否是最好的方式 - 就像所有的設計決定「取決於」。

4

即使你沒有使用NetDataContractSerializer(評論),即SomeValueBO未聲明爲一個數據合同的事實意味着將主要充當場串。這是特別痛因爲自動實現的屬性被重新場串行皇家疼痛 - 他們成爲瘋狂脆。

我將宣佈爲一個合同:

[DataContract] 
public class SomeValueBO 
{ 
    [DataMember] 
    public DateTime Timestamp{ get; set; } 
} 

,並切換到DataContractSerializer,但請注意這是重大更改 - 你會在同一時間更新所有客戶端和服務器。只要他們共享完整的合同簽名,您就可以擁有其他實施方式。

重新目前使用的NetDataContractSerializer - 如果這是對性能,有替代品 - 有合同基於二進制序列化是更快(CPU)和小(帶寬)比NetDataContractSerializerPerformance Tests of Serializations used by WCF Bindings

+0

我也做了一些指定數據合同的嘗試,在我的文章中我只使用了bo規範的原始形式。 – Enyra 2011-02-18 10:46:16