ASP.NET-Session与复杂数据类型

原文连接:http://www.cnblogs.com/fish-li/archive/2013/05/28/3104750.htmlhtml

Session与复杂数据类型程序员

Session有三种工做模式,拿ASPX页面来讲,EnableSessionState指令有三个可选值:true, false, ReadOnlyweb

第一个

EnableSessionState="false",这个容易理解:不使用Session。sql

第二个

EnableSessionState="ReadOnly",从字面上来讲,就是Session是只读的。
只读的控件不容许用户修改,然而Session的只读模式是说:你能够改,但我不保存你的修改。 这样理解没有问题吧。数据库

第三个

EnableSessionState="true",表示Session支持可读可写。
当你更新了Session的内容以后,当前会话的全部Session数据将会被从新保存。安全

进程内Session容易丢失,且不支持多台Web服务器共享数据,所以选择这种保存方法的人很少, 大多数人会选择状态服务或者SQL Server来保存,那么这里就有一个问题须要关注了: 当Session模式是EnableSessionState="true"时,若是你访问了一个复杂对象(不是系统值类型也不是字符串), 无论你有没有修改它,Session的保存操做都会执行。 对于进程外Session,保存操做意味着须要执行序列化,还能够会有网络传输的开销,它们会影响性能。服务器

若是上面的描述不容易理解的话,请看下面的示例代码:cookie

string sessionValue = Session["s2"] as string;
if( sessionValue == null ) {
    Session["s2"] = "Fish Li";
    sessionValue = Session["s2"] as string;
}

当这个页面首次运行时,Session被修改了,所以会有保存的操做发生。可是后面的访问就不会有保存的动做。网络

再看另外一段代码:session

// TestData是一个自定义类型。
TestData sessionValue = Session["s1"] as TestData;
if( sessionValue == null ) {
    Session["s1"] = new TestData { IntValue = 5, StrValue = "Fish Li" };
    sessionValue = Session["s1"] as TestData;
}

此时每次执行这段代码时,都会有保存操做发生(只要是EnableSessionState="true")。

我再重申一遍:这个问题只有当EnableSessionState="true",且访问复杂对象(不是系统值类型也不是字符串)才会发生。 对于进程内Session来讲,这个问题的影响不大,可是对于进程外Session来讲,会对性能产生一些影响, 到底有多大的影响,要根据Session的数据量以及用户的并发度来决定。

列出这个问题只是想告诉你们:若是你确实须要使用Session,请尽可能在Session中保存【不可变】的简单数据, 尤为是不要保持Session的默认设置(EnableSessionState="true")。

检验这个问题的方法是:实现一个自定义的SessionStateStoreProviderBase派生类,而后调试观察。 SessionStateItemCollection的二个索引器也会给你一个答案。

引伸一下服务器端的Session管理,web form作例子

web form网页是基于HTTP的,它们没有状态, 这意味着它们不知道全部的请求是否来自 同一台客户端计算机,网页是受到了破坏,以及是否获得了刷新,这样就可能形成信息的 丢失。因而,状态管理就成了开发网络应用程序的一个实实在在的问题。在ASP中可以经过Cookie 、查询字符串、 应用程序、会话(Session) 等轻易解决这些问题。 如今在ASP.NET环境中,咱们依然可使用这些功能,而且功能更增强大。

状态管理分为服务端和客户端两种状况, 这里只是介绍 服务端状态管理:

与Application对象不一样的是, ASP.NET 的Session对象能够在IIS服务器或者工做进程从新启动时 恢复启动前的状态而不丢失其中的数据。这是由于存储在Session中的因此信息都缺省的存储在 一个做为Windows服务运行的状态服务器进程中。状态能够被序列化并以二进制形式保存在内存中。 程序员能够悬着使用Microsoft Sql server数据库来存储数据。

状态服务器服务和状态信息能够和web应用程序一块儿存在于同一台服务器上,也能够保存到外部的 状态服务器上。 为了指定如何存储信息,程序员能够在web.config文件中编写适当的配置。

ASP.NET会话状态模块在Web.config文件中<System.web>标记下的 标记的mode属性来决定 该属性的四种可能的值:** Off、 Inproc StateServer 和SQLserver**。

 1 Inproc是缺省的设置

它容许“无Cookie”的会话,以及在服务器以外存储 会话数据。ASP.NET会话状态模块在Web.config文件中像下面这样配置:

<sessionState mode="InProc" cookieless="false" timeout="20" />

