简单的 ASP.NET 会话管理框架






2.64/5 (10投票s)
一篇关于管理会话信息的文章。
引言
在为我以前的雇主所做的项目中,我遇到了一个问题,与其他域上的其他应用程序通信后会丢失会话信息。 我的 ASP.NET 应用程序通过隐藏字段,通过 POST 与 Java-Servlet 和 PHP 页面进行通信。 这些页面获取我的 postback-aspx-URL,但在回发后,我失去了会话信息,因为这些应用程序在不同的域上运行。
这就是为什么我一直在 ASP.NET 中寻找存储会话信息的可能性,而无需使用复杂的 State-Management-server 或数据库。
创建框架
ASP.NET 开发人员熟悉 Session
和 Cache
对象,这些对象是我管理会话信息的框架的核心。
我开始创建一个用于存储会话信息的对象,名为 SessionObject
。 见清单 1。 在此对象中,您可以放置会话所需的变量。
public class SessionObject
{
private string _userName = string.Empty;
public string UserName
{
get { return _userName; }
set { _userName = value; }
}
}
清单 1. SessionObject.cs
之后,我一直在思考如何取回 SessionObject
。 在 ASP.NET 中,有一个名为 Cache
的对象。 此对象在每个应用程序域上创建,并且在多线程应用程序上是类型安全的。 不要忘记,当您的 ASP.NET 应用程序被 WebServer 卸载时,您的 Cache
对象也会被刷新。 见清单 2。
public class SessionManager
{
private const string SESSION_MANAGER = "SessionManager";
private HttpContext _context;
private Guid _sessionID;
private SessionObject _sessionObject;
public SessionManager (HttpContext httpContext)
{
_context = httpContext;
}
public static void Initialize(HttpContext httpContext)
{
httpContext.Items.Add(SESSION_MANAGER, new SessionManager (httpContext));
}
public static SessionManager Current
{
get { return (SessionManager) HttpContext.Current.Items[SESSION_MANAGER]; }
}
public Guid SessionID
{
get { return _sessionID; }
set
{
if (!_sessionID.Equals(value))
{
_sessionID = value;
GetSessionObject(value);
}
}
}
private void GetSessionObject(Guid sessionID)
{
_sessionObject = _context.Cache[sessionID.ToString()] as SessionObject;
if (_sessionObject == null)
SetSessionObject(sessionID, new SessionObject());
}
private void SetSessionObject(Guid sessionID, SessionObject sessionObject)
{
_context.Cache.Add(sessionID.ToString(),
sessionObject,
null,
DateTime.MaxValue,
TimeSpan.FromHours(2),
System.Web.Caching.CacheItemPriority.High,
null);
_sessionObject = sessionObject;
}
public SessionObject SessionObject
{
get { return _sessionObject; }
}
}
清单 2. SessionManager.cs
SessionManager
使用 SessionID
,它存储在 Session
对象(不是我们的 SessionObject
)中,或者它将由 ASPX 页面的 QueryString
变量返回。 在 ASP.NET 应用程序的每个请求上,SessionManager
都会被初始化并添加到 HttpContext.Items
中。
protected void Application_BeginRequest(Object sender, EventArgs e)
{
Chompff.SessionManager.Web.SessionManager.Initialize(Context);
}
清单 3. Global.asax.cs
通过创建一个基础 ASPX 页面,所有其他 ASPX 页面都从该页面派生,并带有一个属性 SessionManager
,您可以在所有其他 ASPX 页面上访问 SessionManager
。 但 SessionManager
可能没有初始化 SessionObject
。 因此,我们创建一个属性 SessionID
,并且通过设置基础 ASPX 页面的 SessionID
,SessionManager
会从 Cache 中获取 SessionObject
,或者当它不存在时,它会创建一个并将其放置在 Cache 中。 见清单 4。
public class BaseWebForm : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
}
public SessionManager SessionManager
{
get { return SessionManager.Current; }
}
public Guid SessionID
{
get { return (Guid) Session["SessionID"]; }
set
{
Session["SessionID"] = value;
SessionManager.SessionID = value;
}
}
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
}
清单 4. BaseWebForm.cs
在每个 ASP.NET 应用程序中,都有一个起始页。 此页面必须通过在 Page_Load
中执行以下代码来创建一个新的 SessionID
: this.SessionID = Guid.NewGuid;
。 现在,在 Cache 中创建了一个 SessionObject
,您可以通过在该页面上设置 SessionID
在每个其他 ASPX 页面上获取会话信息。