博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Custom Session-State Module
阅读量:6949 次
发布时间:2019-06-27

本文共 11315 字,大约阅读时间需要 37 分钟。


SessionStateModule类

为一个应用程序提供session-state服务.这个类不能继承.
[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level 
=
 AspNetHostingPermissionLevel.Minimal)]
public
 
sealed
 
class
 SessionStateModule : IHttpModule
SessionStateModle 是ASP.NET的默认Sssion-state Handler,它写入session 数据并且从session-state存储中找回它和调用Session_OnStart和Session_OnEnd事件.下面详细关于怎样使用ASP.NET session state 去存储和为一个用户session找回值.
你能自定义实现IHttpModule接口取代SessionStateModule.

(1)IHttpModule Interface

提供module初始化和配置事件去实现类.
[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level 
=
 AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermissionAttribute(SecurityAction.InheritanceDemand, Level 
=
 AspNetHostingPermissionLevel.Minimal)]
public
 
interface
 IHttpModule

(2)SessionStateUtility Class

提供由session-state modules和session-state储存提供者提供去管理ASP.NET应用程序Session信息helper方法.
[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level 
=
 AspNetHostingPermissionLevel.Minimal)]
public
 
static
 
class
 SessionStateUtility
注意
SessionStateUtility类提供static helper方法,这个方法被一个session-state module所使用或一个session-state存储提供者.应用程序开发者不需要使用他们的代码调用这些方法.
下面是session-state module和session-state 储存者使用的方法:

(3)SessionStateUtility.GetHttpSessionStateFromContext Method

从当前请求context中找回session data.
public
 
static
 IHttpSessionState GetHttpSessionStateFromContext(
    HttpContext context
)
Context参数为HttpContext
返回值类型为System.Web.SessionState.IHttpSessionState.
从当前请求中的Session 数据迁移到IHttpSessionState实现实例.
GetHttpSessionStateFromContext 方法能被一个session-state module使用来从当前请求中找回session data.在触发RelesseRequestState期间是在在一个请求结束时.返回session数据,之后被写入session数据存储.如果Session已经被废弃,这个session数据能从数据存储中被移出和HttpContext,并且Session_OnEnd时间就被执行.
注意:
你能使用RemoveHttpSessionStateFromContext方法去移出session 数据,并且使用 RaiseSessionEnd调用Session_OnEnd事件.
private
 
void
 OnReleaseRequestState(
object
 source, EventArgs args)
{
    HttpApplication app 
= (HttpApplication)source;
    HttpContext context 
= app.Context;
    
string sessionID;
    
// Read the session state from the context
    HttpSessionStateContainer stateProvider =
      (HttpSessionStateContainer)(SessionStateUtility.GetHttpSessionStateFromContext(context));
    
// If Session.Abandon() was called, remove the session data from the local Hashtable
    
// and execute the Session_OnEnd event from the Global.asax file.
    if (stateProvider.IsAbandoned)
    
{
        
try
        
{
            pHashtableLock.AcquireWriterLock(Int32.MaxValue);
            sessionID 
= pSessionIDManager.GetSessionID(context);
            pSessionItems.Remove(sessionID);
        }
        
finally
        
{
            pHashtableLock.ReleaseWriterLock();
        }
        SessionStateUtility.RaiseSessionEnd(stateProvider, 
this, EventArgs.Empty);
    }
    SessionStateUtility.RemoveHttpSessionStateFromContext(context);
}

(4)SessionStateUtility.AddHttpSessionStateToContext Method

从当前请求context里申请session数据.
public
 
static
 
void
 AddHttpSessionStateToContext(
    HttpContext context,
    IHttpSessionState container
)
参数:
context:就是HttpContext.
container:类型为IHttpSessionState,实现这个实例添加进去详细的HTTP context.
注意:
AddHttpSessionStateToContext方法被一个session-state module用来在当前请求中添加session 数据,在开始请求触发AcquireRequestState事件期间.在当前请求Session数据既会找回现有session或创建一个新的session.这个Session数据是封装在一个IHttpSesssionState实现的实例中.与当前的HttpContext一起传给AddHttpSessionStateToContext方法中.提供Session数据之后通过当前context的Session属性产生可是使用的应用程序代码.

