2013-09-25 57 views
4
  • 請注意,我正在修改現有服務以添加額外的數據項,我無法更改服務或客戶端的結構。我知道ASMX已經過時,並沒有使用最佳實踐。

我遇到了一個非常奇怪的問題,我只是無法弄清楚如何讓這個工作正常。我有一個ASMX網絡服務(我知道它過時了,我不能改變這一點)這需要一個響應,並用zip壓縮來壓縮它。然後通過SOAP將其交付給客戶端,客戶端接收該流並對其進行解壓縮,並使用由「添加服務引用」和XMLSerializer創建的合約來反序列化對象。反序列化ASMX Web服務部分失敗

我遇到的問題是它無法正確反序列化對象。我的XML在壓縮之前和解壓縮後看起來完全一樣,但看起來Web服務忽略了我的參數排序。我嘗試過[DataMember],[MessageBodyMember],[XmlElement],[MessageHeader]都帶有正確的排序參數和MustUnderstand,但它似乎始終將元素粘貼在XML的底部。

這裏是什麼是混亂的,我messagecontract類從另一個消息協定類繼承,像這樣

[MessageContract(IsWrapped = true)] 
public class MyClass : MyBaseContract{} 

就好了,每次下觸頭反序列化的元素,即使我改變他們周圍,他們的工作只是罰款。那裏的元素根本不包含任何順序,他們只是工作。

這是我的反序列化代碼。

using (MemoryStream stream = new MemoryStream(data)) 
     { 
      XDocument document = XDocument.Load(stream); 

      System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(type); 
      System.Xml.XmlReader read = System.Xml.XmlReader.Create(new System.IO.StringReader(document.ToString())); 

      object o = serializer.Deserialize(read); 

      return o; 
     } 

下面是序列化代碼:

 XmlSerializer xs = new XmlSerializer(value.GetType()); 
     MemoryStream stream = new MemoryStream(); 
     xs.Serialize(stream, value); 
     stream.Position = 0; 
     StreamReader sr = new StreamReader(stream); 
     return sr.ReadToEnd(); 

因此,這裏是我的代碼需要

  1. 電話到網絡服務的步驟
  2. Web服務調用助手,並返回一個響應對象
  3. 響應對象被壓縮
  4. 壓縮對象以肥皂格式通過電線發送
  5. 客戶端獲得響應
  6. 客戶端根據「添加服務引用」功能提供的合約進行反序列化。
  7. 客戶端管理反序列化來自響應基類的數據,但響應類本身沒有任何反序列化。

回答

2

好吧,我解決了它,但它真的很棘手。

發生了什麼是「添加服務引用」生成的代碼包含命名空間又名

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://myservice.com")] 

但是,你可以手動執行不包括命名空間中生成的XML隨時隨地XML序列化。如果我指定使用此代碼,則XML序列化程序將中斷。

[MessageContract(IsWrapped = true,WrapperNamespace="http://myservice.com")] 

使其正確工作的唯一方法是將生成的代碼中指定名稱空間的行添加回合同類,如下所示。

[XmlType(Namespace="http://myservice.com")] 
public class MyContract {} 

在此添加之後,所有生成的xml將包含每個元素中的完整名稱空間,並且反序列化器將表現正常。爲什麼它打破了命名空間的WCF主義,我不知道。它適用於其他WCF主題。

其部分原因是因爲之前的開發人員添加了一種手動在客戶端的某些XML元素上插入名稱空間的方法。特別是那些正常工作的基類!我只是沒有看到被調用的方法,因爲它埋得如此之深。