ASP . NET提供了4种状态类型,分别应用于不同的目的。
- 视图状态:用于保存本窗体页的状态
- 应用程序状态:用于保存整个应用程序的状态,状态存储在服务器端。
- 会话状态:用于保存单一用户的状态,状态存储在服务器端。
- Cookie状态:用于保存单一用户的状态,状态存储在浏览器端。
一. 视图状态
简单的说,视图状态就是本窗体的状态。保持视图状态就是在反复访问本窗体页的情况下,能够保持状态的连续性。
视图状态只能在本网页与服务器的往返中保持,而不能在不同网页之间传递,这是和其他状态所不同的地方。在默认情况下几乎所有服务器控件都具有保持视图状态的功能。
劣势:如果控件中包括的数据量很大(例如某控件内有数百条记录)时,会网页往返需要的时间。 而且有安全的危险。
二. 应用程序状态
Application对象是HTTPApplicationState类的实例。 Application是属于全局性的对象,用于存放应用程序中多个用户共享的信息。当用户第一次访问某虚拟目录的资源时被创建,退出应用程序或关闭服务器时被撤销。
Application对象利用“键----值”对的字典方法来定义,其中“键”为字符串,代表状态的“名”,“值”可以是任何类型的数据。 例如:
Application[“message”]=”mysmg”; //给名为“message”的Application对象赋值“mysmg”
String myvar=Application[“message”] . toString() ;
// 取出名为“message”的Application的值赋给字符串 myvar
为了和ASP版本兼容,也可以使用以下语句:
Application . contents[“message”]=”mysmg” ;
String myvar=Application .contents[“message”] . toString() ;
可以利用Application的add方法向Application的集合中添加项,也可以利用Remove方法删除不需要的项。例如:
Application . add(“message” , “mysmg”) ;
Application . remove(“message”) ;
可以利用clear()或者removeAll()方法清除Application集合中的内容。例如:
Application . clear() ;
Application . removeAll() ;
由于信息共享,有可能出现多个用户同时访问application时而引发的竞争。为了防止竞争带来的影响,可以利用Application对象的两个方法lock()和Unlock() 。其中lock()用于锁定对象,不允许其他进程访问; unlock()用于解锁,以便允许其他进程访问。
例如,将Application[“counter”]用来统计访问网站的人数时可以采用以下代码:
Application . lock() ; //锁定application对象,避免多用户竞争访问
Application[“counter”]=(int)Application[“counter”]+1 ;
Application . unlock() ; //解除对application对象的锁定
应用程序状态只能在网站运行时存在。 如果WEB服务器关闭或崩溃了,应用程序状态所保留的信息也会损坏或丢失 。因此,对于那些需要永久保留的状态应当保存在数据库或其他永久性的存储器中。
三. 会话状态
会话状态(SessionState)是为单个用户保留的状态。在网站中,每一个新访问的用户都将产生自己的会话(Session)对象。这个Session对象在服务器端进行管理,只能为当前访问的用户服务。如果另一位用户也进入网站,他也将拥有自己的Session对象,两个用户的Session对象之间即使同名,也不能共享同一个Session对象。
Session对象中方法的调用
Session对象的方法可以用来保存会话状态和管理会话状态两个方面。
1. 保存会话状态
保存会话状态时可以使用以下语句:
Session[“message”]=”mysmg” ;
取出session对象时可以使用以下语句:
String myvar=session[“message”] .tostring () ;
2. 启动会话状态
应用程序状态在网站中总是可用的,而会话状态在使用前必须先启动。不过,因为配置文件(Machine . config)的默认设置是启动会话状态,因此不需要额外的步骤就能启动它。 虽然如此,还是应该知道,是Machine. config和应用程序的Web . config配置文件的设置决定了会话状态是被启动还是被禁止。
如果要想延迟到需要时再启动会话状态, 则可以在页面中编写以下指令:
<%@ page EnableSessionState =“False”%>
上述设置并不会破坏其他页面建立的会话, 而只会禁止从该页面访问Session对象的值 。
另外一种方法就是通过改变窗体页的属性来选择, 在下拉列表框中选择DOCUMENT ,然后选择enableSessionState属性,在True、False、Readonly三个选项中选择其一。
3. 管理会话
Session对象提供了Timeout属性,用来设置Session的有效时效,以分钟为单位。默认情况下有效时效是20分钟。即如果在有效时间内没有连接Web服务器,对Session的设置将自动失效。可以在网页中延长或缩短Session的有效时间,例如语句:
Session . Timeout = 60 ;
就可以将Session的有效时间延长至60分钟。
如需要终止Session的使用时,可以调用Abandon()方法。 语句如下:
Session . Abandon() ;
四. Cookie状态
和Session对象一样,cookie对象也是保存下来作为单个用户共享的状态,但是这个对象保存的位置与Session不同。Session被保存在服务器端,而cookie被保存在浏览器端。
Cookie的作用是与Session对象相结合来识别用户。每当用户开始连接站点时,系统将自动在内存中创建一个用户有关的会话状态,同时创建一个用户的ID存放在浏览器端,与当前的用户唯一地联系起来。这样,服务器保存了Session ,浏览器保存了cookie(用户的ID)。当下一次用户发出请求时,请求的用户将被要求提交用户的ID,两者对照以正确的还原原来的会话状态。这就是在无状态协议的HTTP条件下保持用户标志的方法。
可以通过Response . cookie. add() ;方法直接向浏览器写入cookie ,通过request . cookie方法读取已经设置好的cookie 。
写入cookie的方法是,先创建一个HttpCookie对象,通过这个对象来构造一个cookie 。例如:
// 创建一个HttpCookie对象
Httpcookie cookie = new httpcookie (namefield . text) ;
//设定此cookie值
Cookie1 . value = valuefield . text ;
//加入此cookie
Response . cookies . add(cookie) ;
Cookie有临时的,也有永远的。永久的cookie以文件的形式存在于计算机上,关闭IE时仍然保留在计算机上。再次访问该站点时,创建该cookie的网站可以读取。在具体的编程时候,是在写如此cookie的时候,设定cookie的生命周期,其代码如下:
Datetime dtnow = Datetime . now ;
TimeSpan tsminute = new timeSpan (0,1,0,0) ;
Cookie . Expires = dtnow+tsminute ;
Response . cookies . add(cookie1) ;
以上代码是设定新产生的cookie的生命周期为一个小时,可以通过修改TimeSpan的属性来设置cookie具体的生命期。如果不设定时间,默认时间为 20分钟。
读取指定的cookie时的语句如下:
Httpcookie cookie = request .cookies[“cookie的名称” ];
如果想将读出的cookie显示出来时,可以使用以下语句:
Response . write (cookie . value . toString()) ;
Cookie是保存在客户端的字符串,它会影响用户的行为,但又不受用户的直接管理。虽然它只是一种标志(字母数字字符串)而不是程序,不可能用它来收集客户的信息,破坏用户隐私。
ASP . NET 2.0 现在已完全解决了在不使用cookie的情况下,识别用户的方法。解决的办法很简单,只需要在应用程序的根目录下的Web . config文件中,对<SessionState>节点进行配置,其他任何程序都不需要修改。为什么一定要在应用程序的根目录下配置? 因为会话状态的设置是应用程序范围的设置。站点中的网页要么全都使用该配置,要么全都不使用。配置语句是:
<SessionState cookieless =“useUri”/>
或
<SessionState cookieless=”AutoDetect”/>
配置时,当编写到“cookieless= ”语句时,将弹出AutoDetect、useCookies、useDeviceProfile、useUri四种选择。选择AutoDetect或useUri均可在无Cookies的条件下识别用户。
简单的一个应用实例
1. 下面通过一个“用户登录及保护”的简单示例来说明会话(Session)对象的特点。
假定有一批网页只对部分用户开放。访问者需要先输入自己的姓名及密码,密码正确时才能进入被保护的页面。
(要注意:因为因特网是个开放的系统,用户完全可以绕过对密码的验证,直接通过URL访问其他网页。)
利用Session对象可以构筑一座虚拟的围墙。
页面设置:两个Label控件,两个Textbox控件,一个Button控件。 在button控件中增加对Session对象的设置,以便在其他网页中共享。 具体代码如下:
Private void Button1_click(object sender , system . EventArges e)
{
If (Textbox2 . text == “3245326”)
{
Session [“pass”] = “Right” ;
Response . Redirect (“webform2. aspx”) ;
}
Else
{
Session [“pass”] =null ;
Response . write (“密码有误!”) ;
}
}
代码中有对Session [“pass”] 对象的设置。如果密码正确 ,执行语句:
Session [“pass”] = “Right” ;
如果密码不正确,则执行语句:
Session [“pass”] = null ;
而在被保护的网页(即webform2. aspx)的Page _ load 事件中增加以下代码:
{
If (Session [“pass”]==null)
{
Response . Redirect (“webform1. aspx”) ;
}
}
代码中的webform1 . aspx代表登录页面。当网页打开时(Page _ load事件发生)先将Pass会话对象中的字符串取出,然后进行判断,若字符串为null ,则返回登录页面,要求重新输入密码。这就防止了不经过验证密码的用户进入网页的可能。