Dot-Net

通過 Web 服務發送複雜數據的首選方法是什麼?

  • September 22, 2015

現在是 2008 年,我仍然對這個感到困惑。因此,我正在開發一種需要將復雜類型傳遞到其中並從中返回的 Web 方法。我正在玩弄的兩個選項是:

  1. 傳遞和返回具有數據和行為的*實際業務對象。*執行 wsdl.exe 時,它會自動創建僅包含數據部分的代理類,並且這些代理類將自動與伺服器端的真實業務對象相互轉換。在客戶端,他們只能使用啞代理類型,並且他們必須將它們映射到他們認為合適的一些真實的業務對像中。這裡的一個大缺點是,如果我同時“擁有”伺服器端和客戶端,並且我想使用同一組真實業務對象,我可能會遇到名稱衝突等問題。(因為真實對象和代理名稱相同。)
  2. 忘記嘗試傳遞“真實”的業務對象。相反,只需創建簡單的 DataTransfer 對象,我將手動將其映射到我的真實業務對象。無論如何,它們仍然會被 wsdl.exe 複製到新的代理對象,但至少我沒有欺騙自己認為 Web 服務可以本機處理具有業務邏輯的對象。

順便說一句 - 有誰知道如何告訴 wsdl.exe不要複製對象?我們不應該直接告訴它,“嘿,在這裡使用這個現有的類型。不要複製它!”

無論如何,我現在已經確定了#2,但我很好奇你們的想法。我感覺一般來說有更好的方法可以做到這一點,而且我的所有觀點可能都不完全準確,所以請讓我知道你的經歷。

更新:我剛剛發現 VS 2008 在添加“服務引用”時可以選擇重用現有類型,而不是在代理文件中創建全新的相同類型。甜的。

還有一個用於分離層的論點 - 有一組可序列化的對象,這些對象可以傳入和傳出 Web 服務,還有一個翻譯器,用於在該組和業務對象之間進行映射和轉換(可能具有不適合傳遞的屬性)金屬絲)

它是 Web 服務軟體工廠服務工廠所青睞的方法,這意味著您可以在不破壞 Web 服務介面/契約的情況下更改業務對象

我會做一個混合動力車。我會使用這樣的對象

public class TransferObject
{
   public string Type { get; set; }
   public byte[] Data { get; set; }
}

然後我有一個很好的小實用程序,可以序列化一個對象然後壓縮它。

public static class CompressedSerializer
{
   /// <summary>
   /// Decompresses the specified compressed data.
   /// </summary>
   /// <typeparam name="T"></typeparam>
   /// <param name="compressedData">The compressed data.</param>
   /// <returns></returns>
   public static T Decompress<T>(byte[] compressedData) where T : class
   {
       T result = null;
       using (MemoryStream memory = new MemoryStream())
       {
           memory.Write(compressedData, 0, compressedData.Length);
           memory.Position = 0L;

           using (GZipStream zip= new GZipStream(memory, CompressionMode.Decompress, true))
           {
               zip.Flush();
               var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
               result = formatter.Deserialize(zip) as T;
           }
       }

       return result;
   }

   /// <summary>
   /// Compresses the specified data.
   /// </summary>
   /// <typeparam name="T"></typeparam>
   /// <param name="data">The data.</param>
   /// <returns></returns>
   public static byte[] Compress<T>(T data)
   {
       byte[] result = null;
       using (MemoryStream memory = new MemoryStream())
       {
           using (GZipStream zip= new GZipStream(memory, CompressionMode.Compress, true))
           {
               var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
               formatter.Serialize(zip, data);
           }

           result = memory.ToArray();
       }

       return result;
   }
}

然後,您只需傳遞具有類型名稱的傳輸對象。所以你可以做這樣的事情

[WebMethod]
public void ReceiveData(TransferObject data)
{
   Type originType = Type.GetType(data.Type);
   object item = CompressedSerializer.Decompress<object>(data.Data);
}

現在壓縮的序列化器使用泛型使其強類型化,但是您可以輕鬆地創建一個方法來使用上面的 originType 來反序列化 Type 對象,這一切都取決於您的實現。

希望這能給你一些想法。哦,要回答您的其他問題,wsdl.exe 不支持重用類型,但 WCF 支持。

引用自:https://stackoverflow.com/questions/12982