SessionState 状态

本文详细介绍了ASP.NET中的会话状态管理机制,包括Session的工作原理、如何在Web应用程序中使用Session存储用户信息,以及Session的多种存储方式,如InProc、StateServer和SQLServer模式。此外,还提供了配置示例和一些实用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当用户在 Web 应用程序中导航 ASP.NET 页时,ASP.NET 会话状态使您能够存储和检索用户的值。HTTP 是一种无状态协议。这意味着 Web 服务器会将针对页面的每个 HTTP 请求作为独立的请求进行处理。服务器不会保留以前的请求过程中所使用的变量值的任何信息。

ASP.NET 会话状态将来自限定时间范围内的同一浏览器的请求标识为一个会话,当每个用户首次与这台WWW服务器建立连接时,他就与这个服务器建立了一个Session,同时服务器会自动为其分配一个SessionID,用以标识这个用户的唯一身份。Session提供用于在该会话持续期间内保留变量值的方法。默认情况下,将为所有 ASP.NET 应用程序启用ASP.NET 会话状态.

会话变量可以是任何有效的 .NET Framework 类型, 注意:当使用 InProc 以外的会话状态模式时,会话变量类型必须为基元 .NET 类型或可序列化的类型。这是因为会话变量值存储在外部数据存储区中。

会话由一个唯一标识符标识,可使用 SessionID 属性读取此标识符。为 ASP.NET 应用程序启用会话状态时,将检查应用程序中每个页面请求是否有浏览器发送的 SessionID 值。如果未提供任何 SessionID 值,则 ASP.NET 将启动一个新会话,并将该会话的 SessionID 值随响应一起发送到浏览器。

默认情况下,SessionID 值存储在 Cookie 中。但也可以将应用程序配置为在“无 Cookie”会话的 URL 中存储 SessionID 值。只要一直使用相同的 SessionID 值来发送请求,会话就被视为活动的。如果特定会话的请求间隔超过指定的超时值(以分钟为单位),则该会话被视为已过期。使用过期的 SessionID 值发送的请求将生成一个新的会话。

安全说明:

无论是作为 Cookie 还是作为 URL 的一部分,System.Web.SessionState.HttpSessionState.SessionID 值都以明文的形式发送。恶意用户通过获取 SessionID 值并将其包含在对服务器的请求中,可以访问另一位用户的会话。如果您将敏感信息存储在会话状态中,建议使用 SSL 来加密浏览器和服务器之间包含 SessionID 值的任何通信。

默认情况下,SessionID 值存储在浏览器的不过期会话 Cookie 中。但是,通过在 Web.config 文件的 sessionState 节中将 cookieless 属性设置为 true,可以指定不应将会话标识符存储在 Cookie 中。

<configuration>

  <system.web>

    <sessionState cookieless="true"

      regenerateExpiredSessionId="true" />

  </system.web>

</configuration>

ASP.NET 通过自动在页的 URL 中插入唯一的会话 ID 来保持无 Cookie 会话状态。例如,下面的 URL 已被 ASP.NET 修改,以包含唯一的会话 ID lit3py55t21z5v55vlm25s55:

http://www.example.com/(S(lit3py55t21z5v55vlm25s55))/orderform.aspx

 

搭建Session服务器的几种方式

  将Session保存在独立的服务器中可以实现在多台Web服务器之间共享Session.虽然我们也可以自己开发Session存储系统, 但是使用ASP.NET自带的存储机制将更加便捷.

  .NET提供了5种保存Seission的方式:

  

方式名称
 存储方式
 性能
 
Off
 设置为不使用Session功能
 无
 
InProc
 设置为将Session存储在进程内,就是ASP中的存储方式,这是默认值。
 性能最高
 
StateServer
 设置为将Session存储在独立的状态服务中。通常是aspnet_state.exe进程.
 性能损失10-15%
 
SQLServer
 设置将Session存储在SQL Server中。
 性能损失10-20%
 
