2013-01-06 25 views
5

從我可以看到我有創造的各種數據我想通過WCF傳遞一個「特殊」的數據類型,所以如果我有像使用共享的數據類型爲DataContract在WCF

public class District 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
} 
共享類

,我想使用WCF發送區對象,我要創建一個datacontract,所以我必須創建一個新的WCF類

[DataContract] 
public class WCFDistrict 
{ 
    [DataMember] 
    public long Id { get; set; } 

    [DataMember] 
    public string Name { get; set; } 
} 

然後當我在執行我使用它在WCF服務必須解析從一個對象到另一個對象的數據

public WCFDistrict GetDistrict(long id) 
{ 
    var district = _districtRepository.GetDistrict(id); 
    return new WCFDistrict {Id = district.Id, Name = district.Name}; 
} 

有沒有辦法將共享類作爲DataContract重用,而沒有這些屬性?或者我應該在他們可以共享的類上創建一個接口,以便我可以將它們放在它們之間?還是第三個?

回答

9

首先,您沒有嚴格要求提供DataContract;只要您使用.Net 3.5 SP1或更高版本,WCF就會正確序列化普通舊類對象(PO​​CO)。

其次,您可以在服務器和客戶端的項目中共享相同的物理類文件;我們擁有數百個以這種方式直接共享的類(和代碼)的項目,並且在開發和測試中節省了大量的時間和精力。

有一對夫婦來獲得所需的步驟此啓動和運行(從內存中這樣做,所以我可能需要調整的答案):

1)在客戶端,如果你正在使用VB,創建與你想在客戶端使用的類相同的默認命名空間項目(對C#來說,這並不重要,因爲命名空間嵌入在類中)。

2)將類文件作爲鏈接添加到項目中,以便您擁有該類的一個物理副本。

3)如果您還沒有WCF配置,請在您的WCF配置中添加dataContractSerializer

4)在客戶端,右鍵單擊該服務,然後選擇配置服務引用...在出現的對話框中,確保已選中Reuse types in all referenced assemblies,並且已選擇Reuse types in all referenced assemblies選項。

5)讓這項工作最棘手的部分是收集。

a)用CollectionDataContract屬性來裝飾集合。

b)在reference.svcmapCollectionMappings表中添加一個條目。要查找reference.svcmap,請顯示項目中的所有文件,然後展開該服務。要編輯它,只需雙擊文件。您將在這裏爲您正在序列化的每個特定集合添加一個條目,並且您需要區分具有列表<>基本和具有字典<>基本的那些項目。如果你不採取這一步,WCF會自動將這些類序列化到底層的通用簽名,你將失去對類的使用。

此表看起來像這樣的條目:

<CollectionMappings> 
    <CollectionMapping TypeName="System.Collections.Generic.Dictionary`2" Category="Dictionary" /> 
    <CollectionMapping TypeName="System.Collections.Generic.List`1" Category="List" /> 
    <CollectionMapping TypeName="System.Collections.Specialized.StringCollection" Category="List" /> 
    <CollectionMapping TypeName="My.Namespace.MyDictionaryCollection" Category="Dictionary" /> 

當您添加這些條目並保存文件時,WCF客戶端生成器將重建reference.cs或取決於reference.vb文件你正在使用什麼語言。您可以通過查看生成的代碼來判斷是否正確配置了引用:如果該代碼包含類定義,那麼由於某種原因,WCF代碼生成器無法映射到您的複製類。

最後一個注意事項:有時WCF代碼生成器完全無法生成代碼,這總是由於服務中的問題(通常一個類不夠獨特或者一個類型不能被序列化爲一個理由或其他)。

爲了調試這種類型的問題,最簡單的事情就是添加WCF診斷日誌記錄,它將生成一個文件,該文件可以被一個特殊的工具打開(忘記它的名稱),允許您鑽取錯誤信息並發現究竟出了什麼問題。這爲我們節省了數不清的工作時間。要配置此日誌記錄,以下內容添加到你的web.config中<configuration>部分的任何地方:

<system.diagnostics> 
    <sources> 
     <source name="System.ServiceModel" 
       switchValue="Information, ActivityTracing" 
       propagateActivity="true"> 
     <listeners> 
      <add name="traceListener" 
       type="System.Diagnostics.XmlWriterTraceListener" 
       initializeData="c:\log\WcfTrace.svclog" /> 
     </listeners> 
     </source> 
    </sources> 
    </system.diagnostics> 

一旦你添加了這一點,並保存web.config文件,嘗試更新客戶端的服務引用,然後雙擊點擊你指定的日誌文件,工具就會打開。

4

你會需要這些屬性。爲了讓您的生活更輕鬆,您可以使用像AutoMapper這樣的工具來完成數據傳輸對象的佈線,因爲所有屬性的手動設置可能很乏味。

無論如何,讓您的模型類與數據合同保持獨立是很好的做法,以便對模型所做的更改不必直接影響數據合同。