(5)SessionStateUtility.RemoveHttpSessionStateFromContext方法

从context中移出session data.
public
 
static
 
void
 RemoveHttpSessionStateFromContext(
    HttpContext context
)
参数:
cotext:就是HttpContext;
注意:
RemoveHttpSessionStateFromContext 方法是从HttpContext中清出session数据.一个 session-state module将在ReleaseRequestState事件handler中调用RemoveHttpSessionStateFromContext.

(6)SessionStateUtility.GetSessionStaticObjects Method

从context中得到一个static Object collection引用.
参数:
context:类型为HttpContext.
GetSessionStaticObjects被使用来找回定义在Global.asax文件中的static object collection.一个session-state module实现将提供返回HttpStaticObjcetCollection 集合去在IHttpSessionState实现的实例中使用AddHttpSessionStateToContext方法添加进当前context.

(7)HttpSessionStateContainer 类

包括Session-state值也有为当前去请求session-level设置.
Session data 传递和从当前的HttpContext中找回,就如HttpSessionStateContainer对象或任何有效的IHttpSessionState接口的实现都可以做到.
ASP.NET提供session-state管理允许你存储信息结合一个唯一浏览器session跨越多个请求.你能存储在用key,index控制的一个值的collection中.访问Session值并且结合通过当前请求的Sesion属性或Page的Session属性给HttpSessionState类所使用,而这个HttpSessionState类访问Sesion-state值和session-level设置都在一个Sesion-state Container设置和引用,而这个HttpSessionState interface的实现已经迁移session-state数据并且由session-state module为HttpApplication添加进当前请求的HttpContext中.
而这个HttpSessionState类调用HttpSessionStateContainer类,来管理在内存中的session的设置和值.
在HttpSessionStateContainer类是HttpSessionState interface的ASP.NET实现.这个HttpSessionStateContainer类不需要调用应用程序代码.如果你要使用custom Session-state module替换SessionStateModule,你能使用HttpSessionStateContainer class或提供你自己的IHttpSessionState interface的实现.

当创建一个SessionStateStoreData时对象一个sessionStateStoreProviderBase还能使用GetSessionStaticObjcets方法.
下面代码为一custom session-state module实现使用Hashtable存储session信息.这个module使用SessionStateUtility 类去引用当前请求的HttpContext和SessionIDManager,重新找回当前的HttpStaticObjcetCollection,并且调用Session_OnEnd事件定义在Global.asax文件.但这里没有防止多个Web请求使用相同的session 标记.
using
 System;
using
 System.Web;
using
 System.Web.SessionState;
using
 System.Collections;
using
 System.Threading;
using
 System.Web.Configuration;
using
 System.Configuration;
