您的位置:首页 > 编程语言 > ASP

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

2009-11-25 19:17 531 查看
【原创】

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

完稿
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: