全部博文(64)
分类: 嵌入式
2012-11-03 19:16:11
ASP.NET有了ViewState变得异常强大,同时,也为人"诟病"。
往往你能在很多入门的书籍中看到:请谨慎或者禁用ViewState 这样的字眼。
它会让你的站点和用户交互起来很好很强大,也会增加页面的体积,让你的带宽资源变得很差很窘迫。
真的是鱼和熊掌不可兼得?未必。
我们拿一个实例来分析,找到解决问题的思路,而不是一刀切的思维模式。
------------------------
【空间换时间】
我们新建一个网站,使用默认的Default.aspx页面,给它拖拽一个GridView控件,然后显示几条数据看看。
很简单是吧,看看它的体积有多大:
它也生成了一堆体积庞大的ViewState:
在实际工程中,这么大容量的页面体积,难免会导致网络传输过程中有点缓慢。
----------------------------
恩,其实这个ViewState有三种保存形式:
一个是上面图中的【也是默认的】,推送到客户端浏览器;
一个是保存在服务器内存里【cache】;
一个是保存在服务器硬盘中。
这三种方式,我们选择哪个?
个人建议,保存在服务器硬盘中;
因为,如果存储在内存里,不能确保它的稳定性,消失了怎么办?
---------------------------------
同样的页面,我们保存到服务器硬盘中,是否有所改观呢?
先不贴代码,先看看疗效。
【ViewState存储到硬盘之后】
一眼看上去,页面代码整洁多了,以前体积庞大的字符串现在成了一行有ID的标示。
那页面体积呢?
体积缩小了接近50%,那么,既然我们没有禁用ViewState,那我们的视图状态哪里去了?
我把它保存在服务器磁盘中了。
这样,既不影响用户体验,又减少了页面体积,页面加载的速度自然就提升了。
【当然,视图状态为了安全,可以加密,这在本文末端有详细的代码示例】
---------------------------
该演示一下代码了,先在网站下创建一个文件夹存储视图状态的文件:
然后,添加一个类,来保存视图状态【红线部分自己多注意】:
然后,如果有那个页面想缩小体,就修改页面的基类,让页面从我们的这个管理类中派生:
就这么简单,怎么样,心动了吧?
快去动手试试吧!
----------------------------------
当然,如果你的服务器带宽资源很出色,就不一定不需要我的方法来降低网络负载。
------------------------------------------------------------------------------
Class1:
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.IO;
using System.Threading;
///
///Class1 的摘要说明
///
public class Class1 : System.Web.UI.Page
{
public Class1()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
protected override object LoadPageStateFromPersistenceMedium()
{
var viewStateID = (string)((Pair)base.LoadPageStateFromPersistenceMedium()).Second;
var stateObject = Cache[viewStateID];
if (stateObject != null)
{
return stateObject;
}
var fn = this.Server.MapPath("~/App_Data/ViewState/" + viewStateID);
var stateStr = File.ReadAllText(fn);
return new ObjectStateFormatter().Deserialize(stateStr);
}
protected override void SavePageStateToPersistenceMedium(object state)
{
var viewStateID = (DateTime.Now.Ticks + this.GetHashCode()).ToString();
Cache.Insert(viewStateID, state);
ThreadPool.QueueUserWorkItem(obj =>
{
var value = new ObjectStateFormatter().Serialize(state);
var fn = this.Server.MapPath("~/App_Data/ViewState/" + viewStateID);
File.WriteAllText(fn,value);
});
base.SavePageStateToPersistenceMedium(viewStateID);
}
}
--------------------------------------------------------------------
http://hi.baidu.com/mybblog/item/9a74bc0cd5b570cb75cd3c4d