WebService傳輸DataSet的一點想法和實踐

其實這個標題很大,實現起來也可以有許多的辦法。甚至,應否這樣做也許都能惹出許多的爭論(比如,爲什麼用WS而不是Remoting? 爲什麼傳DataSet而不是Entity[]?)。

       由於DS的體態豐腴,選用何種序列化就很多的選擇了,我嘗試過如下方法:

      1,    SOAPFomatter

       2, BinaryFomatter 

  3,SOAPFomatter + SharpZipLib

  4,BinaryFomatter + SharpZipLib

  5, DataSetSurrogate (http://support.microsoft.com/default.aspx?scid=kb;en-us;829740

  6, DataSetSurrogate + SharpZipLib

  7, PAB.CompressDataSet.Wrapper (http://www.eggheadcafe.com/articles/20031219.asp)

若論壓縮效果,第7種辦法是最優秀的,第2名是第6種辦法。

若論速度,第7種和第6種幾乎差不多。。。(最快的好像是第2種)

(區區年前曾做了一個詳細的工程,分別用100/1000/10000條紀錄對上述方法進行測試,然該工程很可能丟到抓娃國了,故詳細數據暫且欠奉,待找回後當補充之)

PAB.CompressDataSet.Wrapper 據上文所說,乃是通過反向工程.NET Compact Framework而得到的壓縮代碼,我估計它也採用了類似於DataSetSurrogate那樣的替代對象來存儲。本來我是很傾向使用這個方法的,可惜這個咚咚沒有源碼(且DLL加了混淆)。。。而反觀第6種,我們則可以輕鬆坐擁全部源碼,所以最後我還是選擇了第6種辦法的。下面的一點代碼,可供各位曬笑:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Data;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;

/// <summary>
  /// 壓縮數據集
  /// </summary>
  /// <param name="ds"></param>
  /// <returns></returns>
  public static byte[] CompressDS(DataSet ds)
  {
   MemoryStream ms = new MemoryStream();
   ZipOutputStream zos = new ZipOutputStream(ms);
   zos.PutNextEntry(new ZipEntry(ds.DataSetName));   
   BinaryFormatter bf = new BinaryFormatter();
   DataSetSurrogate dss = new DataSetSurrogate(ds);
   bf.Serialize(zos, dss);
   zos.CloseEntry();
   zos.Close();
   byte[] ret = ms.ToArray();   
   ms.Close();
   return ret;
  }

  /// <summary>
  /// 解壓數據集
  /// </summary>
  /// <param name="byt"></param>
  /// <returns></returns>
  public static DataSet DecompressDS(byte[] byt)
  {
   MemoryStream ms = new MemoryStream(byt);
   BinaryFormatter bf = new BinaryFormatter();
   ZipInputStream zis = new ZipInputStream(ms);
   zis.GetNextEntry();   
   DataSetSurrogate dss = (DataSetSurrogate)bf.Deserialize(zis);
   zis.Close();
   ms.Close();
   DataSet ds = dss.ConvertToDataSet();
   return ds; 
  } 

基於SharpZipLib實現上面兩個函數後,DS壓縮的任務就完成了。BTW,VS2005裏邊,.NET FW 自帶了CompressStream,我們可以跟SharpZipLib說再見了:)

至於WS怎麼傳輸,在CSDN上看到Tomgus (小橋流水) 老兄轉載的http://www.cnblogs.com/flyskywlh/archive/2005/08/18/217382.html,乃Flyskywlh老兄的大作。

     首先我也很同意使用byte[]數組傳輸,非常方便。至於具體WebMethod的方式,我在實際應用中是大量使用實體WebMthod的,比如:

[WebMethod]

public DataSet GetOrders() {};    //獲取所有訂單

[WebMethod]

public DataSet UpdateOrders(DataSet dsOrders){};     //更新指定訂單

因爲採取這種模式,所以系統裏邊有極多的WebMethod(WinformUI僅通過WS交互),一個標準WM的調用流程是:

客戶端壓縮WM中所有DS型的參數-〉調用WM-〉服務器端解壓所有DS型的參數-〉執行實際WM-〉對DS型的返回值進行壓縮-〉客戶端接收並解壓得出結果DS

上述流程的具體實現很麻煩,在客戶端用了AOP的透明代理的概念;服務器端則用了動態調用WS的技術。實現這種“雙代理”的模式後,對於WS端或Winform端,壓縮與不壓縮變得透明瞭,兩方面的程序員都不用再關心這個問題了。而且我覺得“雙代理”還可以爲我們處理其他很多的問題,比如排隊,異步操作,權限等等。那位朋友||大拿||高人有興趣探討這個問題的,小可甚喜!

發佈了13 篇原創文章 · 獲贊 2 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章