会话管理
学习于:http://msdn.microsoft.com/zh-cn/magazine/cc300437(en-us).aspx#S6
ASP.NET提供了许多种方法来在http请求过程中保持数据【保持会话状态】:
存在ASP中的状态容器 1.Application 2.Cookies 3.Form Post / Hidden Form Field 4.QueryString 5.Session
ASP.NET增添了以下几个状态容器 1.Cache 2.Context 3.ViewState 4.Web.config and Machine.config Files
面对这么多的不同容器,在一个特定的情形下选用哪个有时会显得困惑/混乱,为了弄清这个问题,有3个方面我们应该要考虑到:
1.谁需要访问这些数据
2.这些数据打算保持多久
3.数据有多大
从这3个方面考虑的话,我们就可以决定出选用哪个最合适的容器来保持数据
方法 对谁可见 保持多久 数据大小 保存在哪里 Application 整个应用程序/所有用户 整个应用程序的生命周期 任意大小 服务器端 cookie 单个用户 根据用户的需要设定(可以很短, 小量,简单的数据 客户端 也可以是几个月,甚至是几年) Hidden Form Field 单个用户 所在的WEB页面的生命周期 小量,简单的数据 客户端 QueryString 单个用户 直到下次页面跳转请求 小量,简单的数据 客户端 Session 单个用户 用户活动时间加上一段延迟时间 小量,简单的数据 服务器端 (一般为20分钟) Cache 整个应用程序/所有用户 根据用户的需要设定 任意大小 服务器端 Context 单个用户 只在本次请求中 可以保存大数据块,但是在 每个请求中都有各自的Context, 服务器端 所以保存的数据都不大 ViewState 单个用户 所在的WEB页面的生命周期 可以保存大数据块 客户端 Config file 整个应用程序/所有用户 直到Config file被更新 可以保存大量数据 服务器端
Application
是字典类型,保存的数据对所有用户都可见,使用Application对象时有点需要注意,对Application的写入操作必须在Application_OnStart事件中(该事件在global.asax文件中定义)或者在Application.Lock和Application.UnLock同步锁中完成。同步锁可以保证写入的正确性,但也带来了性能问题,如:并发操作
cookie
由于浏览器在每个HTTP请求中都会带上cookie,考虑到带宽资源以及性能问题,cookie适合保存少量且简单的数据,且不应该是敏感信息
Hidden Form Field
只有在Form以Post方式提交的时候才可以保持隐藏域中的值,随着form post请求在网络上来回传送。通过HttpRequest对象中的Form容器来访问:Request.Form["username"]
QueryString
是通过在URL上面附加参数值,对用户是可见的,所以不宜传敏感数据
Session
1.Session有几种模式:
a.mode="Inproc"
数据存储在WEB服务器上的本地内存里
b.mode="StateServer" 将会话数据存储到单独的内存缓冲区中,再由单独一台机器上运行的Windows服务来控制这个缓冲区。它由Web.config文件中的stateConnectionString属性来配置,该属性指定了服务所在的服务器,以及要监听的端口:
<sessionState mode="StateServer" stateConnectionString="tcpip=myserver:42424" cookieless="false" timeout="20" />
c.mode="SqlServer" 将数据存储到由sqlConnectionString属性指定的SQL Server中
2.Session默认情况下是用cookie来保存会话Id的,这个cookie的默认的名字是ASP.NET_SessionId,也可以使用不基于cookie的session,只需要在web.config做相应配置即可:
<sessionState mode="Inproc" cookieless="true" timeout="20" /> //此时存会话Id会作为URL的一部分来进行传递----http://localhost:1974/(S(43vo1sctvr2lfodnqycdcfns))/Querystring.aspx //43vo1sctvr2lfodnqycdcfns就是本次会话Id
Cache
页面通常需要从数据源获取数据,并经过一些计算逻辑,最终变成一些HTML代码发给客户端显示。而这些计算过程显然也是有成本的。 这些处理成本最直接可表现为影响服务器的响应速度,尤其是当数据的处理过程变得复杂以及访问量变大时,会变得比较明显。 另一方面,有些数据并非时刻在发生变化,如果我们可以将一些变化不频繁的数据的最终计算结果(包括页面输出)缓存起来, 就可以非常明显地提升程序的性能,缓存的最常见且最重要的用途就体现在这个方面。
ASP.NET Cache有个很强大的功能,那就是缓存依赖。一个缓存项可以依赖于另一个缓存项
ASP.NET Cache与一些static变量所实现的缓存效果并不相同,它的缓存项是可以根据一些特定的条件失效的,那些失效的缓存将会从内存中移除。 虽然,某些移除条件并不是由我们的代码直接解发的,但ASP.NET还是提供一种方法让我们可以在缓存项在移除时,能通知我们的代码,这个方法是通过CacheItemRemovedCallback类型委托来实现的
Context
每个请求中都有各自的Context,不能在各个请求中共享数据。一般用来保持小块数据,数据其实是保存在Context对象的Item容器中
HttpContext.Current.Items["myKey"] = "Hello world";
ViewState
可以保存大量的数据,但是在使用中必须要考虑到数据量的大小,因为ViewState中的数据在request和response中来回传递,如果数据量过大,响应速度就会受到很大的影响。
webform中的服务器控件在页面之间postback数据时都是用ViewState来保持数据的。可能在使用时我们都没有注意到这点,所以在使用时一定要注意每个ViewState会带上多少数据,因为它会严重影响程序的性能。
在<%@ Page language="c#" Codebehind="Form1.aspx.cs" AutoEventWireup="false" Inherits="ASPAuthors.MSDN.StateManagement.Form1" trace="true" %>中将trace打开,然后在页面上就可以看到整个trace信息,在Control Tree中可以看到每个控件中的ViewState所包含的字节数,
如果某个控件在postbacks中不需要保持数据,那就把该控件中的EnableViewState属性设置成false.
如果想看整个页面所有ViewState加起来的大小,可以通过view source来打开html页面,然后检查隐藏域“__VIEWSTATE”中所包含的数据信息,这些数据是通过Base64-encoded处理过的
可以在@Page指定中通过添加EnableViewState="false"来关闭当前页面中的所有ViewState
简单使用:
ViewState["myKey"] = “myValue”;
Response.Write(ViewState["myKey"]);