文档章节

谨慎Asp.net中static变量和viewstate的用法

剑禅觅心
 剑禅觅心
发布于 2016/08/01 21:26
字数 1440
阅读 14
收藏 0

在.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的用法很简单,如下所示:
    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中后,ViewState可不管你是普通变量还是对象,统统按Object来对待。所以当我们取出存放在ViewState中的东西时,一定要转换成相应的类型,否则就会报错。而这一操作不用在用ViewState保存变量时进行,系统会自动转换。(注意ViewState括号中的字符串只是为了标识不同变量的索引,用不着非要和变量同名)所以上面计数器的代码应该这样写才好:
       ...
       ViewState["times"]=0;
       ...
       private void Button1_Click(object sender,EventArgs e)
       {
           int times=(int)ViewState["times"];
           times++;
           ViewState["times"]=times;
           Label1.Text=times.ToString();
        }
    一般情况向下,将要保存到ViewState中的对象(或变量)用属性的形式来实现会更方便。如对于上述的计数器times,可以这样处理:
    ...
    private int times
    {
        get
         {
            return (int)ViewState["times"];
         }
        set
        {
            ViewState["times"]=value;
        }
    }
    ...
    private void Button1_Click(object sender,EventArgs e)
     {
        times++;
        Label1.Text=times.ToString();
     }
    ...
    在这里times将当作私有属性来操作,是不是非常方便?
    那是不是说static型变量就没用了哪?当然不是!在C#中用static声明的类不用实例化直接使用。正是由于所有用户共享服务器端的同一个static变量,所以可以用static型对象来存取一些公用的处理模块,比如类型转换、变量验证等工作。所以要根据具体情况而定。
    还有一点需要注意:如果在页面中多个过程要共享一个对象或变量,我们在页面类的开始部分定义一个页面级的全局变量是不行的,static本来可以,但上面说了这种类型的变量不安全,所以这时就可以用ViewState。
    好了,这下我们可以放心的暂存某些变量或对象了。

本文转载自:http://blog.csdn.net/amohan/article/details/12646699

剑禅觅心
粉丝 7
博文 224
码字总数 0
作品 0
深圳
高级程序员
私信 提问
ASP.NET管理状态的十种途径

HTTP协议是无状态的,ASP.NET提供了丰富的手段在页面之间管理状态。本文列举ASP.NET管理状态的十种途径。 ASP.NET中,从System.Web.UI.Page继承的类里有以下十种管理页面状态的途径: 1. App...

晨曦之光
2012/03/09
47
0
别总以为asp.net mvc比asp.net web form好--web form的页面也可以体积小巧

最近才看到网上有一种对asp.net web form的误解。也有很多讨论,弄得微软ScottGu也来澄清。asp.net mvc和web form是并行存在的两种开发模式。许多人对web form的诟病很多,其中最主要的就是说...

mikelij
2012/05/13
0
0
ASP.NET保持用户状态的九种选择

2003-06-10 ■陶刚编译 ■yesky 摘要:ASP.NET为保持用户请求之间的数据提供了多种不同的途径。你可以使用Application对象、cookie、hidden fields、Sessions或Cache对象,以及它们的大量的方...

晨曦之光
2012/03/09
270
0
ASP.NET ViewState 初探

Susan Warren Microsoft Corporation 与刚接触 ASP.NET 页面的开发人员交谈时,他们通常向我提出的第一个问题就是:“那个 ViewState 到底是什么?”他们的语气中流露出的那种感觉,就象我来...

晨曦之光
2012/03/09
149
0
在ASP.NET下实现数字和字符相混合的验证码

作者:kwklover(原作) 出处:CSDN 在ASP.NET下实现数字和字符相混合的验证码 经常在论坛里看到有问怎么实现验证码的帖子,其实关于验证码的文章在CSDN,DEV-CLUB等网站上都有很多,但是很多文...

晨曦之光
2012/03/09
64
0

没有更多内容

加载失败,请刷新页面

加载更多

华为手机翻译功能怎么使用?这三种方法请务必收藏

华为手机翻译功能怎么使用?在我们的生活中会经常遇到翻译问题,许多外语不好的朋友该怎么办呢?华为手机已经为我们解决了这个问题,今天小编就教大家学会使用华为手机中的三种翻译技巧,需要...

翻译小天才
25分钟前
4
0
企业服务软件开发中需要注意的三个问题

在开发企业服务软件时,我们需要分为:业务需求、用户需求、产品需求,三大需求层次,三个层次互相关联,企业服务软件开发首先要服务业务,需要满足业务的需求,再关注用户体验,也就是用户需...

积木创意科技
28分钟前
4
0
C++容器底层数据结构

内置数组: int arr[10][10];memset(arr,0,10*10*sizeof(int)); //初始化int tmp[10][10];memcpy(arr, tmp, 10 * 10 * sizeof(int));//拷贝 void *memcpy(void *destin, void *source,......

SibylY
28分钟前
3
0
Dubbo-自适应拓展机制

背景 在 Dubbo 中,很多拓展都是通过 SPI 机制进行加载的,比如 Protocol、Cluster、LoadBalance 等,这些都是Dubbo的基础组件。这些基础组件的拓展不是在系统框架启动阶段被加载,而是拓展方...

rock-man
57分钟前
7
0
Kali安装fcitx输入法(五笔)

安装fcitx > sudo apt-get install fcitx-rime fcitx-config-gtk3 重启 > sudo reboot fcitx配置 效果就是这样 配置输入法切换 系统设置...

yeahlife
59分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部