ASP.NET Web API GZip/Deflat 資料遺失迷航記
前情提要:參考(1)(2),之前測試發現 ASP.NET Web API 有個查詢資料量不小(1.92 MB),並且會有同等級的上傳行為,在 ASP.NET Web API 加入 GZIP/Deflate (解)壓縮來改善效能,資料由 1.92 MB → 50 KB 壓縮率約 40 倍,這是用一點 CPU 來改善效能的好範例。
同事回報,在測試區當資料量提升至 3.3 MB(3338506 bytes) 後,程式有機會(隨機)出錯(Exception)。
先來看 HTTP POST 流程:
RestSharp (RawData: Over 3.3 MB) → GZIP → GZIP ByteArray (79515 bytes) → HTTP POST → ASP.NET Web API
這是個 VSTO 的 Excel 應用程式,在讀取 Web API 資料之後,原封不同進行上傳(HTTP POST)動作,由側錄取得離線 RawData 約 3.3 MB,經過 GZIP 壓縮後得到約 78 KB 的 Byte Array 資料,最後使用參考(2)程式碼送出:
request.AddParameter("application/json", content.ToArray(), ParameterType.RequestBody);
接收流程:
ASP.NET Web API → DecompressionHandler → RawData → Web API life cycle
Web API 收到請求後安排一個 Message Handler 進行解壓縮後取得 RawData 之後,按 Web API 生命流程往下進行。
程式穩定運作,經過許多分析與測試後,在終於在 Web API 側錄到錯誤發生時的資訊:
在 DecompressionHandler 取得的 GZIP ByteArray 大小為 77889,很明顯小於原始的 79515,把解壓縮的 RawData 資料 Dump 出來後確實資料短少被截斷了,造成後續 Web API 在進行 ModelBinding 時的不正常 Exception。