介绍
由于针对于自定义Session存储方式比较少,所以整理了使用自定义Session的方式。用于构建自定义会话存储提供程序代码,而不是使用默认的 SessionStore 介绍
背景
本文使用的是mysql数据库作为存储session的媒介,其他的方式请自行测试
如何来做自定义session
使用的表格式,建表语句如下:
/****** 对象: Table Sessions 脚本日期: 2013/11/20 星期三 15:28:09 ******/ /****** 字段数据长度 = 4011 字节 ******/ DROP TABLE IF EXISTS `Sessions`; CREATE TABLE `Sessions`( `SessionID` varchar(50) NOT NULL DEFAULT '' COMMENT 'ID', `ApplicationName` varchar(255) NOT NULL DEFAULT '' COMMENT '应用程序名', `CreateTime` datetime NOT NULL DEFAULT '1900-01-01 00:00:00' COMMENT '创建时间', `ExpiresTime` datetime NOT NULL DEFAULT '1900-01-01 00:00:00' COMMENT '过期时间', `LockTime` datetime NOT NULL DEFAULT '1900-01-01 00:00:00' COMMENT '锁定时间', `LockID` int(4) NOT NULL DEFAULT 0 COMMENT '锁定ID', `TimeOut` int(4) NOT NULL DEFAULT 0 COMMENT '超时时间', `IsLocked` tinyint(4) unsigned NOT NULL DEFAULT 0 COMMENT '是否锁定(0:未锁定 / 1:锁定)', `SessionItems` varchar(3000) NOT NULL DEFAULT '' COMMENT 'Session内容', `Flags` int(4) NOT NULL DEFAULT 0 COMMENT '标记', `IsDelete` tinyint(4) unsigned NOT NULL DEFAULT 0 COMMENT '是否删除(0:未删除 / 1:删除)', `AddTime` datetime NOT NULL DEFAULT '1900-01-01 00:00:00' COMMENT '添加时间:数据添加Now()(now())', `ModifyTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳(CURRENT_TIMESTAMP)', PRIMARY KEY ( `SessionID` ), INDEX `IDX_Sessions_1` (`ApplicationName`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Session操作表:用于记录session使用数据';
我们定义一个CustomSessionStoreProvider,此类继承了SessionStateStore[roviderBase,里面里面的生成方式来进行处理,代码如下
namespace ShareSession { using System; using System.Collections.Specialized; using System.Configuration; using System.Data; using System.Diagnostics; using System.IO; using System.Web; using System.Web.Configuration; using System.Web.SessionState; using Better.Infrastructures.DBUtility; using MySql.Data.MySqlClient; /// <summary> /// CustomSessionStoreProvider类 /// </summary> public class CustomSessionStoreProvider : SessionStateStoreProviderBase { /// <summary> /// 事件源 /// </summary> private const string EventSource = "ShareSession.CustomSessionStoreProvider"; /// <summary> /// 事件日志名 /// </summary> private const string EventLog = "Application"; /// <summary> /// 连接. /// </summary> private readonly IDbConnection conn = new MySqlConnection(ConfigurationManager.ConnectionStrings["SessionsConn"].ConnectionString); /// <summary> /// Session状态对象 /// </summary> private SessionStateSection configSection; /// <summary> /// 应用程序名 /// </summary> private string applicationName = string.Empty; /* * If false, exceptions are thrown to the caller. If true, * exceptions are written to the event log. */ /// <summary> /// Initializes a new instance of the <see cref="CustomSessionStoreProvider"/> class. /// </summary> public CustomSessionStoreProvider() { this.WriteExceptionsToEventLog = false; } /// <summary> /// 是否写入异常事件日志 /// </summary> public bool WriteExceptionsToEventLog { get; set; } /// <summary> /// 应用程序名 /// </summary> public string ApplicationName { get { return this.applicationName; } } /// <summary> /// 初始化 /// </summary> /// <param name="name">名字</param> /// <param name="config">配置集合</param> public override void Initialize(string name, NameValueCollection config) { // Initialize values from web.config. if (config == null) { throw new ArgumentNullException("config"); } if (name.Length == 0) { name = "CustomSessionStateStore"; } if (string.IsNullOrEmpty(config["description"])) { config.Remove("description"); config.Add("description", "Custom Session State Store provider"); } // Initialize the abstract base class. base.Initialize(name, config); // Initialize the ApplicationName property. this.applicationName = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath; // Get <sessionState> configuration element. var cfg = WebConfigurationManager.OpenWebConfiguration(this.ApplicationName); this.configSection = (SessionStateSection)cfg.GetSection("system.web/sessionState"); // Initialize WriteExceptionsToEventLog this.WriteExceptionsToEventLog = false; if (config["writeExceptionsToEventLog"] != null) { if (config["writeExceptionsToEventLog"].ToUpper() == "TRUE") { this.WriteExceptionsToEventLog = true; } } } /// <summary> /// 释放Session /// </summary> public override void Dispose() { } /// <summary> /// 设置session过期回调方法. /// </summary> /// <param name="expireCallback"> /// The expire callback. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback) { return false; } /// <summary> /// The set and release item exclusive. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="id"> /// The id. /// </param> /// <param name="item"> /// The item. /// </param> /// <param name="lockId"> /// The lock id. /// </param> /// <param name="newItem"> /// The new item. /// </param> public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { // Serialize the SessionStateItemCollection as a string. string sessItems = Serialize((SessionStateItemCollection)item.Items); string tmpDeleteQuery; try { string tmpQuery; if (newItem) { if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } // query to clear an existing expired session if it exists. tmpDeleteQuery = @"UPDATE Sessions SET IsDelete = 1 WHERE SessionID = @session_id AND ApplicationName = @application_name AND ExpiresTime < now() "; MySqlParameter[] deleParameters = { new MySqlParameter("@session_id", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@application_name", MySqlDbType.VarChar) { Value = this .ApplicationName } }; var row = MysqlHelper.ExecuteSql(null, this.conn, tmpDeleteQuery, deleParameters); this.conn.Close(); if (row == 0) { // query to insert the new session item. tmpQuery = @"INSERT INTO Sessions (SessionID, ApplicationName, CreateTime, ExpiresTime, LockTime, LockID, TimeOut, IsLocked, SessionItems, Flags, IsDelete, AddTime) Values(@session_id, @app_name, now(),date_add(now(), interval @minute minute), now(), @lock_id, @timeout, @locked, @session_items, @flags, 0, now())"; MySqlParameter[] insertParameters = { new MySqlParameter("@session_id", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this .ApplicationName }, new MySqlParameter("@minute", MySqlDbType.Int32) { Value = item .Timeout }, new MySqlParameter("@lock_id", MySqlDbType.Int32) { Value = 0 }, new MySqlParameter("@timeout", MySqlDbType.Int32) { Value = item .Timeout }, new MySqlParameter("@locked", MySqlDbType.Int16) { Value = 0 }, new MySqlParameter("@session_items", MySqlDbType.VarChar) { Value = sessItems }, new MySqlParameter("@flags", MySqlDbType.Int32) { Value = 0 } }; this.conn.Open(); MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, insertParameters); this.conn.Close(); } else { tmpQuery = @"UPDATE Sessions SET IsDelete = 0, CreateTime = now(), ExpiresTime = date_add(now(), interval @minute minute) , TimeOut = @TimeOut, SessionItems = @SessionItems WHERE SessionID=@SessionID"; MySqlParameter[] insertParameters = { new MySqlParameter("@minute", MySqlDbType.VarChar) { Value = item.Timeout }, new MySqlParameter("@TimeOut", MySqlDbType.Int32) { Value = item .Timeout }, new MySqlParameter("@SessionItems", MySqlDbType.VarChar) { Value = sessItems }, new MySqlParameter("@SessionID", MySqlDbType.VarChar) { Value = id } }; this.conn.Open(); MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, insertParameters); this.conn.Close(); } } else { // query to update the existing session item. tmpQuery = @"UPDATE Sessions SET ExpiresTime = date_add(now(), interval @minute minute), SessionItems = @sess_items, IsLocked = @locked WHERE SessionId = @sess_id AND ApplicationName = @app_name AND LockID = @lock_id limit 1"; MySqlParameter[] updateParameters = { new MySqlParameter("@minute", MySqlDbType.VarChar) { Value = item.Timeout }, new MySqlParameter("@sess_items", MySqlDbType.VarChar) { Value = sessItems }, new MySqlParameter("@locked", MySqlDbType.Int16) { Value = 0 }, new MySqlParameter("@sess_id", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this .ApplicationName }, new MySqlParameter("@lock_id", MySqlDbType.Int32) { Value = lockId } }; this.conn.Open(); MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, updateParameters); this.conn.Close(); } } catch (Exception e) { if (this.WriteExceptionsToEventLog) { this.WriteToEventLog(e, "SetAndReleaseItemExclusive"); throw; } else { throw; } } finally { this.conn.Close(); this.conn.Dispose(); } } /// <summary> /// 初始化请求对象. /// </summary> /// <param name="context"> /// 请求文本内容. /// </param> public override void InitializeRequest(HttpContext context) { } /// <summary> /// 得到指定session数据. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="id"> /// The id. /// </param> /// <param name="locked"> /// The locked. /// </param> /// <param name="lockAge"> /// The lock age. /// </param> /// <param name="lockId"> /// The lock id. /// </param> /// <param name="actions"> /// The actions. /// </param> /// <returns> /// The <see cref="SessionStateStoreData"/>. /// </returns> public override SessionStateStoreData GetItem( HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this.GetSessionStoreItem( false, context, id, out locked, out lockAge, out lockId, out actions); } /// <summary> /// The get item exclusive. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="id"> /// The id. /// </param> /// <param name="locked"> /// The locked. /// </param> /// <param name="lockAge"> /// The lock age. /// </param> /// <param name="lockId"> /// The lock id. /// </param> /// <param name="actions"> /// The actions. /// </param> /// <returns> /// The <see cref="SessionStateStoreData"/>. /// </returns> public override SessionStateStoreData GetItemExclusive( HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return this.GetSessionStoreItem( false, context, id, out locked, out lockAge, out lockId, out actions); } /// <summary> /// The release item exclusive. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="id"> /// The id. /// </param> /// <param name="lockId"> /// The lock id. /// </param> public override void ReleaseItemExclusive(HttpContext context, string id, object lockId) { string tmpQuery = @"UPDATE Sessions SET IsLocked = 0, ExpiresTime = date_add(now(), interval @minute minute) WHERE SessionId = @sess_id AND ApplicationName = @app_name AND LockID = @lock_id Limit 1"; MySqlParameter[] parameters = { new MySqlParameter("@minute", MySqlDbType.VarChar) { Value = this.configSection.Timeout.Minutes }, new MySqlParameter("@sess_id", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this.ApplicationName }, new MySqlParameter("@lock_id", MySqlDbType.Int32) { Value = lockId } }; if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } try { MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, parameters); } catch (Exception e) { if (this.WriteExceptionsToEventLog) { this.WriteToEventLog(e, "ReleaseItemExclusive"); throw; } else { throw; } } finally { this.conn.Close(); } } /// <summary> /// The remove item. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="id"> /// The id. /// </param> /// <param name="lockId"> /// The lock id. /// </param> /// <param name="item"> /// The item. /// </param> public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item) { string tmpQuery = @"UPDATE Sessions SET IsDelete = 1 WHERE SessionId = @sess_id AND ApplicationName = @app_name AND LockId = @lock_id Limit 1"; tmpQuery = tmpQuery.Replace("@sess_id@", id); tmpQuery = tmpQuery.Replace("@app_name@", this.ApplicationName); tmpQuery = tmpQuery.Replace("@lock_id@", lockId.ToString()); MySqlParameter[] parameters = { new MySqlParameter("@sess_id", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this.ApplicationName }, new MySqlParameter("@lock_id", MySqlDbType.Int32) { Value = lockId } }; if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } try { MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, parameters); } catch (Exception e) { if (this.WriteExceptionsToEventLog) { this.WriteToEventLog(e, "RemoveItem"); throw; } else { throw e; } } finally { this.conn.Close(); } } /// <summary> /// The reset item timeout. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="id"> /// The id. /// </param> public override void ResetItemTimeout(HttpContext context, string id) { string tmpQuery = @"UPDATE Sessions SET ExpiresTime = date_add(now(), interval @minute minute) WHERE SessionId = @sess_id AND ApplicationName = @app_name Limit 1"; MySqlParameter[] parameters = { new MySqlParameter("@minute", MySqlDbType.VarChar) { Value = this.configSection.Timeout.Minutes }, new MySqlParameter("@sess_id", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this.ApplicationName } }; if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } try { MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, parameters); } catch (Exception e) { if (this.WriteExceptionsToEventLog) { this.WriteToEventLog(e, "ResetItemTimeout"); throw; } else { throw; } } finally { this.conn.Close(); } } /// <summary> /// The create new store data. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="timeout"> /// The timeout. /// </param> /// <returns> /// The <see cref="SessionStateStoreData"/>. /// </returns> public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout) { return new SessionStateStoreData( new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout); } /// <summary> /// The create uninitialized item. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="id"> /// The id. /// </param> /// <param name="timeout"> /// The timeout. /// </param> public override void CreateUninitializedItem(HttpContext context, string id, int timeout) { try { var tmpQuery = @"UPDATE Sessions SET IsDelete = 0, CreateTime = now(), ExpiresTime = date_add(now(), interval @minute minute), TimeOut = @TimeOut, SessionItems = @SessionItems WHERE SessionID=@SessionID Limit 1"; MySqlParameter[] parameters = { new MySqlParameter("@minute", MySqlDbType.VarChar) { Value = timeout }, new MySqlParameter("@TimeOut", MySqlDbType.Int32) { Value = timeout }, new MySqlParameter("@SessionItems", MySqlDbType.VarChar) { Value = string .Empty }, new MySqlParameter("@SessionID", MySqlDbType.VarChar) { Value = id } }; if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } var row = MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, parameters); this.conn.Close(); if (row != 0) { return; } // query to insert the new session item. tmpQuery = @"INSERT INTO Sessions (SessionID, ApplicationName, CreateTime, ExpiresTime, LockTime, LockID, TimeOut, IsLocked, SessionItems, Flags, IsDelete, AddTime) Values(@session_id, @app_name, now(),date_add(now(), interval @minute minute), now(), @lock_id, @timeout, @locked, @session_items, @flags, 0, now())"; MySqlParameter[] insertParameters = { new MySqlParameter("@session_id", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this .ApplicationName }, new MySqlParameter("@minute", MySqlDbType.VarChar) { Value = timeout }, new MySqlParameter("@lock_id", MySqlDbType.Int32) { Value = 0 }, new MySqlParameter("@timeout", MySqlDbType.Int32) { Value = timeout }, new MySqlParameter("@locked", MySqlDbType.Int16) { Value = 0 }, new MySqlParameter("@session_items", MySqlDbType.VarChar) { Value = string .Empty }, new MySqlParameter("@flags", MySqlDbType.Int32) { Value = 0 } }; if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, insertParameters); } catch (Exception e) { if (this.WriteExceptionsToEventLog) { this.WriteToEventLog(e, "ResetItemTimeout"); throw; } else { throw; } } finally { this.conn.Close(); this.conn.Dispose(); } } /// <summary> /// The end request. /// </summary> /// <param name="context"> /// The context. /// </param> public override void EndRequest(HttpContext context) { } /// <summary> /// 反序列化对象 /// </summary> /// <param name="context">请求文本内容对象</param> /// <param name="serializedItems">序列化项目</param> /// <param name="timeout">超时时间</param> /// <returns>返回构造好的Session储存对象</returns> private static SessionStateStoreData Deserialize(HttpContext context, string serializedItems, int timeout) { MemoryStream ms = new MemoryStream(Convert.FromBase64String(serializedItems)); SessionStateItemCollection sessionItems = new SessionStateItemCollection(); if (ms.Length > 0) { BinaryReader reader = new BinaryReader(ms); sessionItems = SessionStateItemCollection.Deserialize(reader); } return new SessionStateStoreData( sessionItems, SessionStateUtility.GetSessionStaticObjects(context), timeout); } /// <summary> /// 序列化 /// </summary> /// <param name="items">需序列化的session对象</param> /// <returns>返回序列化字符串</returns> private static string Serialize(SessionStateItemCollection items) { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); if (items != null) { items.Serialize(writer); } writer.Close(); return Convert.ToBase64String(ms.ToArray()); } /// <summary> /// 得到session存储对象 /// </summary> /// <param name="lockRecord">是否锁定记录</param> /// <param name="context">请求对象文本</param> /// <param name="id">唯一id</param> /// <param name="locked">返回是否锁定</param> /// <param name="lockAge">锁定时长</param> /// <param name="lockId">锁定Id</param> /// <param name="actionFlags">触发标记</param> /// <returns>返回Session状态存储对象数据</returns> private SessionStateStoreData GetSessionStoreItem( bool lockRecord, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags) { // Initial values for return value and out parameters. SessionStateStoreData item = null; lockAge = TimeSpan.Zero; lockId = null; locked = false; actionFlags = 0; // DateTime to check if current session item is expired. DateTime expires; // String to hold serialized SessionStateItemCollection. string serializedItems = string.Empty; // True if a record is found in the database. bool foundRecord = false; // True if the returned session item is expired and needs to be deleted. bool deleteData = false; // Timeout value from the data store. int timeout = 0; try { string tmpQuery; // lockRecord is true when called from GetItemExclusive and // false when called from GetItem. // Obtain a lock if possible. Ignore the record if it is expired. if (lockRecord) { tmpQuery = @"UPDATE Sessions SET IsLocked = @Islocked, LockTime = now() WHERE SessionID = @sessionid AND ApplicationName = @app_name AND ExpiresTime > now() AND IsDelete = 0"; MySqlParameter[] parameters = { new MySqlParameter("@Islocked", MySqlDbType.Int16) { Value = 1 }, new MySqlParameter("@sessionid", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this.ApplicationName } }; if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } locked = MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, parameters) == 0; this.conn.Close(); } // Retrieve the current session item information. tmpQuery = @"SELECT ExpiresTime, SessionItems, LockID, LockTime, Flags, TimeOut FROM Sessions WHERE SessionID = @sessionid AND ApplicationName = @app_name AND IsDelete = 0"; MySqlParameter[] seleParameters = { new MySqlParameter("@sessionid", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this.ApplicationName } }; if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } // Retrieve session item data from the data source. using (var reader = MysqlHelper.ExecuteReader(null, this.conn, tmpQuery, seleParameters)) { if (reader.HasRows) { while (reader.Read()) { expires = reader.IsDBNull(reader.GetOrdinal("ExpiresTime")) ? DateTime.Parse("1900-1-1") : reader.GetDateTime(reader.GetOrdinal("ExpiresTime")); if (expires < DateTime.Now) { // The record was expired. Mark it as not locked. locked = false; // The session was expired. Mark the data for deletion. deleteData = true; } else { foundRecord = true; } serializedItems = reader.IsDBNull(reader.GetOrdinal("SessionItems")) ? string.Empty : reader.GetString(reader.GetOrdinal("SessionItems")); lockId = reader.IsDBNull(reader.GetOrdinal("LockID")) ? 0 : reader.GetInt32(reader.GetOrdinal("LockID")); lockAge = DateTime.Now.Subtract(reader.IsDBNull(reader.GetOrdinal("LockTime")) ? DateTime.Parse("1900-1-1") : reader.GetDateTime(reader.GetOrdinal("LockTime"))); actionFlags = (SessionStateActions)(reader.IsDBNull(reader.GetOrdinal("Flags")) ? 0 : reader.GetInt32(reader.GetOrdinal("Flags"))); timeout = reader.IsDBNull(reader.GetOrdinal("TimeOut")) ? 0 : reader.GetInt32(reader.GetOrdinal("TimeOut")); } } } this.conn.Close(); // If the returned session item is expired, // delete the record from the data source. if (deleteData) { tmpQuery = @" UPDATE Sessions SET IsDelete = 1 WHERE SessionID = @sess_id AND ApplicationName = @app_name AND IsDelete = 0 Limit 1"; MySqlParameter[] deleParameters = { new MySqlParameter("@sessionid", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this.ApplicationName } }; if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, deleParameters); this.conn.Close(); } // The record was not found. Ensure that locked is false. if (!foundRecord) { locked = false; } // If the record was found and you obtained a lock, then set // the lockId, clear the actionFlags, // and create the SessionStateStoreItem to return. if (foundRecord && !locked) { lockId = (int)lockId + 1; tmpQuery = @" UPDATE Sessions SET LockId = @lock_id, Flags = @flags WHERE SessionID = @sess_id AND ApplicationName = @app_name Limit 1"; MySqlParameter[] updateParameters = { new MySqlParameter("@lock_id", MySqlDbType.Int32) { Value = lockId }, new MySqlParameter("@flags", MySqlDbType.Int32) { Value = 0 }, new MySqlParameter("@sess_id", MySqlDbType.VarChar) { Value = id }, new MySqlParameter("@app_name", MySqlDbType.VarChar) { Value = this.ApplicationName } }; if (this.conn.State != ConnectionState.Open) { this.conn.Open(); } MysqlHelper.ExecuteSql(null, this.conn, tmpQuery, updateParameters); this.conn.Close(); // If the actionFlags parameter is not InitializeItem, // deserialize the stored SessionStateItemCollection. if (actionFlags == SessionStateActions.InitializeItem) { item = this.CreateNewStoreData(context, this.configSection.Timeout.Minutes); } else { item = Deserialize(context, serializedItems, timeout); } } } catch (Exception e) { if (this.WriteExceptionsToEventLog) { this.WriteToEventLog(e, "GetSessionStoreItem"); throw; } else { throw; } } finally { this.conn.Close(); this.conn.Dispose(); } return item; } /// <summary> /// 写入事件日志 /// </summary> /// <param name="e">异常对象</param> /// <param name="action">触发点</param> private void WriteToEventLog(Exception e, string action) { EventLog log = new EventLog { Source = EventSource, Log = EventLog }; string message = "An exception occurred communicating with the data source. "; message += "Action: " + action + " "; message += "Exception: " + e; log.WriteEntry(message); } } }
未解决的问题
- 统计在线人数,Session共享后如何来处理
- 不能序列化的数据,如何处理
其他相关链接
http://msdn.microsoft.com/en-us/library/ms178589(v=vs.100).aspx