压缩ViewState

在状态管理中经常要用到ViewState 可是当数据比较大的时候我们可以压缩ViewState。压缩的方式很多,

1。在这里提供通过重写PageStatePersister属性来实现

先写一个压缩的工具类:

   public class CompressHelp
    {
        static LosFormatter formatter = new LosFormatter();
        public static object Decompress(string stateString)
        {
            byte[] buffer = Convert.FromBase64String(stateString);
            MemoryStream ms = new MemoryStream(buffer);
            GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);
            MemoryStream msReader = new MemoryStream(buffer);
            buffer = new byte[0x1000];
            while (true)
            {
                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);
            return formatter.Deserialize(stateString);
        }
        public static string Compress(object state)
        {
            StringWriter writer = new StringWriter();
            formatter.Serialize(writer, state);
            string stateString = writer.ToString();
            writer.Close();
            byte[] buffer = Convert.FromBase64String(stateString);
            MemoryStream ms = new MemoryStream();
            GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, true);
            zipStream.Write(buffer, 0, buffer.Length);
            zipStream.Close();
            buffer = new byte[ms.Length];
            ms.Position = 0;
            ms.Read(buffer, 0, buffer.Length);
            ms.Close();
            stateString = Convert.ToBase64String(buffer);
            return stateString;
        }
    }

新增一个CompressPageStatePersister类:

public class CompressPageStatePersister : PageStatePersister
    {
        string PageStateKey = "_VIEWSTATE";
        public CompressPageStatePersister(Page page) : base(page) { }

        public override void Load()
        {
            string postbackState = Page.Request.Form[PageStateKey];
            if (!string.IsNullOrEmpty(postbackState))
            {
                Pair statePair = (Pair)CompressHelp.Decompress(postbackState);
                if (!Page.EnableViewState)
                    this.ViewState = null;
                else
                    this.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);
                string stateString = CompressHelp.Compress(statePair);
                Page.ClientScript.RegisterHiddenField(PageStateKey, stateString);
            }
        }
    }

使用方式,在page页面中:

   protected override PageStatePersister PageStatePersister
        {
            get
            {
                return new CompressPageStatePersister(this);
            }
        }

注意:此种实现不支持AJAX,即只能是同步方式

2。重写page的SavePageStateToPersistenceMedium方法和LoadPageStateFromPersistenceMedium方法

首先写一个工具类:

    public class Utils
    {
        public static bool IsMsAjaxCallback(HttpRequest request)
        {
            return (request != null && request.Headers["X-MicrosoftAjax"] != null);
        }
        public static byte[] Compress(byte[] data)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
                {
                    zip.Write(data, 0, data.Length);
                    zip.Dispose();
                    return ms.ToArray();
                }
            }
        }
        public static Byte[] Compress(string viewState)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] data = Convert.FromBase64String(viewState);
                Deflater defaulter = new Deflater(Deflater.BEST_COMPRESSION);
                DeflaterOutputStream oms = new DeflaterOutputStream(ms, defaulter, 131072);
                oms.Write(data, 0, data.Length);
                oms.Close();
                return ms.ToArray();
            }
        }
        public static byte[] DeCompress(byte[] data)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                int dataLength = BitConverter.ToInt32(data, 0);
                ms.Write(data, 0, data.Length);
                byte[] buffer = new byte[dataLength];
                ms.Position = 0;
                using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
                {
                    zip.Read(buffer, 0, buffer.Length);
                }
                return buffer;
            }
        }
        public static Byte[] DeCompress(string viewState)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] data = Convert.FromBase64String(viewState);
                InflaterInputStream ims = new InflaterInputStream(new MemoryStream(data));
                int msize;
                byte[] tempdata = new byte[4096];
                while (true)
                {
                    msize = ims.Read(tempdata, 0, tempdata.Length);
                    if (msize > 0)
                        ms.Write(tempdata, 0, msize);
                    else break;
                }
                ims.Close();
                return ms.ToArray();
            }
        }
    }

使用方式

  protected override void SavePageStateToPersistenceMedium(object state)
        {
            LosFormatter formatter = new LosFormatter();
            using (StringWriter writer = new StringWriter())
            {
                formatter.Serialize(writer, state);
                string viewState = writer.ToString();
                if (Utils.IsMsAjaxCallback(Request))
                {
                    byte[] data = Convert.FromBase64String(viewState);
                    data = Utils.Compress(data);
                    ScriptManager.RegisterHiddenField(this, "_COMPRESSEDVS", Convert.ToBase64String(data));
                }
                else
                {
                    Boolean mUseZip = false;
                    if (viewState.Length > LimitLength)
                    {
                        mUseZip = true;
                        byte[] data = Utils.Compress(viewState);
                        viewState = Convert.ToBase64String(data);
                    }
                    ScriptManager.RegisterHiddenField(this, "_MSPVSTATE", viewState);
                    ScriptManager.RegisterHiddenField(this, "_MSPVSTATE_ZIP", mUseZip.ToString().ToLower());
                }
            }
        }
        protected override object LoadPageStateFromPersistenceMedium()
        {
            string viewState = Request.Form["_COMPRESSEDVS"];
            LosFormatter formatter = new LosFormatter();
            byte[] data;
            if (viewState != null && viewState.Length > 0)
            {
                data = Convert.FromBase64String(viewState);
                data = Utils.DeCompress(data);
                return formatter.Deserialize(Convert.ToBase64String(data));
            }
            else
            {
                viewState = Request.Form.Get("_MSPVSTATE");
                bool zip = bool.Parse(Request.Form.Get("_MSPVSTATE_ZIP"));
                if (zip) data = Utils.DeCompress(viewState);
                else data = Convert.FromBase64String(viewState);
                return formatter.Deserialize(Convert.ToBase64String(data));
            }
        }

在这里用了第三方的工具包ICSharpCode.SharpZipLib

该实例可以在http://download.csdn.net/source/1864129下载

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值