网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > ASP.NET技巧
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.Asp.net下的对象成员数据绑定器实.
.asp.net ajax 使用updatepanel进.
.asp.net里导出excel表方法汇总.
.使Div内内容可编辑.
.实现asp.net只对个别控件实时访问.
.动态控制Page页的Head信息.
.ASP.NET底层架构探索之IE6的革新.
.使用ASP.NET Atlas编写显示真实进.
.ASP.net组件编程中的两种事件编写.
.ASP.NET 2.0页面框架简要慨述.
.ASP.NET构架与安全机制之Http请求.
.ASP.NET 2.0服务器控件开发精要.
.RSS 文档中 language 标签中的可.
.如何实现无刷新的DropdownList联.
.利用.NET的File控件上传文件的最.
.使用asp.net2.0中的SiteMap中的一.
.IFRAME跨域名的解决方法,终结版.
.asp.net 2.0中一次性更新所有GRI.
.ASP.NET 2.0 中使用自定义缓存依.
.UrlRewriter重写地址的POSTBACK后.

小议优化ASP.NET应用性能之ViewState篇

发表日期:2006-8-2


    如果你有在IE中查看当前浏览页面HTML源代码的习惯,你也许常会看到类似以下的代码片断:
<input type="hidden" name="__VIEWSTATE" value="dDwtMzU5NzUyMTQ1O3Q8O2w8aTwwPjs+O2w8dDw7bDxpPDA+Oz47bDx0PDtsPG
……

  聪明的你一定会问,这是什么?有什么作用?它与本篇文章有何转折亲关系?各位看官,且听我慢慢道来。
  其实,这就是MS在Asp.net应用ViewState技术的特征表现。为了页面能在PostBack后依然能读取服务器控件原有的状态数据,Asp.net中使用了ViewState技术,而ViewState技术本质上是用一个默认名称为"__VIEWSTATE的Hidden类型表单域来保存和传递数据(这些数据是经过了序列化后Base64编码的字符串值,且是在方法Page.SavePageStateToPersistenceMedium输出前保存、并由Page.LoadPageStateFromPersistenceMedium加载)。虽然我们可以通过三种级别来轻松禁用掉这些数据的往返传递:

