[转]ASP.NET变量的作用域
ASP.NET不同于delphi等WinForm,因为桌面程序是面向一个用户,而ASP.NET是面向多个用户。
所以,当你在程序中的class下,在方法、函数前写变量是,虽然是全页变量,但只要页面刷新,这个新赋值的值都会丢失。
如:
public class along:System.Web.UI.Page { string s="a"; protected void Button1_Click() { s+="b"; textbox1.text=s; } protected void Button2_Click() { s+="c"; textbox1.text=s; } }
你会发现 每当你点击按钮的时候,s的值并没有重复累加,而只是从初始化的a开始。
由于我们每次刷新asp.net页面都是一个全新的对象,而不是上一次访问的对象。所以上次页面访问时对页面中变量的改动都没有保留。遇到这个问题的时候直觉就将这个变量设置成static,这样是可以保留住页面中变量的状态。但这个状态是针对一个客户端的(如同 session的效果)。而得到的结果是只要一个客户端改变了该值则所有的其他客户端都受到 了影响(如同Applicatin的效果)。
究其原因这还要从Asp.net的运行机制谈起。在C/S模式软件开发过程中,我们通常不会关心应用程序是在哪里运行的,变量存放在哪里,客户端程序就运行在客户端,服务器端程序就运行在服务器端,一般情况下,二者除了数据库中的数据外基本没有其他共享的问题。 所以这时客户端的用户大可放心的使用static变量,因为它们就存放在客户端程序中。于是我们就习惯的在做B/S模式的页面时也用static变量,殊不知Asp.net中的static已不同于C/S中的static。是因为在Asp.net中所有的用户将使用同一个static变量。这就意味 着每一个使用该页面的用户对该变量的操作将会影响到其他用户。
解决的办法之一是可以选择Asp.net提供的ViewState对象。ViewState对象可以用来保 存页面中的各种变量,甚至是对象。“有些数据可以直接保存到ViewState中,诸如字符串 、整数、布尔、数组里表、哈希表等。”只要用变量名称做索引,如ViewState[“Var ”], 就可以存取变量Var的值,而不管Var是普通变量,还是对象,甚至是内存中的一张DataTable。服务器端会为每个连接到该页面的用户分别建立一个ViewState,所以ViewState相当于 页面级的Session。相当于页面全局变量,但是一旦退出当前页面,它就会丢失。
ViewState的用法很简单,如下所示:
1、保存变量到ViewState中: ViewState[“times”]=times; //存放普通变量times
ViewState[“Orders”]=dtOrders; //存放DataTable型对象dtOrders
2、读出ViewState中的值: times=(int)ViewState[“times”];
dtOrders=(DataTable)ViewState[“Orders”];
读出变量的值时要进行强制类型转换,这是因为当变量(不管是int型的普通变量times ,还是DataTable型的对象dtOrders)被存放到ViewState中后统统按Object类型存放。所以当我们从ViewState取出时,一定要转换成相应的类型,否则就会报错。在变量保存到ViewS tate中时,系统会自动转换。
这不是说static型变量就没用了,在C#中用static声明的类不用实例化直接使用。正是 由于所有用户共享服务器端的同一个static变量,所以可以用static型对象来存取一些公用 的处理模块,比如类型转换、变量验证等工作。所以要根据具体情况而定。
还有一点需要注意:如果在页面中多个过程要共享一个对象或变量,我们在页面类的开始部分定义一个页面级的全局变量是不行的,static本来可以,但上面说了这种类型的变量 不安全,所以这时就可以用ViewState。ViewState是将数据存入到页面隐藏控件里,不再占用服务器资源,因此, 我们可以将一 些需要服务器"记住"的变量和对象保存到viewstate里面。viewstate并不能存储所有的.net 类型数据,它仅仅支持String、Integer、Boolean、Array、ArrayList、Hashtable 以及自 定义的一些类型。
ViewState 常用于保存单个用户的状态信息,生存期等于页面的生存期。viewstate是 在本页面之内各函数间进行传值的 , 至于为什么要使用这种方法是因为在一个事件发生之 后 , 页面可能会刷新 , 如果定义全局变量会被清零 , 所以要使用 viewstate保持数据,任何事物都有两面性, 因为ViewState变量在客户端实际上是用<input type=“hidden ” value=“ADFAIB3P234P-AFAFAF……”/>保存的一个对象,这样如果要保存的是个对象, 甚 至是个很复杂的对象(如DataTable),这样以来就会增加网络传输的负担。 使用viewstat e会增加页面html的输出量,占用更多的带宽,这一点是需要慎重考虑的。另外, 由于所有的v iewstate都是存储在一个隐藏域里面,用户可以很容易的通过查看源码来看到这个经过base6 4编码的值,然后再经过转换就可以获取你存储其中的对象和变量值。
ViewState只能在一个页面上传值(session可跨多个页面传值),ViewState只是在当 前page内有效,关了当前页,再重新打开,ViewState所保存的值也就消失了。需要在用户 访问一个页面时保持一个变量的值,并随时改变它的值,用ViewState好些。ViewState是用 来同步客户端与服务端的变量状态的?当有两个用户对同一页面进行操作时,若使用Static 出现了数据张冠李戴的严重错误时,改为ViewState后就会一切正常了。
本文转载自:http://blog.csdn.net/fengyun14/article/details/6733994