Customer
 自定制的存储方案
 由实现方式确定
 

  我们可以在Web.Config中配置程序使用的Session存储方式.默认情况下是InProc, 即保存在IIS进程中. 关于Off, InProc和Customer本文不做讲解. 相关文章大家都可以在网上搜索到.

  下面主要讲解 StateServer 和 SQLServer 的应用.

  四.使用 StateServer 模式搭建Session服务器

  (1)服务器端配置

  1.启动 Asp.net State service服务.(这个服务默认的状态为手动.修改为自动并启动.)

  2.修改注册表: [HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/aspnet_state/Parameters]

  设置 AllowRemoteConnection = 1 , 设置 Port = 42424 (十进制,默认即为42424)

  Port是服务的端口号

  AllowRemoteConnection 表示是否允许其他机器连接,0为仅能本机使用,1为可以供其他机器使用.

  (2)客户端设置

  在Web应用程序的Web.Config中, 我们需要修改 / 的节点.如果没有

  没有则添加(默认使用的是InProc方式)

  mode="StateServer"

  stateConnectionString="tcpip=服务器ip:42424"

  cookieless="false"

  timeout="60"/>

  上面的参数我们可以根据需要修改.

  五.使用SqlServer模式搭建Session服务器

  (1)服务器端配置

  使用SqlServer模式搭建Session服务器端有两种方式. ASP.NET 1.0和1.1版本请使用方式a, 2.0即以上版本请使用方式b.

  a.使用SQL文件创建Session数据库

  在ASP.NET 1.0和1.1 版本中, 只能使用这种方式.对于2.0及其以上版本,请使用aspnet_regsql.exe工具.(当然此方法也通用2.0版本)

  .net提供了数据库安装脚本,可以在机器的windows文件夹中找到:

  C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/ InstallSqlState.sql

  C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/ InstallSqlStateTemplate.sql

  根据ASP.NET的版本不同, 需要使用不同的SQL脚本. ASP.NET主要有1.1和2.0两个版本,可以在不同的版本文件夹找到这两个SQL.

  InstallSqlState.sql 是创建默认名称的数据库"[ASPState]".此SQL可以直接运行.

  InstallSqlStateTemplate.sql 可以使用自己指定的数据库保存数据.此SQL需要自己修改后运行, 打开SQL文件将其中 [DatabaseNamePlaceHolder] 替换为自己指定的数据库名称.

  执行installsqlstate.sql时不需要指定数据库,可以在任意数据库上执行.此SQL会自己创建新的数据库

  b. 使用aspnet_regsql.exe工具

  ASP.NET 2.0版本后微软提供了aspnet_regsql.exe工具可以方便的配置Session数据库.该工具位于 Web 服务器上的"系统根目录/Microsoft.NET/Framework/版本号"文件夹中.

  使用举例:
  C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/aspnet_regsql.exe -ssadd -E 运行这个新OK了

  C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/aspnet_regsql.exe -S . -U sa -P 123456 -ssadd -sstype p  这个可远程开启 

例如:

C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727>aspnet_regsql.exe -S . -U sa -P 7777777 -ssadd -sstype c -d chens(自定数据库)

 


  -S参数:

  表示数据库实例名称. 可以用"."表示本机.

  -U和-P参数:

  表示用户名和密码.

  -E参数:

  可以再-U –P 与 -E中选择一组. –E表示以当前系统用户通过windows身份验证登录数据库, -U -P则是使用SqlServer用户登录数据库.

  -ssadd / –ssremove 参数:

  -ssadd表示是添加Session数据库, -ssremove表示移除Session数据库.

  sstype 参数:

  

选项
 说明
 
t
 将会话数据存储到 SQL Server tempdb 数据库中。这是默认设置。如果将会话数据存储到 tempdb 数据库中,则在重新启动 SQL Server 时将丢失会话数据。
 
p
 将会话数据存储到 ASPState 数据库中,而不是存储到 tempdb 数据库中。
 
