ASP.NET3.5控制項與元件開發大全學習筆記:Ch6實作PageStatePersister 來壓縮ViewState

  • 2549
  • 0

摘要:學習筆記:Ch6實作PageStatePersister 來壓縮ViewState

1.壓縮方法

public class CompressHelp
    {
        //序列化工具,LosFormatter是頁面預設的序列器
        private static LosFormatter _formatter = new LosFormatter();

        /// <summary>
        /// 解壓並反序列化狀態內容
        /// </summary>
        /// <param name="stateString">從用戶端取回的頁面狀態字串</param>
        /// <returns>還原後的頁面狀態Pair物件</returns>

        public static object Decompress(string stateString)
        {
            byte[] buffer = Convert.FromBase64String(stateString);
            MemoryStream ms = new MemoryStream(buffer);//將內容放作MemoryStream
            GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);//解壓
            MemoryStream msReader = new MemoryStream();
            buffer = new byte[0x1000];// buffer = new byte[4096];
            while (true)//將解壓內容讀入msReader
            {
                int read = zipStream.Read(buffer, 0, buffer.Length);
                if (read <= 0)
                    break;
                msReader.Write(buffer, 0, read);
                
            }

            zipStream.Close();
            ms.Close();
            msReader.Position = 0;//設定為最前面
            buffer = msReader.ToArray();//取出內容
            stateString = Convert.ToBase64String(buffer);//將byte變為字串
            return _formatter.Deserialize(stateString);//反序列
        }


        /// <summary>
        /// 序列化並壓縮狀態資料
        /// </summary>
        /// <param name="state">頁面狀態</param>
        /// <returns>結果字串</returns>

        public static string Compress(object state)
        {
            StringWriter writer = new StringWriter();
            _formatter.Serialize(writer, state);
            string stateString = writer.ToString();
            byte[] buffer = Convert.FromBase64String(stateString);
            
            //將壓縮內容寫入ms
            MemoryStream ms = new MemoryStream();
            GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, true);
            zipStream.Write(buffer, 0, buffer.Length);
            zipStream.Close();

            //將壓縮內容取出至buffer
            buffer = new byte[ms.Length];
            ms.Position = 0;
            ms.Read(buffer, 0, buffer.Length);
            ms.Close();
            //將buffer轉成base64字串
            stateString = Convert.ToBase64String(buffer);
            return stateString;
        }

    }

 

 2.實作PageStatePersister

/// <summary>
    /// 實作PageStatePersister 來壓縮ViewState
    /// </summary>

    public class CompressPageStatePersister : PageStatePersister
    {
        //頁面狀態鍵值
        private string PageStateKey = "____VIEWSTATE";

        public CompressPageStatePersister(Page page)
            : base(page)
        {

        }


        public override void Load()
        {
            //取得頁面狀態鍵值
            string postbackState = Page.Request.Form[PageStateKey];
            if (string.IsNullOrEmpty(postbackState))
                return;
            //頁面狀態包括視圖狀態和控制項狀態兩部分
            Pair statePair = (Pair)CompressHelp.Decompress(postbackState);
            if(!Page.EnableViewState)
                this.ViewState=null;
            else
                ViewState = statePair.First;//視圖狀態
            this.ControlState = statePair.Second;//控制項狀態

        }


        public override void Save()
        {
            if (!Page.EnableViewState)
                this.ViewState = null;
            if (this.ViewState != null || this.ControlState != null)
            {
                Pair statePair = new Pair(ViewState, ControlState);//將頁面狀態及控制項狀態存到Pair
                string stateString = CompressHelp.Compress(statePair);//壓縮物件並序列化成字串

                Page.ClientScript.RegisterHiddenField(PageStateKey, stateString);//存在隱藏欄位
            }

        }

    }

 

3.使用方式

 

public partial class CompressPageState : System.Web.UI.Page
    {
        protected override PageStatePersister PageStatePersister
        {
            get
            {
                return new CompressPageStatePersister(this);
            }

        }

        protected void Page_Load(object sender, EventArgs e)
        {

        }


        protected void btnShow_Click(object sender, EventArgs e)
        {
            this.lblMsg.Text = "";
            for (int i = 0; i < 1000; i++)
            {
                this.lblMsg.Text += DateTime.Now.ToShortTimeString() + " OK:" + this.ViewStateControl1.FaceStyle.OK + "<br>";

            }

        }

    }