在.Net平台下进行CS软件开发时,我们经常遇到以后还要用到某些变量上次修改后的值,为了简单起见,很多人都习惯用static来定义这些变量,我也是。这样非常方便,下一次调用某个函数时该变量仍然保存的是处理过的值,直接拿来用就可以了。
现在转入了BS软件开发,我们很自然地会沿用这种习惯。如在页面中统计某个按钮被按下的次数,先在类中OnClick事件的处理过程前定义一static变量times,则每次调用该按钮的OnClick事件时,令times增1即可,非常方便:
[C#]:
代码如下:
...
static int times=0;
...
private void Button1_Click(object sender,EventArgs e)
{
times++;
Label1.Text=times.ToString();
}
在我们庆幸如此方便之余,就未曾意识到我们已经埋下了一棵难以察觉的定时炸弹。为什么哪?
这还要从Asp.net的运行机制谈起。在CS模式软件开发过程中,我们通常不会关心应用程序是在哪里运行的,变量存放在哪里,客户端程序就运行在客户端,服务器端程序就运行在服务器端,一般情况下,二者除了数据库中的数据外基本没有其他共享的东西。所以这时客户端的用户大可放心的使用static变量,因为它们就存放在客户端程序中。
于是我们就习惯的在做BS模式的页面时也用static变量,殊不知Asp.net中的static已不同于CS中的static。原因很简单,就是因为在Asp.net中所有的用户将使用同一个static变量。这就意味着每一个使用该页面的用户对该变量的操作将会影响到其他用户。就拿上面计数器的例子来说,假设times初试值为0,因为此时只有我们自己在使用这个页面,当然不会有什么问题,但如果有两个人同时连接到这个页面,如果A单击了Button1一次,则B刷新页面后Label1将显示1,如果B再单击Button1一次,则times变成2,两个人刷新页面后就出现问题了:A和B都会说,我明明只单击了Button1一次,怎么Label1就显示我单击了两次哪?——这就是因为两个人共用的是服务器上同一个times,任何一个人对times的操作都会在使用该页面的他人的浏览器中表现出来。问题就出在这里。
怎么办哪?还好,除了传统的Asp中的Session对象外,Asp.net提供了一个更好的ViewState对象。ViewState对象用来保存页面中的各种变量,甚至是对象。使用方法和HashTable类似,只要用变量名称做索引,如ViewState["Var"],就可以用存取变量Var的值,而不管Var是普通变量,还是对象,甚至是内存中的一张DataTable,太方便了。为什么可以用ViewState而不能用static变量哪?原因就是服务器端会为每个连接到该页面的用户分别建立一个ViewState,所以ViewState相当于页面级的Session。这下我们可以放心地使用ViewState来存取需要暂存的变量和对象了。
ViewState的用法很简单,如下所示:
新闻热点
疑难解答
图片精选