c
 将会话数据存储到自定义数据库中。如果指定 c 选项,则还必须使用 -d 选项包括自定义数据库的名称。
 

  (2)Session客户端设置

  此房是同样需要Web应用程序修改Web.Config中的节点.如果使用默认的数据库(ASPState库), 则配置如下:

   <sessionState

      mode="SQLServer"

      sqlConnectionString="server=192.168.9.151; uid=sa; pwd=123456;"

      />

  如果使用了自定义的数据库名称,则还需要制定allowCustomSqlDatabase属性并在数据库连接串中指定数据库:

  <sessionState

      mode="SQLServer"

      allowCustomSqlDatabase="true"

      sqlConnectionString="server=192.168.9.151; DataBase=MyAspState;uid=sa; pwd=123456;"

      />

  六.使用经验与技巧总结

  下面是SessionID, Session_End时间, StatServer模式 和 SqlServer模式的各种经验和技巧总结.

  (1)StateServer模式:

  1.在web farm中,请确认在所有的web服务器上有相同的

  2. 要保存在Session中的对象是可序列化的。

  3.为了在web farm中的不同web服务器上维护session state,IIS Metabase中的网站应用程序路径(如/LM/W3SVC/2)应该在所有的服务器上保持一致(大小写敏感).

  4. ASP.NET处理Session是在Machine.Config中配置的HttpModuel模块, 在.NET的安装目录下的Config文件夹中, 查看Web.Config(1.1版本是在Machine.Config):

  <httpModules>

            ...

<add name="Session" type="System.Web.SessionState.SessionStateModule"/> ...

</httpModules>

  确认此模块是否存在.

  5.StateServer不支持负载均衡, 所以如果大并发推荐使用SqlServer模式, 可以享受到SqlServer的高性能和安全性.虽然存储效率会有下降.

  6.需要让所有机器的MachineKey相同.在Machine.Config中配置:

  <machineKey

validationKey="1234567890123456789012345678901234567890AAAAAAAAAA"

decryptionKey="123456789012345678901234567890123456789012345678"

validation="SHA1"

decryption="Auto"

/>

  (2)SqlServer模式:

  1. 要保存在Session中的对象是可序列化的。

  2. 如果使用了默认是数据库, 则在客户端配置文件中的数据库链接字符串的用户,需要拥有ASPState(存储过程在这里==)和tempdb(表在这里)两个库的dbowner权限.

  3. 在SQLServer模式下,session过期是由SQL Agent使用一个注册任务完成的,要确认SQL Agent已经运行。否则无法清理过期的Session数据, 会导致数据库数据一直增加.

  4. 如果使用SqlServer模式时, 对于Web场中的各服务器的 ASP.NET 应用程序路径必须是相同的。请在 IIS 配置数据库中对 Web 场中的所有 Web 服务器进行 Web 站点的应用程序路径同步。大小写一定要相同,因为 Web 站点的应用程序路径是区分大小写的。

  5.需要让所有机器的MachineKey相同.在Machine.Config中配置:

  <machineKey

validationKey="1234567890123456789012345678901234567890AAAAAAAAAA"

decryptionKey="123456789012345678901234567890123456789012345678"

validation="SHA1"

decryption="Auto"

/>

  (3)Session:

  1. 不能直接通过Session服务器在ASP.NET和ASP之间共享Session. 请使用微软提供的解决方案:

  http://msdn.microsoft.com/zh-cn/library/aa479313.aspx

  2. 在不同的应用程序或一个网站的不同虚拟目录之间无法共享Session

  3. Session的过期时间是滑动时间.

  4. Session存储.NET自带的值类型性能最优. 存储对象会降低性能.

  (4)SessionID:

  1.SessionID 还可以保存在URL上, 设置Web.Config文件中的System.Web/sessionState节点的Cookiesless属性即可:

   <sessionState

      cookieless="UseUri"

      />

  2. 一般在Session超时或删除之后,SessionID保持不变. 因为Session过期后会在服务器端清除数据, 但是SessionID保存在用户浏览器上, 所以只要浏览器不关闭则HTTP头中的SessionID保持不变.

  3.关闭浏览器后再访问, SessionID会不同.

  4.每打开一个IE6窗口, SessionID都不同, 在IE6中两个窗口的Session不能共享.

  5.FireFox的标签页和新的FireFox窗口, SessionID都相同, 在FF的窗口和标签页上Session能共享.

  6.对于包含FrameSet的页面,比如:

  <frameset cols="25%,50%,25%">

  <frame src="SessionID.aspx">

  <frame src="SessionID.aspx">

  <frame src="SessionID.aspx">

