ASP.NET会话(Session)保存模式

 

【原创】 ASP.NET 会话( Session )保存模式

作者 寒羽枫 (cityhunter172)

 

大家好,已有四个多月没写东东啦。今日抽空就说一下 Session .Net v1.0/v1.1 中的存储模式。大家可在 MSDN 2003 中搜索一下 < sessionState > 即可看到关于 Web.config 中的 < sessionState > 节点元素的描述,共有 Off InProc StateServer SQLServer 四种模式。 Off InProc 分别指“不启用”、“进程内保存(默认值)”,此两种模式没啥讲的,所谓 InProc 就是把 Session 保存在 aspnet_wp.exe (Windows 2000 解析 ASP.NET 页面所用的进程 ) w3wp.exe (Win2003 的进程 ) 中,一旦进程被中止或被重置, Session 将丢失。

一、        引发 Session 丢失的几种原因

动过手写代码的人都知道, Session 丢失是比较常见的事。以下是本人这几年所遇到的,能够引发 Session 丢失的原因,不敢说是百分百,丢失概率还是特别高的。错…,简直可以说是“相…当…”高哇 ^_^"

1、     存放 Session 的电脑重启(废话,若这样都不丢,你神仙啊)

2、     InProc 模式: aspnet_wp.exe w3wp.exe 在“任务管理器”中或其它情况下导致其进程被终止运行。

3、     InProc 模式:修改 .cs 文件后,编译了两次(只编译一次,有时不会丢失)

4、     InProc 模式:修改了 Web.config

5、     InProc 模式, Windows 2003 环境:应用程序池回收、停止后重启

6、     InProc 模式:服务器上 bin 目录里的 .dll 文件被更新

以上列举的都是 InProc 模式下,容易引发解析 ASP.NET 应用程序重置的原因。是不是觉得很窝火?之前我也有这种感觉,慢慢就习惯啦,再后来就干脆不用这种模式了。于是乎,就有了使用下列两种模式的尝试,现写出来与大家一起分享。

二、        使用 StateServer 保存 Session

StateServer 模式的实质是,把 Session 存放在一个单独的进程里,此进程独立于 aspnet_wp.exe w3wp.exe 。启用此服务后,在“任务管理器”中可以看到一个名为 aspnet_state.exe 的进程,下面开始说明一下设置的具体步骤:

 

1、     修改注册表(关键步骤,如下图)

运行 regedit 打开注册表 找到 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/aspnet_state/Parameters 节点 AllowRemoteConnection 的键值设置成“ 1 ”( 1 为允许, 0 代表禁止)→ 设置 Port ( 端口号 )

注意事项:

       a) 、若 ASP.NET State Service 正在运行,修改注册表内容后,则需要重新启动该服务

b) 、注意端口号的键值是以十六进制储存的,可以使用十进制进行修改, 42424 是默认的端口

c) AllowRemoteConnection 的键值设置成“ 1 后,意味着允许远程电脑的连接,也就是说只要知道你的服务端口,就可享用你的 ASP.NET State Service ,即把 Session 存放在你的电脑进程内,因此请大家慎用;键值为“ 0 时,仅有 stateConnectionString 为“ tcpip=localhost: 42424 与“ tcpip=127.0.0.1:42424 的情况,方可使用 ASP.NET State Service

 

 

2、     开启 ASP.NET State Service (如下图)

右键点击“我的电脑”→ 管理 服务与应用程序 服务 双击“ ASP.NET State Service 启动(可设为“自动”)

说明:只要安装了 .Net Framework v1.0/v1.1 ,都拥有此服务。

 

 

3、     更改 Web.config

打开 Web.config 找到 < sessionState > 节点内容

< sessionState

            mode ="InProc"

            stateConnectionString ="tcpip=127.0.0.1:42424"

            sqlConnectionString ="data source=127.0.0.1;Trusted_Connection=yes"

            cookieless ="false"

            timeout ="20" />

 

将其改为以下内容

< sessionState mode ="StateServer"   stateConnectionString ="tcpip=192.168.0.2:42424" timeout ="20" />

