2010-05-24 27 views
2

我創建了兩個WCF服務(發貨& PDF生成器)。他們和我的ClientApp一起共享一個名爲Kyle.Common.Contracts的程序集。在本次大會,我有三大類:爲什麼當MessageContract位於我的WCF服務中時,代理生成的代碼會創建一個新類?

namespace Kyle.Common.Contracts 
{ 
    [MessageContract] 
    public class PDFResponse 
    { 
     [MessageHeader] 
     public string fileName { get; set; } 
     [MessageBodyMember] 
     public System.IO.Stream fileStream { get; set; } 
    } 

    [MessageContract] 
    public class PDFRequest 
    { 
     [MessageHeader] 
     public Enums.PDFDocumentNameEnum docType { get; set; } 
     [MessageHeader] 
     public int? pk { get; set; } 
     [MessageHeader] 
     public string[] emailAddress { get; set; } 
     [MessageBodyMember] 
     public Kyle.Common.Contracts.TrackItResult[] trackItResults { get; set; } 
    } 

    [DataContract(Name = "TrackResult", Namespace = "http://kyle")] 
    public class TrackResult 
    { 
     [DataMember] 
     public int SeqNum { get; set; } 
     [DataMember] 
     public int ShipmentID { get; set; } 
     [DataMember] 
     public string StoreNum { get; set; } 
    } 
} 

我的pdfGenerator的ServiceContract樣子:

namespace Kyle.WCF.PDFDocs 
{ 
    [ServiceContract(Namespace="http://kyle")] 
    public interface IPDFDocsService 
    { 
     [OperationContract] 
     PDFResponse GeneratePDF(PDFRequest request); 

     [OperationContract] 
     void GeneratePDFAsync(Kyle.Common.Contracts.Enums.PDFDocumentNameEnum docType, int? pk, string[] emailAddress); 

     [OperationContract] 
     Kyle.Common.Contracts.TrackResult[] Test(); 
    } 
} 

如果我註釋掉GeneratePDF存根,通過VS2010生成的代理意識到測試返回凱爾數組.Common.Contracts.TrackResult。但是,如果我在那裏保留GeneratePDF,代理拒絕使用Kyle.Common.Contracts.TrackResult,而是創建一個新類ClientApp.PDFDocServices.TrackResult,並將其用作Test的返回類型。

有沒有辦法強制代理生成器使用Kyle.Common.Contracts.TrackResult,每當我使用MessageContract?也許有更好的方法使用Stream和File Name作爲返回類型?

我只是不想創建一個Copy方法從ClientApp.PDFDocServices.TrackResult複製到Kyle.Common.Contracts.TrackResult,因爲它們應該是完全相同的類。

回答

2

經過很多額外的挖掘,我意識到它實際上是Enum「打破」它。它與DataContractSerializer與XmlSerializer的工作方式有關。長話短說,解決方案是將Enum變爲可空。

[MessageContract] 
public class PDFRequest 
{ 
    [MessageHeader] 
    public Enums.PDFDocumentNameEnum? docType { get; set; } 
    [MessageHeader] 
    public int? pk { get; set; } 
    [MessageHeader] 
    public string[] emailAddress { get; set; } 
    [MessageBodyMember] 
    public Kyle.Common.Contracts.TrackItResult[] trackItResults { get; set; } 
} 
1

您可以指示Visual Studio重新使用引用程序集中的類。因此,如果您的測試項目具有對Kyle.Common.Contracts程序集的程序集引用,它應該重新使用那裏定義的那些類型,而不是添加新的客戶端代理類。

啓用這個開關是在Add Service Reference對話窗口中Advanced頁面上 - 它應該是在默認情況下:

alt text http://i48.tinypic.com/281d3m1.png

確保您的項目

  • 設有大會參考通用數據合同彙編
  • 當您添加服務參考
  • 時,此設置真正開啓
+0

marc,感謝您的及時回覆。我已經仔細檢查了這一點,並且它已被DEFINITELY檢查。 如果我註釋掉使用MessageContracts的OperationContract,並在客戶端更新我的引用,那麼客戶端將使用正確的程序集。 但是,只要取消註釋OperationContract,然後再次更新我的引用,客戶端就會創建新的類。 這讓我覺得它與MessageContracts的工作方式有關。 – DaleyKD 2010-05-24 20:07:23

+0

@DaleyKD:好吧,有趣的聽到 - 我從來沒有使用MessageContracts,所以我不能從我自己的經驗告訴可能會導致這種行爲。似乎有點奇怪,雖然.... – 2010-05-24 20:22:28

2

我遇到了同樣的問題(MessageContract +枚舉),你的文章幫助了我。事實上,如果你明確地將枚舉字段設置爲可爲空,它就可以工作。問題是,當使用枚舉時,WCF使用XML序列化程序,它無法從空字符串中指出null。

有一個實際的WCF團隊成員之一here對此行爲的詳細解釋。

對於使用裸消息的文檔/文字,WCF在處理枚舉類型時會退回到XmlSerializer。 ... XmlSerializer默認將null視爲缺少...我們遇到一個沒有nillable =「true」的模式...值類型的檢測邏輯當前只處理原始值類型,它不檢查枚舉。

換句話說WCF不喜歡枚舉......但是,嘿,它的作品,你只需要意識到它!

相關問題