</frameset>

  如果后缀名是.htm并且.htm文件没有交给ASP.NET的ISAPI处理, 那么根据服务器速度在每个Frame页面生成不同的SessionID, 再刷新后相同都等于最后一个SessionID.

  解决办法是将.htm后缀改成.aspx, 或者将.htm文件交给ASP.NET的ISAPI处理.

  (5)Session_End事件:

  1. Session_End仅在InProc模式中可用

  2. 关闭浏览器,Session_End是不会触发的。HTTP是一种无状态协议,服务器没有办法知道你的浏览器是否已经关闭。

  3. 当Session因为时间过期或调用Session.Abandon时,Session_End才会触发.Session.Clear()仅仅是清除数据,但没有删除session。

  4. Session_End由一个后台线程触发,使用工作者进程账号运行. 所以程序不会通知发生的错误.

  5. 在Session_End访问数据库要考虑权限问题. Session_End是用运行工作者进程(aspnet_wp.exe)的帐号运行的,这个账号可以在machine.config中指定。因此,在Session_End中,如果使用integrity security连接SQL,它将使用工作者进程账号身份连接,这可能会引起登录失败.

  6.因为Session_End是有独立线程出发的, 所以在Session_End中无法使用HttpContext对象(Request,Response,Server等对象都在HttpContext中), 即无法使用 Response.Redirect 和Server.Transfer等方法.

  七.总结

  我已经使用SqlServer模式对公司的多台服务器实现了Session共享, 服务器重启也不会导致用户预定过程重新开始(预定过程需要的Session不会丢失). 希望本文对具体的Session服务器搭建人员有所帮助.