注意事项:

       a) 、设成 StateServer 后,必须要有对应的 stateConnectionString

       b) 、注意 IP 地址(可以是远程计算机 IP 、计算机名称、域名)与端口号,端口号需与 ASP.NET State Service 的服务端口一致

 

三、        Session 放入 SQLServer 保存

SQLServer 模式就是,把 Session 存放在 SQL Server 数据库里(注意不是 Oracle ,动动脚趾都能猜到原因啦),下面开始说明一下设置的具体步骤:

 

1、     启动相关的数据库服务(如图)

运行 SQL Server 服务管理器 启动 SQL Server (最好设为开机自动运行) 启动 SQL Server Agent 服务(最好设为开机自动运行)

注意事项:

       a) 、注意启动顺序,也可通过下列方式设置: 右键点击“我的电脑”→ 管理 服务与应用程序 服务 找到“ MSSQLSERVER ”与“ SQLSERVERAGENT 启动并设置启动类型为“自动”

b) SQL Server Agent 在此处的作用是清除数据库中已过期的 Session

 

 

2、     建立存放 Session DataBase

运行“ SQL 查询分析器”→ 使用“ sa ”或是拥有“ master ”的 db_owner 权限的用户登录数据库 打开查询文件 C:/WINNT/Microsoft.NET/Framework/v1.1.4322/InstallSqlState.sql (存放在 Windows 系统目录的 .Net 安装目录下可找到) 直接运行该 sql 脚本 刷新数据库即可看到名为 ASPState DataBase

 

 

 

3、     建立连接数据库 ASPState 的用户,并为此用户授权(此步骤可跳过)

进行此步的原因是:一是不想在 Web.config 中出现 sa 的密码;二是 tempdb 在数据库启动后仅保留 sa 一个帐号的使用权限,其余帐号的权限统统被清除,但保存 Session 又需要用到此 DataBase

 

A) 、运行 SQL Server 的企业管理器 展开数据库的安全性 右击“登录” 新建“登录” 输入“名称” 选择 SQL Server 身份验证” 输入“密码” 指定“数据库” 点击“数据库访问” 勾选 ASPState 选中“ db_owner ”角色 点击“确定” 再一次输入“密码” 点击“确定” 后即可建立 ASPState 的用户(此处建立名为“ SessionStateUser ”,密码为“ 123456 的测试用户)

 

      

 

 

