【原创】项目性能优化全纪录(二) 把ViewState放在服务器端

ViewState相信稍微懂asp.net的人都知道是什么东西。有部分人见到ViewState就头疼,因为其生成了很多废代码,浪费宝贵的流量。那现在让我们来看看如何在使用ViewState的情况下减少流量,即把viewstate放到服务器端去。

ViewState是一个信息集合,由.aspx页面上的控件生成,用于保存回发(postback)期间恢复控件状态的信息。

ViewState不会重新创建页面上的自定义控件或为控件恢复已发送的值,不能将其作为会话数据,因为它特定于页面,而不是会话。也不能在仅仅是服务器对象中使用,比如数据库连接,在使用Server.Transfer()做一次服务器端转向后它将不再有效。

从缓存角度来看,ViewSate还是很有用的,因为它可以作为页面的一部分,缓存仅仅与某个特定的页面相关信息。ViewState只能在Page_Init()事件之后,Page_PreRender()之前被读取和写入。Asp.net通过查看HTTP POST中是否存在_VIEWSTATE隐藏域来确定Page.IsPostBack的值。要把ViewState保存在服务器上,就必须重写Page类得LoadPageStateFromPersistenceMedium和SavePageStateToPersistencemedium两个方法。

具体实现方法如下:

  1 public class MyPage : Page//继承Page类
2 {
3 static private DirectoryInfo _Dir;
4
5
6
7 private static string UrlSuffix
8 {
9 get
10 {
11 return HttpContext.Current.Request.Url.Host + HttpContext.Current.Request.ApplicationPath;
12 }
13 }
14 private static string UrlBase
15 {
16 get
17 {
18 return @"http://" + UrlSuffix;
19 }
20 }
21
22
23 /// <summary>
24 /// ViewSate在服务器上的存放路径
25 /// </summary>
26 private DirectoryInfo Dir
27 {
28 get
29 {
30 if (_Dir == null)
31 {
32 _Dir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data"));//默认放在App_Data文件夹中
33 if (!_Dir.Exists)
34 _Dir.Create();
35 _Dir = new DirectoryInfo(Path.Combine(_Dir.FullName, "ViewState"));
36 if (!_Dir.Exists)
37 _Dir.Create();
38 }
39 return _Dir;
40 }
41 }
42 /// <summary>
43 /// 取出ViewState对象
44 /// </summary>
45 /// <returns></returns>
46 protected override object LoadPageStateFromPersistenceMedium()
47 {
48 PageStatePersister ps = this.PageStatePersister;
49 ps.Load();
50 if (ps.ControlState != null)
51 ps.ControlState = DeserializeObj((string)ps.ControlState);
52 if (ps.ViewState != null)
53 ps.ViewState = DeserializeObj((string)ps.ViewState);
54 return new Pair(ps.ControlState, ps.ViewState);
55 }
56 /// <summary>
57 /// 存入ViewState对象
58 /// </summary>
59 /// <param name="state"></param>
60 protected override void SavePageStateToPersistenceMedium(object state)
61 {
62 PageStatePersister ps = this.PageStatePersister;
63 if (state is Pair)
64 {
65 Pair pair = (Pair)state;
66 ps.ControlState = pair.First;
67 ps.ViewState = pair.Second;
68 }
69 else
70 {
71 ps.ViewState = state;
72 }
73 if (ps.ControlState != null)
74 ps.ControlState = SerializeObj(ps.ControlState);
75 if (ps.ViewState != null)
76 ps.ViewState = SerializeObj(ps.ViewState);
77 ps.Save();
78 }
79 /// <summary>
80 /// 反序列化viewstate对象
81 /// </summary>
82 /// <param name="stateID"></param>
83 /// <returns></returns>
84 private object DeserializeObj(string stateID)
85 {
86 string stateStr = (string)Cache[stateID];
87 string file = Path.Combine(Dir.FullName, stateID);
88 if (stateStr == null)
89 stateStr = File.ReadAllText(file);
90 else
91 Cache.Remove(stateID);
92 return new ObjectStateFormatter().Deserialize(stateStr);
93 }
94 /// <summary>
95 /// 序列化viewstate对象
96 /// </summary>
97 /// <param name="obj"></param>
98 /// <returns></returns>
99 private string SerializeObj(object obj)
100 {
101 string value = new ObjectStateFormatter().Serialize(obj);
102 string stateID = (DateTime.Now.Ticks + (long)value.GetHashCode()).ToString(); //产生离散的id号码
103 File.WriteAllText(Path.Combine(Dir.FullName, stateID), value);
104 Cache.Insert(stateID, value);
105 return stateID;
106 }
107 /// <summary>
108 /// 在页面卸载的时候删除无效的viewsate
109 /// </summary>
110 /// <param name="e"></param>
111 protected override void OnUnload(EventArgs e)
112 {
113 base.OnUnload(e);
114 DateTime dt = DateTime.Now.AddMinutes(-20);
115 foreach (FileInfo fl in Dir.GetFiles())
116 if (fl.LastAccessTime < dt)
117 try
118 {
119 fl.Delete();
120 }
121 catch
122 {
123 }
124 }
125 protected override void OnError(EventArgs e)
126 {
127 Logger.Write("Page error", "Resume.Classes.MyPage.OnError(EventArgs e)", Server.GetLastError());
128 base.OnError(e);
129 }
130
131 }

  

posted @ 2011-09-19 15:24  水晶泡泡  阅读(367)  评论(0编辑  收藏  举报