对于asp.net 程序员来说,Session的存储方式有InProc、StateServer、SQLServer和Custom,但是Custom确很少有人提及。但Custom确实最好用,目前最实用和最灵活一种方式,因为Custom可以实现各种情况的Session存储,特别对于大型网站尤为重要,解决Session丢失和Session效率的最佳实现方式,也是实现单点登录的最佳途径。 对于InProc、StateServer和SQLServer各自优缺点,网上一大堆,这里就不做详解。
重要的两点
1、首先是关于Session存储,Session的存储并不是我们想象的,当设置Session时立即往数据容器里插入或者修改数据,当获取Session的值时就是立即去数据容器里获取值,这种理解是错误的(我之前就是这样理解的)。后来想想完全没必要这样操作,而且会大大影响效率。Asp.net的Session实现方式是每次请求前获取数据,当请求逻辑代码结束的时候在设置Session的值,所以说Session对数据容器的修改简单的意义只有两次,这个可能就要牵扯到管道流了。
2、第二个就是关于Asp.net网站异步的问题,当我们不设置Session的状态为只读时,我们每个用户的请求其实都是同步的,也就说每个用户请求网站同时只能有一个请求响应。理解这个就可以理解后面实现方法中需要锁的概念了。
SessionStateStoreProviderBase
SessionStateStoreProviderBase是asp.net框架为我们提供的一个用来存储Session提供程序所需的成员(就是实现这个类),我们知道的InProc、SQLServer、StateServer都是实现了这个抽象类。继承这个类需要有多个抽象方法需要实现。关于这多个方法没必要每个都实现,我们只关注我们需要实现的即可。说简单点就是对Session数据的增删改查(CRUD)。关于SessionStateStoreProviderBase的详情可以参考
<table summary="table">
<tr><th scope="col">
成员
如果数据存储区中未找到任何会话项数据,则方法将
如果在数据存储区中找到会话项数据但该数据已锁定,则方法将
如果
如果提供程序支持无 Cookie 会话,请将
方法 除了不尝试锁定数据存储区中的会话项以外,此方法与方法执行的操作相同。方法在属性设置为 方法 采用当前请求的实例、当前请求的值、包含要存储的当前会话值的对象、当前请求的锁定标识符以及指示要存储的数据是属于新会话还是现有会话的值作为输入。如果
调用方法后,调用方法来更新会话项数据的过期日期和时间。
方法 采用当前请求的实例、当前请求的值以及当前请求的锁定标识符作为输入,并释放对会话数据存储区中的项的锁定。在调用或方法,并且数据存储区指定被请求项已锁定,但锁定时间已超过值时会调用此方法。此方法清除锁定,释放该被请求项以供其他请求使用。 方法 采用当前请求的实例、当前请求的值以及当前请求的锁定标识符作为输入,并删除数据存储区中与提供的值、当前应用程序和提供的锁定标识符相匹配的数据存储项的会话信息。此方法在方法被调用时调用。 方法 采用当前请求的实例、当前请求的值以及当前请求的锁定标识符作为输入,并向会话数据存储区添加一个如果
生成新的值的过程需要浏览器重定向到包含新生成的会话 ID 的 URL。在包含过期的会话 ID 的初始请求期间,会调用方法。获取一个新的值来替换过期的会话 ID 之后,它会调用方法以将一个未初始化项添加到会话状态数据存储区中。然后,浏览器重定向到包含新生成的值的 URL。如果会话数据存储区中存在未初始化项,则可以确保包含新生成的值的重定向请求被视为新的会话,而不会被误认为是对过期会话的请求。
会话数据存储区中未初始化的项与新生成的值关联,并且仅包含默认值,其中包括到期日期和时间以及与和方法的
方法 采用当前请求的实例和当前会话的值作为输入,并返回带有空对象的新的对象、一个集合和指定的值。使用方法可以检索 ASP.NET 应用程序的实例。 方法 采用引用 Global.asax 文件中定义的 由于本机只有SQLServer作为数据存储,所有就用SqlServer作为代码演示,其原理都一样的,直接改成Redis或者其他的就可以。表结构
. () ,
,
,
,
,
,
,
() ,
,
)
代码实现
System.Web.Configuration.SessionStateSection sessionStateSection = (System.Web.Configuration.SessionStateSection)System.Configuration.ConfigurationManager.GetSection( _expiresTime =
SessionStateStoreData CreateNewStoreData(HttpContext context, SessionStateStoreData(
ReleaseItemExclusive(HttpContext context, (SessionStateEF db = session = (session ==
session.Locked = session.Expires = DateTime.Now +
RemoveItem(HttpContext context, (SessionStateEF db = session = (session ==
ResetItemTimeout(HttpContext context, (SessionStateEF db = session = (session == session.Expires = DateTime.Now +
SessionStateStoreData DoGet( isExclusive,HttpContext context, (SessionStateEF db =
item = lockAge = lockId = locked = actions =
session = (session ==
locked = lockAge = session.LockDate - lockId =
(session.Expires <
lockId = lockId == ? : ()lockId + session.Flags = ( session.LockId =
timeout = actions == SessionStateActions.InitializeItem ?
SessionStateItemCollection sessionStateItemCollection =
(actions == SessionStateActions.None && ! sessionStateItemCollection =
item = SessionStateStoreData(sessionStateItemCollection ?? SessionStateItemCollection(),(
序列化反序列化Session的值
MemoryStream ms = BinaryWriter writer = (items !=
}
最后配置web.configsystem.web/sessionState
Github地址
最后的最后,求推荐