2012-06-26 29 views
2

我一直在用這個來敲我的頭,以利用。任何想法都非常受歡迎!Msmq和sgen for xmlserialization完全失敗

我有一個使用MSMQ的vb.net中的客戶端/監聽器應用程序,當我不使用sgen.exe在編譯時生成序列化時,它可以100%正常工作。

使用sgen時,它在偵聽器部件上失敗。

 qOrders.Formatter = New XmlMessageFormatter(New Type() {GetType(InfoMessage)}) 

     m = qOrders.EndReceive(e.AsyncResult) 

它炸彈在米。 m.Body有錯誤"Cannot deserialize the message passed as an argument. Cannot recognize the serialization format.",其餘的屬性也有錯誤,沒有收到一個值。

該程序集名爲strong,並且App.XmlSerializers.dll也正確簽名。我知道dll被使用,因爲我在程序運行時無法刪除它。

InfoMessage類是一個帶有3個公共字符串成員的簡單公共類。用Reflector檢查dll,我確實看到sgen生成了一個InfoMessageSerializer類。

該問題不在客戶端,因爲我刪除了DLL並運行偵聽器,它的工作原理與往常一樣。

那麼,這裏可能會出現什麼問題? :○

感謝,

約翰

編輯:鏈接到監聽來源:http://pastebin.com/TqWfLVJ0

回答

1

sgen輸出的design limitation。此限制爲never removed

這些生成的程序集無法在Web服務的服務器端使用。此工具僅適用於Web服務客戶端和手動序列化方案。

基本上,你預計不會運行sgen使Web服務速度更快的服務器端,因爲XmlSerializer啓動時間並不是它的性能(與某些類型的客戶端的對比)的關鍵因素。

當然,sgen可以在非Web服務方案中的服務器端使用,只要你不傳遞任何XmlAttributeOverridesXmlSerializer構造。

隨着MSMQ,有二進制和XML序列化的選擇,你的代碼在這裏選擇後者:

qOrders.Formatter = New XmlMessageFormatter(New Type() {GetType(InfoMessage)}) 

因此,讓我們一起來看看如何MessageQueue創建一個XmlSerializer。以下是從System.Messaging.dll,.NET 4.0取得的XmlMessageFormatter的一種方法。它的.NET 2.0對應類似。

private void CreateTargetSerializerTable() 
{ 
    if (!this.typeNamesAdded) 
    { 
    for (int index = 0; index < this.targetTypeNames.Length; ++index) 
    { 
     Type type = Type.GetType(this.targetTypeNames[index], true); 
     if (type != (Type) null) 
     this.targetSerializerTable[(object) type] 
      = (object)new XmlSerializer(type); 
    } 
    this.typeNamesAdded = true; 
    } 
    if (!this.typesAdded) 
    { 
    for (int index = 0; index < this.targetTypes.Length; ++index) 
     this.targetSerializerTable[(object) this.targetTypes[index]] 
     = (object)new XmlSerializer(this.targetTypes[index]); 
    this.typesAdded = true; 
    } 
    if (this.targetSerializerTable.Count == 0) 
    throw new InvalidOperationException(Res.GetString("TypeListMissing")); 
} 

正如你可以看到,MSMQ不提供XmlAttributeOverrides,不像在框架的Web服務的服務器端代碼。儘管如此,還有其他人結合XmlMessageFormatter和sgen來組合have trouble

我的猜測是,sgen仍可以與MSMQ的工作,因爲MSMQ不使用XmlAttributeOverrides,但你必須確保你沒有使用proxytypes命令行選項,你還在道外移動微軟曾經測試過的。

我會建議看這些可能性:使用sgen與MSMQ

  • 避免。
  • 避免使用/proxytypes選項與sgen
  • 禁用SGenUseProxyTypes萬一您從項目文件中調用sgenlook here查看如何)。
  • 看看MSMQ使用二進制序列化。
  • 密切關注您通過客戶端隊列發送的類型。
+0

有趣!有一個問題:兩個文檔都討論了Web服務 - 我沒有做任何與Web服務相關的事情,所以它是如何應用的?事實上,這只是MSMQ通信的一個簡單的PoC(從實際應用縮小到查明問題)。 – johnjohn

+0

@johnjohn - 答案已展開。順便說一句,如果你的問題包含更多的代碼,特別是誰和如何實例化'XmlSerializer',這將使它成爲一個更好的問題。 –

+0

感謝您的澄清。我更新了一個鏈接到監聽器代碼 - 它在qOrders_ReceiveCompleted方法(包含問題中的代碼)上轟炸。它根本不使用XmlAttributeOverrides。 – johnjohn