namespace
 Samples.AspNet.SessionState
{
    
public sealed class MySessionStateModule : IHttpModule, IDisposable
    
{
        
private Hashtable pSessionItems = new Hashtable();
        
private Timer pTimer;
        
private int pTimerSeconds = 10;
        
private bool pInitialized = false;
        
private int pTimeout;
        
private HttpCookieMode pCookieMode = HttpCookieMode.UseCookies;
        
private ReaderWriterLock pHashtableLock = new ReaderWriterLock();
        
private ISessionIDManager pSessionIDManager;
        
private SessionStateSection pConfig;
        
// The SessionItem class is used to store data for a particular session along with
        
// an expiration date and time. SessionItem objects are added to the local Hashtable
        
// in the OnReleaseRequestState event handler and retrieved from the local Hashtable
        
// in the OnAcquireRequestState event handler. The ExpireCallback method is called
        
// periodically by the local Timer to check for all expired SessionItem objects in the
        
// local Hashtable and remove them.
        
private class SessionItem
        
{
            
internal SessionStateItemCollection Items;
            
internal HttpStaticObjectsCollection StaticObjects;
            
internal DateTime Expires;
        }
        
//
        
// IHttpModule.Init
        
//
        
public void Init(HttpApplication app)
        
{
            
// Add event handlers.
            app.AcquireRequestState += new EventHandler(this.OnAcquireRequestState);
            app.ReleaseRequestState 
+= new EventHandler(this.OnReleaseRequestState);
            
// Create a SessionIDManager.
            pSessionIDManager = new SessionIDManager();
            pSessionIDManager.Initialize();
            
// If not already initialized, initialize timer and configuration.
            if (!pInitialized)
            
{
                
lock (typeof(MySessionStateModule))
                
{
                    
if (!pInitialized)
                    
{
                        
// Create a Timer to invoke the ExpireCallback method based on
                        
// the pTimerSeconds value (e.g. every 10 seconds).
                        pTimer 
= new Timer(new TimerCallback(this.ExpireCallback),
                                           
null,
                                           
0,
                                           pTimerSeconds 
* 1000);
                        
// Get the configuration section and set timeout and CookieMode values.
                        Configuration cfg =
                          WebConfigurationManager.OpenWebConfiguration(System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);
                        pConfig 
= (SessionStateSection)cfg.GetSection("system.web/sessionState");
                        pTimeout 
= (int)pConfig.Timeout.TotalMinutes;
                        pCookieMode 
= pConfig.Cookieless;
                        pInitialized 
= true;
                    }
                }
            }
        }
        
//
        
// IHttpModule.Dispose
        
//
        
public void Dispose()
        
{
            
if (pTimer != null)
            
{
                
this.pTimer.Dispose();
               ((IDisposable)pTimer).Dispose();
            }
        }
        
//
        
// Called periodically by the Timer created in the Init method to check for 
        
// expired sessions and remove expired data.
        
//
        
void ExpireCallback(object state)
        
{
            
try
            
{
                pHashtableLock.AcquireWriterLock(Int32.MaxValue);
                
this.RemoveExpiredSessionData();
            }
            
finally
            
{
                pHashtableLock.ReleaseWriterLock();
            }
        }
        
//
        
// Recursivly remove expired session data from session collection.
        
//
        private void RemoveExpiredSessionData()
        
{
            
string sessionID;
            
foreach (DictionaryEntry entry in pSessionItems)
            
{
                SessionItem item 
= (SessionItem)entry.Value;
                
if ( DateTime.Compare(item.Expires, DateTime.Now)<=0 )
                
{
                    sessionID 
= entry.Key.ToString();
                    pSessionItems.Remove(entry.Key);
                    HttpSessionStateContainer stateProvider 
=
                      
new HttpSessionStateContainer(sessionID,
                                                   item.Items,
                                                   item.StaticObjects,
                                                   pTimeout,
                                                   
false,
                                                   pCookieMode,
                                                   SessionStateMode.Custom,
                                                   
false);
                    SessionStateUtility.RaiseSessionEnd(stateProvider, 
this, EventArgs.Empty);
                    
this.RemoveExpiredSessionData();
                    
break;
                }
            }
        }
        
//
        
// Event handler for HttpApplication.AcquireRequestState
        
//
        
private void OnAcquireRequestState(object source, EventArgs args)
        
{
            HttpApplication app 
= (HttpApplication)source;
            HttpContext context 
= app.Context;
            
bool isNew = false;
            
string sessionID;
            SessionItem sessionData 
= null;
            
bool supportSessionIDReissue = true;
            pSessionIDManager.InitializeRequest(context, 
falseout supportSessionIDReissue);
            sessionID 
= pSessionIDManager.GetSessionID(context);
            
if (sessionID != null)
            
{
                
try
                
{
                    pHashtableLock.AcquireReaderLock(Int32.MaxValue);
                    sessionData 
= (SessionItem)pSessionItems[sessionID];
                    
if (sessionData != null)
                       sessionData.Expires 
= DateTime.Now.AddMinutes(pTimeout);
                }
                
finally
                
{
                    pHashtableLock.ReleaseReaderLock();
                }
            }
            
else
            
{
                
bool redirected, cookieAdded;
                sessionID 
= pSessionIDManager.CreateSessionID(context);
                pSessionIDManager.SaveSessionID(context, sessionID, 
out redirected, out cookieAdded);
                
if (redirected)
                    
return;
            }
            
if (sessionData == null)
            
{
                
// Identify the session as a new session state instance. Create a new SessionItem
                
// and add it to the local Hashtable.
                isNew 
= true;
                sessionData 
= new SessionItem();
                sessionData.Items 
= new SessionStateItemCollection();
                sessionData.StaticObjects 
= SessionStateUtility.GetSessionStaticObjects(context);
                sessionData.Expires 
= DateTime.Now.AddMinutes(pTimeout);
                
try
                
{
                    pHashtableLock.AcquireWriterLock(Int32.MaxValue);
                    pSessionItems[sessionID] 
= sessionData;
                }
                
finally
                
{
                    pHashtableLock.ReleaseWriterLock();
                }
            }
            
// Add the session data to the current HttpContext.
            SessionStateUtility.AddHttpSessionStateToContext(context,
                             
new HttpSessionStateContainer(sessionID,
                                                          sessionData.Items,
                                                          sessionData.StaticObjects,
                                                          pTimeout,
                                                          isNew,
                                                          pCookieMode,
                                                          SessionStateMode.Custom,
                                                          
false));
            
// Execute the Session_OnStart event for a new session.
            if (isNew && Start != null)
            
{
                Start(
this, EventArgs.Empty);
            }
        }
        
//
        
// Event for Session_OnStart event in the Global.asax file.
        
//
        
public event EventHandler Start;
        
//
        
// Event handler for HttpApplication.ReleaseRequestState
        
//
        
private void OnReleaseRequestState(object source, EventArgs args)
        
{
            HttpApplication app 
= (HttpApplication)source;
            HttpContext context 
= app.Context;
            
string sessionID;
            
// Read the session state from the context
            HttpSessionStateContainer stateProvider =
              (HttpSessionStateContainer)(SessionStateUtility.GetHttpSessionStateFromContext(context));
            
// If Session.Abandon() was called, remove the session data from the local Hashtable
            
// and execute the Session_OnEnd event from the Global.asax file.
            if (stateProvider.IsAbandoned)
            
{
                
try
                
{
                    pHashtableLock.AcquireWriterLock(Int32.MaxValue);
                    sessionID 
= pSessionIDManager.GetSessionID(context);
                    pSessionItems.Remove(sessionID);
                }
                
finally
                
{
                    pHashtableLock.ReleaseWriterLock();
                }
                SessionStateUtility.RaiseSessionEnd(stateProvider, 
this, EventArgs.Empty);
            }
            SessionStateUtility.RemoveHttpSessionStateFromContext(context);
        }
    }
}
还有下面的
configuration
你可能感兴趣的文章
路由器与交换机区别
查看>>
Android菜鸟在路上——Activity生命周期
查看>>
Swing-JCheckBox用法-入门
查看>>
比爾蓋茲給年青人的十一句話
查看>>
注册表单常用验证方式
查看>>
lightoj 1012
查看>>
Python3.5入门学习记录-函数
查看>>
主动撤离一线城市,北京到杭州
查看>>
基于Python语言实现的购物车程序<入门小白>
查看>>
Hadoop完全分布式环境搭建(二)——基于Ubuntu16.04设置免密登录
查看>>
impala 问题
查看>>
OCP 11G 052题库解析汇总链接
查看>>
职业规划
查看>>
【最小割】【Dinic】bzoj3275 Number
查看>>
RvmTranslator6.3 is released
查看>>
OpenCASCADE 麻花钻头造型实例分析
查看>>
[旧博客]酷狗百名榜爬虫开源
查看>>
函数名的应用,闭包,迭代器
查看>>
DNS: Intro & Basics
查看>>
常州day1p3
查看>>