ASP.NET Session

最简单的保存/读取会话状态中的值

Session["name"] = "ZZH";
string name = (string)(Session["name"]);
也可以存储集合,Cookie只能保存字符串

概述

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

只要一直使用相同的 SessionID 值来发送请求,会话就被视为活动的。如果特定会话的请求间隔超过指定的超时值(以分钟为单位),则该会话被视为已过期。使用过期的 SessionID 值发送的请求将生成一个新的会话。

默认情况下,SessionID 值存储在浏览器的不过期会话 Cookie 中。但是,通过在 Web.config 文件的 sessionState 节中将 cookieless 属性设置为 true,可以指定不应将会话标识符存储在 Cookie 中。应用程序配置为在“无 Cookie”会话的 URL 中存储 SessionID 值。如 http://www.example.com/(S(lit3py55t21z5v55vlm25s55))/orderform.aspx

注意:为提高应用程序的安全性,您应当允许用户从应用程序注销,此时应用程序应当调用 Abandon 方法。这降低了恶意用户获取 URL 中的唯一标识符并用它检索存储在会话中的用户私人数据的风险。

下面是如何配置无Cookie会话,在web.config中配置

<configuration>
  <system.web>
    <sessionState cookieless="true"
      regenerateExpiredSessionId="true" />
  </system.web>
</configuration>
默认情况下,将回收无 Cookie 会话中使用的会话 ID 值。也就是说,如果使用已过期的会话 ID 发起一个请求,将使用该请求提供的 SessionID 值启动一个新的会话。当包含无 Cookie SessionID 值的链接由多个浏览器使用时,这会导致无意中共享会话。(如果通过搜索引擎、电子邮件或另一个程序传递链接,则会发生这种情况。)可以通过将应用程序配置为不回收会话标识符来减少共享会话数据的机会。为此,将 sessionState 配置元素的 regenerateExpiredSessionId 属性设置为 true。这将在使用已过期的会话 ID 发起无 Cookie 会话请求时,生成一个新的会话 ID。

会话状态事件

ASP.NET 提供了两种帮助您管理用户会话的事件:Session_OnStart 事件和 Session_OnEnd 事件;前者在新会话开始时引发,后者在会话被放弃或过期时引发。

可以通过向 Global.asax 文件添加一个名为 Session_OnStart 的子例程来处理 Session_OnStart 事件。如果请求开始一个新会话,Session_OnStart 子例程会在请求开始时运行。如果请求不包含 SessionID 值或请求所包含的 SessionID 属性引用一个已过期的会话,则会开始一个新会话。

可以通过向 Global.asax 文件添加一个名为 Session_OnEnd 的子例程来处理 Session_OnEnd 事件。Session_OnEnd 子例程在 Abandon 方法已被调用或会话已过期时运行。如果超过了某一会话 Timeout 属性指定的分钟数并且在此期间内没有请求该会话,则该会话过期。   只有会话状态属性 Mode 设置为 InProc(默认值)时,才支持 Session_OnEnd 事件。如果会话状态属性 Mode 为 StateServer 或 SQLServer,则忽略 Global.asax 文件中的 Session_OnEnd 事件。如果会话状态属性 Mode 设置为 Custom,则由自定义会话状态存储提供程序决定是否支持 Session_OnEnd 事件。


会话状态模式

1. InProc 进程内模式,此模式将会话状态存储在 Web 服务器上的内存中。这是默认设置。(唯一支持Session_End事件)


2. StateServer 状态服务器模式,此模式将会话状态存储在一个名为 ASP.NET 状态服务的单独进程中。这确保了在重新启动 Web 应用程序时会保留会话状态,并让会话状态可用于网络场中的多个 Web 服务器。如下

<configuration>
  <system.web>
    <sessionState mode="StateServer"
      stateConnectionString="tcpip=SampleStateServer:42424"
      cookieless="false"
      timeout="20"/>
  </system.web>
</configuration>

3. SQLServer 模式将会话状态存储到一个 SQL Server 数据库中。这确保了在重新启动 Web 应用程序时会保留会话状态,并让会话状态可用于网络场中的多个 Web 服务器。如下

<configuration>
  <system.web>
    <sessionState mode="SQLServer"
      sqlConnectionString="Integrated Security=SSPI;data 
        source=SampleSqlServer;" />
  </system.web>
</configuration>

4. Custom 自定义模式,此模式允许您指定自定义存储提供程序。
5. Off 模式,此模式禁用会话状态。


下面说说Session在客户端和服务器如何实现跨域共享

当我们请求一个 URL时候,服务器会生成一个全局的SessionID,并且把这个值以Cookies的形式保存在客户端也就是浏览器(这里暂不讨论url方式)。这样 当用户再去请求的时候,在http头把这个SessionID的Cookie发到服务器端,服务器就去找这个SessionID,如果找到了。就证明这个 用户的状态是存在的。

即然是用Cookies来保存SessionID,那么我们就可以在Cooikes上做手脚了。我们都知 道Cooikes记录方式是以域(例如:http://www.local.com/)为区分的,这也是各种浏览器规定的。如果不这么做,安全性就会有问 题。我们要做的就是让指定Cookies的父域方式,不指定具体指域,这样Cookies就可以跨子域了。

asp.net存SessionID的Cooike的名字是ASP.NET_SessionId,我们可以在Session_Start中这样写:

 protected void Session_Start(object sender, EventArgs e)
	{
		Response.Cookies["ASP.NET_SessionId"].Value = Session.SessionID.ToString();
		Response.Cookies["ASP.NET_SessionId"].Domain = ".local.com";
	}
代码的意思是每次会话开始的时候,我都把ASP.NET_SessionId这个Cookie重写成我们已有的SessionID,并且把这个Cookie的domain指定为父域,比如:.local.com,这样就可以实现跨子域的Session共享了。


我们还有一个外题问题,就是客户端保存的问题解决了,但是服务器端的Session怎么办?一般情况下我们不同的子域做的是指向不同的服务器的,比如user.local.com 专门一台服务器,yellow.local.com专门一台服务器。这时它们别说是进程了,连物理上都不是一个了。Session怎么共享?这时就用到另一个方法了,我们默认的Session是存储在asp.net进程中的,这样没法互相访问。<sessionState mode="InProc" />

我们可以用会话状态的StateServer 状态服务器模式,或者SQLServer 模式 来实现即可。


session跨域共享参考自http://www.cnblogs.com/assion/archive/2010/07/29/1787960.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值