压缩ASP.NET中的ViewState的方法

来源:互联网 发布:淘宝商城男装运动套装 编辑:程序博客网 时间:2024/05/09 22:31

服务器端控件带来的好外我在这就不多说了,但多过的使用服务器端件保存控件的状态会带来大量的ViewState的情况大家一定遇到过吧.过多的ViewState会很大程度上降低页面的加载速度制成服务器端的性能下降.

以下是结合CSharpZipLib对ViewState进行压缩的方法.

MSPlus.Web.UI.Page 源码:

 

using System;
using System.Web.UI;
using System.IO;
using ICSharpCode.SharpZipLib.Zip.Compression;

namespace MSPlus.Web.UI
{
    
/**//// <summary>
    
/// PageClass 的摘要说明。
    
/// </summary>

    public class Page : System.Web.UI.Page
    
{
        
/**//// <summary>
        
/// 设定序列化后的字符串长度为多少后启用压缩
        
/// </summary>

        private static Int32 LimitLength = 1096;

        
/**//// <summary>
        
/// 设定压缩比率,压缩比率越高性消耗也将增大
        
/// </summary>

        private static Int32 ZipLevel    = ICSharpCode.SharpZipLib.Zip.Compression.Deflater.BEST_COMPRESSION;

        
/**//// <summary>
        
/// 重写保存页的所有视图状态信息
        
/// </summary>
        
/// <param name="pViewState">要在其中存储视图状态信息的对象</param>

        protected override void SavePageStateToPersistenceMedium(Object pViewState)
        
{
            
//实现一个用于将信息写入字符串的 TextWriter
            StringWriter mWriter    = new StringWriter();

            
//序列化 Web 窗体页的视图状态
            LosFormatter mFormat    = new LosFormatter();

            
//将有限对象序列化 (LOS) 格式化的对象转换为视图状态值
            mFormat.Serialize(mWriter, pViewState);

            
//将序列化对象转成Base64字符串
            String vStateStr = mWriter.ToString();

            
//设置是否启用了加密方式,默认情况下为不启用
            Boolean mUseZip = false;

            
//判断序列化对象的字符串长度是否超出定义的长度界限
            if(vStateStr.Length > LimitLength)
            
{
                
//对于长度超出阶线的进行加密,同时将状态设为加密方式
                mUseZip = true;

                Byte[] pBytes 
= Compress(vStateStr);

                
//将字节数组转换为Base64字符串
                vStateStr = System.Convert.ToBase64String(pBytes); 
            }


            
//注册在页面储存ViewState状态的隐藏文本框,并将内容写入这个文本框
            RegisterHiddenField("__MSPVSTATE", vStateStr);

            
//注册在页面储存是否启用压缩状态的文本框,并将启用状态写入这个文本框
            RegisterHiddenField("__MSPVSTATE_ZIP", mUseZip.ToString().ToLower());
        }


        
/**//// <summary>
        
/// 对字符串进行压缩
        
/// </summary>
        
/// <param name="pViewState">ViewState字符串</param>
        
/// <returns>返回流的字节数组</returns>

        public static Byte[] Compress(String pViewState) 
        

            
//将存储状态的Base64字串转换为字节数组
            Byte[] pBytes = System.Convert.FromBase64String(pViewState);

            
//创建支持内存存储的流
            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();
        }
 

        
/**//// <summary>
        
/// 重写将所有保存的视图状态信息加载到页面对象
        
/// </summary>
        
/// <returns>保存的视图状态</returns>

        protected override Object LoadPageStateFromPersistenceMedium()
        
{
            
//使用Request方法获取序列化的ViewState字符串
            String mViewState        = this.Request.Form.Get("__MSPVSTATE");
            
//使和Request方法获取当前的ViewState是否启用了压缩
            String mViewStateZip    = this.Request.Form.Get("__MSPVSTATE_ZIP");

            Byte[] pBytes;

            
if(mViewStateZip == "true")
            
{
                pBytes 
= DeCompress(mViewState);
            }

            
else
            
{
                
//将ViewState的Base64字符串转换成字节
                pBytes = System.Convert.FromBase64String(mViewState);
            }


            
//序列化 Web 窗体页的视图状态
            LosFormatter mFormat = new LosFormatter();

            
//将指定的视图状态值转换为有限对象序列化 (LOS) 格式化的对象
            return mFormat.Deserialize(System.Convert.ToBase64String(pBytes));
        }


        
/**//// <summary>
        
/// 解压缩ViewState字符串
        
/// </summary>
        
/// <param name="pViewState">ViewState字符串</param>
        
/// <returns>返回流的字节数组</returns>

        public static Byte[] DeCompress(String pViewState) 
        

            
//将Base64字符串转换为字节数组
            Byte[] pBytes = System.Convert.FromBase64String(pViewState);

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

    }

}

 

使用方法(ASPX.CS页面继承MSPlus.Web.UI.Page):public class PageClass : System.Web.UI.Page


测试下来的结果:压缩后的ViewState只有原来的20%!


我作了一个小小的测试.先后用同一个页面加密和不加密的情况下,刷新页面观测w3wp.exe的CPU占用情况.此页面的ViewState大小为3.996 Bytes

w3wp.exe 以下是每次刷新的时CPU的情况

05 03 05 03 06 05 05 08 03 05 03 不加密,平均是 4.6
05 05 06 05 05 03 08 02 03 05 06 加密,平均是5.3
其中压缩组件用的是SharpZipLib 
 
原创粉丝点击