惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
SegmentFault 最新的问题
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Attack and Defense Labs
Attack and Defense Labs
F
Full Disclosure
Vercel News
Vercel News
N
News | PayPal Newsroom
The GitHub Blog
The GitHub Blog
H
Hacker News: Front Page
H
Heimdal Security Blog
P
Privacy International News Feed
博客园 - 司徒正美
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cisco Blogs
L
Lohrmann on Cybersecurity
D
Docker
Recent Announcements
Recent Announcements
Security Archives - TechRepublic
Security Archives - TechRepublic
人人都是产品经理
人人都是产品经理
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Proofpoint News Feed
T
Tailwind CSS Blog
C
Check Point Blog
博客园 - 叶小钗
Google Online Security Blog
Google Online Security Blog
Martin Fowler
Martin Fowler
Stack Overflow Blog
Stack Overflow Blog
博客园 - 聂微东
S
Secure Thoughts
博客园 - Franky
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
P
Palo Alto Networks Blog
Latest news
Latest news
量子位
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog
Last Week in AI
Last Week in AI
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Cisco Talos Blog
Cisco Talos Blog
Hacker News: Ask HN
Hacker News: Ask HN
T
Threatpost
T
Tenable Blog
P
Privacy & Cybersecurity Law Blog
WordPress大学
WordPress大学

博客园 - Mack.Z

压缩ASP.NET中的ViewState MSPlus.TabControl V1.1 版本发布 发布MSPlus TabControl WebControl V1.0.0710 版本 Html Convert Image (Html2Image) Gaia(MasterPage)我的第一个开源控件 MSN Winks 文件的解密 学习SPRING中的一个疑惑.请教一下各位 发布MSPlus DatePicker WebControl V2.0.1201 版本 发布MSPlus ToolBar&Menu WebControl V1.1.0910 版本 MSPlus DatePicker WebControl FreeVersion 1.1.0906 发布啦! 关于MSPlus控件下载后用VS.NET打开提示目录不对的解决方法 - Mack.Z - 博客园 MSPlus ToolBar&Menu WebControl FreeVersion 1.1.0830 发布拉 - Mack.Z [原创]复合控件中如何将客户端的处理结果通知服务器端的解决办法 [原创]屏蔽.NET自定义开发组件中的属性 MSPlus DataList Control(大数据量时的分页演示) MSPlus DataList Control 1.1.0818(个人版) 发布! MSPLUS-DropDownList Control [DEMO Download] 想开发.Net Server Controls 的初学者必读资料 MSPlus-ToolBar Control - Mack.Z - 博客园
压缩ASP.NET中的ViewState的改进方法 - Mack.Z - 博客园
Mack.Z · 2005-07-28 · via 博客园 - Mack.Z

昨晚上写了一篇"压缩ASP.NET中的ViewState"的文章,大家都对这种方式是否会带来性能上消耗的问题比较关心.
有一点是肯定的,压缩ViewState的减少网络带宽的占用,肯定会对性能有影响.

我作了一个小小的测试.先后用同一个页面加密和不加密的情况下,刷新页面观测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


今天双鱼座网友的留言写的挺好的:
我觉得真的很在乎服务器开销的话,建议修改一下方法,如果序列化后的长度大于某个值才压缩,然后在压缩码的最前面加上某个标记以便载入时判断是否为压缩的数据。
有些在使用TreeView和DataGrid的时候,数据量是很大的,达到数百K之巨。但是另外一些时候数据量很小,再压缩就非常不合算了。
另外,如果系统是面向internet的应用应该以网络带宽负荷为优先;局域网内的应用则应以服务器CPU负荷为优先,不一而论。


晚上借用加班的时间按双鱼座网友的方案对代码进行了一些改动,可以设置当ViewState为多大时才启用压缩,和压缩比率的设置.

修改后的源码如下:

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

    }

}

其中压缩组件用的是SharpZipLib