當網頁ViewState過大時,系統會需要使用壓縮技術減少USER下載網頁的時間,因此我參考了gipi與Mr.NFrankenstein的文章,改寫出Update Panel下ViewState過大進行壓縮的程式。
當網頁ViewState過大時,系統會需要使用壓縮技術減少USER下載網頁的時間,因此我參考了gipi與Mr.NFrankenstein的文章,改寫出Update Panel下ViewState過大進行壓縮的程式。
        /// 
        /// 設定序列化後的字串長度為多少後啟用壓縮
        ///  
        private static int LimitLength = 10240;
        /// 
        /// 設定壓縮比率,壓縮比率越高性消耗也將增大
        ///  
        private static int ZipLevel = ICSharpCode.SharpZipLib.Zip.Compression.Deflater.BEST_COMPRESSION;
       
 /// 
        /// override掉Page中原來的SavePageStateToPersistenceMedium()
        ///  
        protected override void SavePageStateToPersistenceMedium(object state)
        {
            Pair pair = default(Pair);
            PageStatePersister persister = this.PageStatePersister;
            object ViewState = null;
            LosFormatter formatter = new LosFormatter();
            StringWriter writer = new StringWriter();
            byte[] compressedData = null;
            string viewStateStr = string.Empty;
            if (state is Pair)
            {
                pair = (Pair)state;
                persister.ControlState = pair.First;
                ViewState = pair.Second;
            }
            else
                ViewState = state;
            formatter.Serialize(writer, ViewState);
            viewStateStr = writer.ToString();
            //沒超過壓縮標準則不壓縮
            if (viewStateStr.Length < LimitLength)
                ZipLevel = ICSharpCode.SharpZipLib.Zip.Compression.Deflater.NO_COMPRESSION;
            compressedData = this.CompressStrToByte(viewStateStr, ZipLevel);
            viewStateStr = Convert.ToBase64String(compressedData);
            persister.ViewState = viewStateStr;
            persister.Save();
        }
        /// 
        /// 重寫將所有保存的視圖狀態資訊載入到頁面物件
        ///  
        /// 保存的ViewState 
        protected override object LoadPageStateFromPersistenceMedium()
        {
            string viewState = string.Empty;
            PageStatePersister persister = this.PageStatePersister;
            byte[] uncompressedData = null;
            LosFormatter formatter = new LosFormatter();
            persister.Load();
            viewState = persister.ViewState.ToString();
            uncompressedData = this.DeCompressStrToByte(viewState);
            viewState = Convert.ToBase64String(uncompressedData);
            return new Pair(persister.ControlState, formatter.Deserialize(viewState));
        }
/// 
        /// 對字串進行壓縮
        ///  
        ///字串
        /// 返回流的位元組陣列 
        public static Byte[] CompressStrToByte(string CompressString, int ZipLevel = Deflater.DEFAULT_COMPRESSION)
        {
            //將字串轉換為位元組陣列
            Byte[] pBytes = System.Convert.FromBase64String(CompressString);
            //建立記憶體的Stream
            MemoryStream mMemory = new MemoryStream();
            Deflater mDeflater = new Deflater(ZipLevel);
            ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream mStream =
                new ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream(mMemory, mDeflater, 131072);
            mStream.Write(pBytes, 0, pBytes.Length);
            mStream.Close();
            return mMemory.ToArray();
        }
        /// 
        /// 解壓縮字串
        ///  
        ///壓縮字串
        /// 返回流的位元組陣列 
        public static Byte[] DeCompressStrToByte(string CompressString)
        {
            //將Base64字串轉換為位元組陣列
            Byte[] pBytes = System.Convert.FromBase64String(CompressString);
            ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream mStream =
                new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(new MemoryStream(pBytes));
            //創建支援記憶體存儲的流
            MemoryStream mMemory = new MemoryStream();
            Int32 mSize;
            Byte[] mWriteData = new Byte[4096];
            while (true)
            {
                mSize = mStream.Read(mWriteData, 0, mWriteData.Length);
                if (mSize > 0)
                {
                    mMemory.Write(mWriteData, 0, mSize);
                }
                else
                {
                    break;
                }
            }
            mStream.Close();
            return mMemory.ToArray();
        }