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

来源:互联网 发布:ubuntu mediawiki 编辑:程序博客网 时间:2024/05/01 01:48
 
【原创】ASP.NET会话(Session)保存模式
作者寒羽枫(cityhunter172)
 
大家好,已有四个多月没写东东啦。今日抽空就说一下 Session .Net v1.0/v1.1 中的存储模式。大家可在 MSDN 2003 中搜索一下<sessionState>即可看到关于 Web.config 中的<sessionState>节点元素的描述,共有OffInProcStateServerSQLServer四种模式。OffInProc 分别指“不启用”、“进程内保存(默认值)”,此两种模式没啥讲的,所谓 InProc 就是把 Session 保存在aspnet_wp.exe (Windows 2000 解析 ASP.NET页面所用的进程) w3wp.exe (Win2003 的进程) 中,一旦进程被中止或被重置,Session 将丢失。
一、        引发 Session 丢失的几种原因
动过手写代码的人都知道,Session 丢失是比较常见的事。以下是本人这几年所遇到的,能够引发 Session 丢失的原因,不敢说是百分百,丢失概率还是特别高的。错…,简直可以说是“相…当…”高哇 ^_^"
1、    存放 Session 的电脑重启(废话,若这样都不丢,你神仙啊)
2、    模式:aspnet_wp.exew3wp.exe 在“任务管理器”中或其它情况下导致其进程被终止运行。InProc
3、    模式:修改 .cs 文件后,编译了两次(只编译一次,有时不会丢失)InProc
4、    模式:修改了Web.configInProc
5、    模式,Windows 2003 环境:应用程序池回收、停止后重启InProc
6、    模式:服务器上 bin 目录里的 .dll 文件被更新InProc
以上列举的都是 InProc 模式下,容易引发解析 ASP.NET 应用程序重置的原因。是不是觉得很窝火?之前我也有这种感觉,慢慢就习惯啦,再后来就干脆不用这种模式了。于是乎,就有了使用下列两种模式的尝试,现写出来与大家一起分享。
二、        使用 StateServer 保存 Session
StateServer模式的实质是,把Session 存放在一个单独的进程里,此进程独立于aspnet_wp.exew3wp.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"/>
 
将其改为以下内容
<sessionStatemode="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 脚本“execsp_adduser'SessionStateUser', 'SessionUser' ,'db_owner' ”→确定点击标签“调度”新建输入“名称”(此例为Start01)→选择类型“SQL Server 代理启动时自动启动”确定最后点击“确定”新增完毕
 
 
 
 
C)、也可运行以下脚本一次性搞定以上 AB 两个步骤
/******脚本开始******/
      --新建数据库帐号 SessionStateUser ,默认登录 ASPState
EXECsp_addlogin 'SessionStateUser', '123456', 'ASPState'
 
useASPState        --切换 DataBase
 
      -- SessionStateUser 授予 db_owner 的权限
exec sp_adduser 'SessionStateUser','SessionUser','db_owner'
 
usemaster            --切换 DataBase
 
BEGIN TRANSACTION  
      /******声明变量******/        
    DECLARE@JobIDBINARY(16) 
    DECLARE@ReturnCodeINT   
    SELECT@ReturnCode= 0    
 
    -- 若没有,则添加作业的分类
    IF(SELECTCOUNT(*)FROMmsdb.dbo.syscategories WHEREname=N'[Uncategorized (Local)]') < 1
        EXECUTEmsdb.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,
            @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<>0OR@ReturnCode<>0)GOTOQuitWithRollback --出错则回滚
   
    -- 新建步骤
    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<>0OR@ReturnCode <>0)GOTOQuitWithRollback
   
    -- 新建调度
    EXECUTE @ReturnCode= msdb.dbo.sp_add_jobschedule
            @job_id =@JobID,
            @name= N'Start01',  --调度名称
            @enabled=1,
            @freq_type= 64              --64表示 SQLServerAgent 服务启动时运行
 
    IF(@@ERROR <>0OR@ReturnCode <> 0)GOTOQuitWithRollback
   
    -- 将新建的作业添加到本地数据库
    EXECUTE@ReturnCode=msdb.dbo.sp_add_jobserver@job_id =@JobID,@server_name=N'(local)'
    IF(@@ERROR<>0OR @ReturnCode<>0)GOTOQuitWithRollback
   
    COMMITTRANSACTION         
    GOTO   EndSave             
QuitWithRollback:
    IF(@@TRANCOUNT>0)ROLLBACKTRANSACTION
EndSave:
/******脚本结束******/
 
4、    设置Web.config内容
打开 Web.config 找到 <sessionState> 节点内容修改为以下内容即可:
<sessionStatemode="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)、若sqlConnectionStringdata source=127.0.0.1;Trusted_Connection=yes”,则使用本地计算机ASPNETWindows 2000 系统帐户)或Network ServiceWindows 2003 系统帐户)的身份登录数据库。要是数据库不允许上述用户登录,则报错;同样,即使上述帐户能成功登录,也要分配其tempdb的权限,理由是 Session 是保存在tempdb中的,若没有该DataBase的存取权限是行不滴。见下图:
 
 
寒羽枫(cityhunter172
2006-05-14 00:01 完稿 
 
 
原创粉丝点击