[ASP.NET] ViewState壓縮

當網頁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();
        }

參考文章:[ASP.NET]使用SharpZipLib進行網頁ViewState壓縮

ViewState壓縮相容於UpdatePanel (VB.NET版本)