在这个例子中,mode属性设为InProc(默认值),代表会话状态要由ASP.NET存储到内存中,并且 不用Cookie来传递会话ID。相反,会话ID要直接插入一个网页URL的查询字符串中。例如,采用 InProc模式并创建一个会话以后,调用一个假想的ASP.NET网页时,须要采用下面这样的URL:

http://my.website.com/(12mfju55vgblubjlwsi4dgjq)/education.aspx

圆括号中长长的字母、数字字符串12mfju55vgblubjlwsi4dgjq就是会话ID。ASP.NET引擎从查询字符中提取会话ID,并将用户 请求与特定会话联系起来。采起这种方式,无论Cookie仍是隐藏表单字段都用不着了。 因此,即便网页中没有使用表单,也能加入会话。

可是这种方法,应用程序的状态将依赖于 ASP.NET进程, 当IIS进程崩溃或者正常重启时,保存在 进程中的状态将丢失。

 2 mode属性设为Off

和从前的ASP同样,ASP.NET的会话状态管理是要产生开销的。因此,假如某个网页不须要访问 Session对象,开发者应将那个页的Page预编译指令的EnableSessionState属性设为False。 要为整个网站禁用会话状态,可在Web.config文件中将sessionState元素的mode属性设为Off。

为了克服inproc 模式的缺点, ASP.NET 提供了两种进程外保存会话状态的方法。

 3 StateServer会话管理

将mode属性设为StateServer,也就是将会话数据存储到单独的内存缓冲区中,再由单独一台机器上运行

的Windows服务来控制这个缓冲区。状态服务全称是“ASP.NET State Service ”(aspnet_state.exe),

它由Web.config文件中的stateConnectionString属性来配置。该属性指定了服务所在的服务器,以及要监视的端口: 在这个例子中,状态服务在一台名为myserver的机器的42424端口(默认端口)运行。要在服务器上改变端口,可编辑HKLM\SYSTEM\CurrentControlSet\Services\aspnet_state注册表项中的Port值。
显然,使用状态服务的优势在于进程隔离,并可在Web form中共享。 使用这种模式,会话状态的存储将不依赖于iis进程的失败或者重启,然而,一旦状态服务停止,全部会话数据都会丢失。换言之,状态服务不像SQL Server那样能持久存储数据;它只是将数据存储在内存中。

4 用SQL Server进行会话管理

ASP.NET还容许将会话数据存储到一个数据库服务器中,方法是将mode属性变成SqlServer。 在这种状况下,ASP.NET尝试将会话数据存储到由sqlConnectionString属性(其中包含数据源以及登陆服

务器所需的安全凭证)指定的SQL Server中。 为了用恰当的数据库对象来配置SQL erver,管理员还须要建立ASPState数据库, 方法是运行WinDir\Microsoft.Net\Framework\Version文件夹中的InstallState.sql脚本(WinDir是服务

器的Windows文件夹,而Version是你使用的.NET框架版本的安装文件夹)这个脚本文件我没有找到,等作这个功能的时候再处理这个问题。 要配置SQL服务器,能够在命令行中运行SQL Server 提供的命令行工具osql.exe

osql -S [ server name] -U [user] -P [password] <InstallSqlState.sql 例如 osql -S (local)\NetSDK -U sa -P "" -i InstallSqlState.sql

在这里用户名必须是SQL服务器上的sa账号,或者具备同等权限的其余账号。有兴趣的读者能够打开 这个脚本文件来了解ASP.NET是如何和SQL Server配合实现状态管理的。
卸载这些表和存储过程,可使用UninstallSqlState.sql脚本,使用方法与上面相似。

作好必要的数据库准备工做后,将web.config 文件中的sessionstate 元素的mode改成"sqlserver" ,而且指定SQL链接字符串。具体以下:

mode="sqlserver" sqlConnectionString="data source=127.0.0.1; userid=sa; password="

配置好SQL Server后,应用程序代码运行时就和InProc模式没有什么区别。但要注意的是,因为数据不存

储在本地内存,因此存储会话状态的对象须要进行序列化和反序列化,以便经过网络传给数据库服务器,

以及从数据库服务器传回。这固然会影响性能。经过在数据库中存储会话状态,可分别针对扩展性及可靠

性来有效地平衡性能。另外,能够利用SQL Server的集群,使状态存储不依赖于单个的SQL Server, 这样就能够为应用程序提供极大限度的可靠性。

相关文章
相关标签/搜索