B) 、运行 SQL Server 的企业管理器 展开“管理” 展开“ SQL Server 代理” 右击“作业” 点击“新建作业” 输入 “名称”(此例为 GrantSessionUser 点击标签 “步骤” 新建 输入 “步骤名”(此例为 Grant01 选择数据库“ tempdb 编写 SQL 脚本“ exec sp_adduser 'SessionStateUser' , 'SessionUser' , 'db_owner' ”→ 确定 点击标签 “调度” 新建 输入 “名称”(此例为 Start01 )→ 选择类型“ SQL Server 代理启动时自动启动” 确定 最后点击“确定”新增完毕

 

 

 

 

C )、也可运行以下脚本一次性搞定以上 A B 两个步骤

/****** 脚本开始 ******/

      -- 新建数据库帐号 SessionStateUser ,默认登录 ASPState

EXEC sp_addlogin 'SessionStateUser' , '123456' , 'ASPState'

 

use ASPState         -- 切换 DataBase

 

      -- SessionStateUser 授予 db_owner 的权限

exec sp_adduser 'SessionStateUser' , 'SessionUser' , 'db_owner'

 

use master             -- 切换 DataBase

 

BEGIN TRANSACTION   

      /****** 声明变量 ******/         

    DECLARE @JobID BINARY ( 16 )  

    DECLARE @ReturnCode INT    

    SELECT @ReturnCode = 0    

 

    -- 若没有,则添加作业的分类

    IF ( SELECT COUNT (*) FROM msdb.dbo. syscategories WHERE name = N '[Uncategorized (Local)]' ) < 1

        EXECUTE msdb.dbo.sp_add_category @name = N '[Uncategorized (Local)]'

 

    -- 新建作业

    EXECUTE @ReturnCode = msdb.dbo.sp_add_job     -- 调用存储过程 sp_add_job

            @job_id = @JobID OUTPUT ,           -- 将返回的 JobID ,赋值给变量

            @job_name = N 'GrantSessionUser' ,   -- 作业名称

            @owner_login_name = NULL,           -- 默认为当前用户所有

            @description = null,%nl=Fspan>

            @category_name = N '[Uncategorized (Local)]' ,        -- 作业分类归属

            @enabled = 1 ,                    -- 是否启用

            @notify_level_email = 0 ,

            @notify_level_page = 0 ,

            @notify_level_netsend = 0 ,

            @notify_level_eventlog = 0 ,

            @delete_level = 0

 

    IF ( @@ERROR <> 0 OR @ReturnCode <> 0 ) GOTO QuitWithRollback -- 出错则回滚

   

     -- 新建步骤

    EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep -- 调用存储过程 sp_add_jobstep

            @job_id = @JobID ,                    -- 传入刚刚新建的 JobID

            @step_id = 1 ,

            @step_name = N 'Grant01' ,         -- 步骤名称

            @command = N 'exec sp_adduser ''SessionStateUser'', ''SessionUser'' ,''db_owner''',

             -- 需要执行的 SQL 脚本(注意用两个连续的单引号表示 SQL 中的单引号)

 

            @database_name = N 'tempdb' , -- 执行上述 SQL 所用的 DataBase

            @server = N '' ,

            @database_user_name = N '' ,

             @subsystem = N 'TSQL' ,     -- 执行类型为“ Transact-SQL 脚本”

            @cmdexec_success_code = 0 ,

            @flags = 0 ,

            @retry_attempts = 0 ,

            @retry_interval = 1 ,

            @output_file_name = N '' ,

            @on_success_step_id = 0 ,

             @on_success_action = 1 ,

            @on_fail_step_id = 0 ,

            @on_fail_action = 2

 

    IF ( @@ERROR <> 0 OR @ReturnCode <> 0 ) GOTO QuitWithRollback

   

    -- 新建调度

    EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule

             @job_id = @JobID ,

            @name = N 'Start01' ,   -- 调度名称

            @enabled = 1 ,

            @freq_type = 64                -- 64 表示 SQLServerAgent 服务启动时运行

 

    IF ( @@ERROR <> 0 OR @ReturnCode <> 0 ) GOTO QuitWithRollback

   

    -- 将新建的作业添加到本地数据库

    EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID , @server_name = N '(local)'

    IF ( @@ERROR <> 0 OR @ReturnCode <> 0 ) GOTO QuitWithRollback

   

    COMMIT TRANSACTION          

    GOTO    EndSave              

QuitWithRollback:

    IF ( @@TRANCOUNT > 0 ) ROLLBACK TRANSACTION

EndSave :

/****** 脚本结束 ******/

 

4、     设置 Web.config 内容

打开 Web.config 找到 < sessionState > 节点内容 修改为以下内容即可:

< sessionState mode ="SQLServer"   sqlConnectionString ="data source=192.168.0.2; user id= SessionStateUser; password=123456" timeout ="20" />

注意事项:

       a) sqlConnectionString 中不能出现 initial catalog 选项

b) SQL Server Agent 在此处的作用是清除数据库中已过期的 Session

c )、你若跳过了第三步,则 user id 需要用 sa 进行登录

d )、若 sqlConnectionString data source=127.0.0.1;Trusted_Connection=yes ”,则使用本地计算机 ASPNET Windows 2000 系统帐户)或 Network Service Windows 2003 系统帐户)的身份登录数据库。要是数据库不允许上述用户登录,则报错;同样,即使上述帐户能成功登录,也要分配其 tempdb 的权限,理由是 Session 是保存在 tempdb 中的,若没有该 DataBase 的存取权限是行不滴。见下图:

 

 

寒羽枫( cityhunter172

2006-05-14 00:01 完稿  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值