Machine级 在machine.config中设置<pages enableViewStateMac='false' />
Application级 在Web Applicatin的web.config中设置<pages enableViewStateMac='false' />
单页面级 在该页面中设置<%@Page enableViewStateMac='false' %>或通过代码设置Page.EnableViewStateMac = false;
 
  可是,如果我们完全能通过禁用ViewState来解决数据传输负担而且不产生副作用的话,那MS的架构师们也不会傻到如此可爱的地步(可有可无的东东留它何用?),正因我们往往不能通过简单的禁用来解决这个传输负担问题,所以我们只能另辟路径使之在网络往返中传输量尽可能地小,于是,压缩成了我们的首选。只要我们重载Page类的SavePageStateToPersistenceMedium()方法与LoadPageStateFromPersistenceMedium()方法,并在重载方法中对数据进行压缩与解压的处理即可。开源项目SharpZipLib提供的类GZipInputStream与GZipOutputStream进入了我们的视野,为了方便,不妨写个类CompressionHelper,代码如下:

 1using System.IO;
 2using ICSharpCode.SharpZipLib.GZip;
 3
 4namespace Ycweb.Components
 5{
 6    /**//// <summary>
 7    /// Summary description for CompressionHelper.
 8    /// </summary>
 9    public class CompressionHelper
10    {
11        public CompressionHelper()
12        {
13            //
14            // TODO: Add constructor logic here
15            //
16        }
17
18        /**//// <summary>
19        /// 压缩数据
20        /// </summary>
21        /// <param name="data">待压缩的字节数组</param>
22        /// <returns>压缩后的字节数组</returns>
23        public static byte[] CompressByte(byte[] data)
24        {
25            MemoryStream ms = new MemoryStream();
26            Stream s=new GZipOutputStream(ms);   
27            s.Write( data, 0, data.Length );
28            s.Close();
29            return ms.ToArray();   
30        }
31
32        /**//// <summary>
33        /// 解压数据
34        /// </summary>
35        /// <param name="data">待解压的字节数组</param>
36        /// <returns>解压出的字节数组</returns>
37        public static byte[] DeCompressByte(byte[] data)
38        {
39            byte[] writeData = new byte[2048];
40            MemoryStream ms= new MemoryStream( data );
41            Stream sm = new GZipInputStream(ms) as Stream;
42            MemoryStream outStream = new MemoryStream();
43            while (true)
44            {
45                int size = sm.Read(writeData,0, writeData.Length );
46                if (size >0)
47                {
48                    outStream.Write(writeData,0,size);
49                }
50                else
51                {
52                    break;
53                }
54            }
55            sm.Close();
56            byte[] outArr = outStream.ToArray();
57            outStream.Close();
58            return outArr;   
59        }
60    }
61}      然后我们在派生于类Page的页面控制基类中重载方法LoadPageStateFromPersistenceMedium()与SavePageStateToPersistenceMedium(Object viewState),代码如下:
 1Load & Save ViewState Data#region Load & Save ViewState Data
 2        protected override object LoadPageStateFromPersistenceMedium()
 3        {
 4//从自己注册的隐藏域__SmartViewState中读取数据
 5            string viewState = Request.Form["__SmartViewState"];
 6            byte[] bytes = Convert.FromBase64String(viewState);
 7            //调用上面提供的静态方法CompressionHelper.DeCompressByte()来解压数据
 8            bytes = CompressionHelper.DeCompressByte(bytes);
 9            LosFormatter formatter = new LosFormatter();
10            return formatter.Deserialize(Convert.ToBase64String(bytes));
11   
12        }
13
14        protected override void SavePageStateToPersistenceMedium(Object viewState)
15        {
16            LosFormatter formatter = new LosFormatter();
17            StringWriter writer = new StringWriter();
18            formatter.Serialize(writer, viewState);
19            string viewStateString = writer.ToString();
20            byte[] bytes = Convert.FromBase64String(viewStateString);
21            //调用上面提供的静态方法CompressionHelper.CompressByte()来压缩数据
22            bytes = CompressionHelper.CompressByte(bytes);
23           
24            //注册一个新的隐藏域__SmartViewState,你也可以自己定义
25            this.RegisterHiddenField("__SmartViewState", Convert.ToBase64String(bytes));   
26        }
27#endregion
   经过以上处理,web输出页面中的源代码就是型如:
<input type="hidden" name="__SmartViewState" value="H4sIAPtPoNwA/81ce1PbWJb/ ……
<input type="hidden" name="__VIEWSTATE" value="" />
    原来的隐藏域"__VIEWSTATE"值为空,而取而代之的是我们自己注册的新的隐藏域"__SmartViewState"来存储了经过压缩后的字符串,这样以来,提速效果是明显的,结合我们的项目,象DG3G.COM的首页原ViewState串值大约是28K,压缩后为7K,而Acafa.com的首页原ViewState串值大约是43K,压缩后为8K。这样的处理还是比较令人满意的。当然,如果你觉得还不够彻底,你还可以把ViewState串存储在Session中,不过这样做,对服务器内存的压力将陡增(尤其是访问量较大的时候),建议还是不要轻易使用,如果你Web服务器内存有个10G、8G的,不妨试试。下面给出相关修改代码:
将上述LoadPageStateFromPersistenceMedium()方法体中的代码:
    string viewState = Request.Form["__SmartViewState"];
修改为:
   string viewState = Session["__SmartViewState"].ToString();
同时,将上述SavePageStateToPersistenceMedium()体中的代码:
   this.RegisterHiddenField("__SmartViewState", Convert.ToBase64String(bytes));
修改为:
   Session["__SmartViewState"] = Convert.ToBase64String(bytes);

    末了,以上代码和方案均来自VS2003开发实践,对VS2005是否合适,本人不做任何承诺,不过如果你能从以上方案中有所收获,我将感到无比的高兴。

上一篇:ASP.NET的错误处理机制 人气:5012
下一篇:开发时复制aspx网页的方法_AX 人气:5264
浏览全部ASP.NET的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