<think>好的,我现在要帮助用户解决关于C# .NETsessionState的配置与使用问题。首先,我需要仔细理解用户的需求。用户提到了几个引用资料,涉及ASP.NET.NET C#以及.NET Core中的Session配置,包括Web.config设置、代码中的调整以及不同模式的区别。用户可能想了解如何正确配置sessionState,选择不同的模式,设置超时时间,以及在不同版本的.NET中的实现差异。 首先,我应该先整理sessionState的基本概念,不同的模式(InProc、StateServer、SQLServer、Off),以及各自的优缺点。然后,需要说明如何在Web.config中配置这些模式,包括各个参数的意义,比如timeout、cookieless、stateConnectionString等。接下来,用户可能想知道如何在代码中动态设置Session的超时时间,比如使用Session.Timeout属性。此外,用户提供的引用中提到了.NET Core中的Session配置,这部分需要单独说明,因为.NET Core的配置方式与传统ASP.NET有所不同,比如在Startup.cs中注入服务和中间件。 还要注意用户可能遇到的一些常见问题,比如Session丢失的情况,特别是在使用InProc模式时,应用程序池回收会导致Session丢失,这时候可能需要使用StateServer或SQLServer模式来持久化Session。同时,超时时间的设置涉及到服务器配置和代码配置,需要解释两者的优先级和最佳实践。 另外,引用资料中提到了不同的配置方法,比如在Web.config中添加sessionState节点,或者在代码中设置Session.Timeout,或者在IIS中进行设置。需要比较这些方法的适用场景和注意事项。例如,使用StateServer模式时需要确保ASP.NET状态服务已经启动,SQLServer模式则需要创建相应的数据库表结构。 在.NET Core部分,用户需要了解如何通过AddSession和AddDistributedSqlServerCache来配置分布式缓存,以及设置IdleTimeout。这部分与传统ASP.NET的配置方式不同,需要详细说明步骤,包括在ConfigureServices中注册服务,在Configure中启用中间件。 最后,用户可能希望了解如何选择适合自己项目的Session模式,比如小型应用可能适合InProc,而需要持久化或扩展的应用则选择StateServer或SQLServer。同时,安全性方面,使用SQLServer模式时需要注意连接字符串的保护,避免敏感信息泄露。 总结一下,我需要分步骤解释sessionState的配置方法,涵盖不同模式和.NET版本,提供代码示例,比较不同模式的优缺点,并给出常见问题的解决方案。同时,根据用户提供的引用资料,确保信息的准确性和相关性,正确标注引用来源。</think>### C# .NET SessionState 配置与使用详解 #### 一、SessionState 基础配置 1. **Web.config 配置** 在 ASP.NET 中,SessionState 的配置主要通过 `Web.config` 文件的 `<sessionState>` 节点实现。支持以下模式: - **InProc**(默认):Session 存储在内存中,重启应用或进程回收会丢失数据。 ```xml <sessionState mode="InProc" timeout="20" cookieless="false" /> ``` - **StateServer**:Session 存储在独立进程(ASP.NET 状态服务)中,需启动服务。 ```xml <sessionState mode="StateServer" timeout="30" stateConnectionString="tcpip=127.0.0.1:42424" /> ``` - **SQLServer**:Session 持久化到 SQL Server 数据库,需初始化表结构。 ```xml <sessionState mode="SQLServer" sqlConnectionString="Data Source=server;Initial Catalog=SessionDB;..." /> ``` - **Off**:禁用 Session[^4]。 - **参数说明**: - `timeout`:会话超时时间(分钟)。 - `cookieless`:是否启用无 Cookie 模式(URL 嵌入 Session ID)。 - `stateConnectionString`:StateServer 的地址和端口[^2][^5]。 2. **代码中动态设置超时** 在 C# 中可通过 `Session.Timeout` 属性调整超时时间: ```csharp protected void Page_Load(object sender, EventArgs e) { Session.Timeout = 60; // 单位:分钟 } ``` #### 二、.NET Core 中的 Session 配置 .NET Core 的 Session 配置方式与传统 ASP.NET 不同,需依赖中间件和分布式缓存: 1. **Startup.cs 配置** - 注册服务: ```csharp public void ConfigureServices(IServiceCollection services) { services.AddDistributedSqlServerCache(o => { o.ConnectionString = "server=10.1.1.10;database=SessionDB;..."; o.SchemaName = "dbo"; o.TableName = "SessionState"; }); services.AddSession(o => { o.IdleTimeout = TimeSpan.FromMinutes(30); // 超时时间 }); } ``` - 启用中间件: ```csharp public void Configure(IApplicationBuilder app) { app.UseSession(); } ``` - 使用 SQL Server 分布式缓存需预先执行脚本创建表结构[^3]。 #### 三、模式对比与选型建议 | 模式 | 优点 | 缺点 | 适用场景 | |------------|-------------------------------|-------------------------------|-----------------------| | **InProc** | 简单、性能高 | 数据易丢失,不支持扩展 | 单服务器小型应用 | | **StateServer** | 支持多服务器共享 | 需维护状态服务 | 负载均衡环境 | | **SQLServer** | 数据持久化,高可靠 | 性能较低,需数据库支持 | 关键业务或高可用需求 | | **Off** | 节省资源 | 无法使用 Session | 无需 Session 的场景 | #### 四、常见问题与解决 1. **Session 丢失** - InProc 模式下,应用程序池回收会导致数据丢失。解决方法:改用 StateServer 或 SQLServer 模式[^1]。 - 检查 `timeout` 是否过短,或代码中是否主动调用 `Session.Abandon()`。 2. **分布式环境配置** - 使用 StateServer 时,需确保 `ASP.NET State Service` 已启动(通过 `services.msc` 检查)。 - SQLServer 模式需执行 `InstallSqlState.sql` 脚本初始化数据库。 3. **性能优化** - 避免存储大型对象,优先使用轻量数据(如用户 ID)。 - 对频繁访问的 Session 数据增加缓存机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值