Asp.Net 自定义储存Session方式

时间:2022-09-17 16:34:54

介绍

由于针对于自定义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.\n\n";
message += "Action: " + action + "\n\n";
message += "Exception: " + e; log.WriteEntry(message);
}
}
}

未解决的问题

  • 统计在线人数,Session共享后如何来处理
  • 不能序列化的数据,如何处理

其他相关链接

http://msdn.microsoft.com/en-us/library/ms178589(v=vs.100).aspx

Asp.Net 自定义储存Session方式的更多相关文章

  1. ASP&period;NET 使用mode&equals;”InProc”方式保存Session老是丢失,无奈改成StateServer 模式。

    http://blog.csdn.net/fox123871/article/details/8165431 session是工作在你的应用程序进程中的.asp.net进程.iis往往会在20分钟之后 ...

  2. ASP&period;NET WebApi 基于分布式Session方式实现Token签名认证

    一.课程介绍 明人不说暗话,跟着阿笨一起学玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NETWebSer ...

  3. ASP&period;NET WebApi 基于分布式Session方式实现Token签名认证&lpar;发布版&rpar;

    一.课程介绍 明人不说暗话,跟着阿笨一起学玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NETWebSer ...

  4. 连表查询都用Left Join吧 以Windows服务方式运行&period;NET Core程序 HTTP和HTTPS的区别 ASP&period;NET SignalR介绍 asp&period;net—WebApi跨域 asp&period;net—自定义轻量级ORM C&num;之23中设计模式

    连表查询都用Left Join吧   最近看同事的代码,SQL连表查询的时候很多时候用的是Inner Join,而我觉得对我们的业务而言,99.9%都应该使用Left Join(还有0.1%我不知道在 ...

  5. ASP&period;NET中的Session怎么正确使用

    Session对象用于存储从一个用户开始访问某个特定的aspx的页面起,到用户离开为止,特定的用户会话所需要的信息.用户在应用程序的页面切换时,Session对象的变量不会被清除. 对于一个Web应用 ...

  6. ASP&period;NET中的Session怎么正确使用&lbrack;转&rsqb;

    Session对象用于存储从一个用户开始访问某个特定的aspx的页面起,到用户离开为止,特定的用户会话所需要的信息.用户在应用程序的页面切换时,Session对象的变量不会被清除. 对于一个Web应用 ...

  7. 【译文】漫谈ASP&period;NET中的Session

    最近这两天被一个Web Farm环境下的Session处理问题虐得很痛苦,网上到处找解决方案,在无意中翻看到这篇文章,感觉很不错,顺手查了一下,貌似没有现成的译文,于是一咬牙一跺脚把这篇文章翻译出来了 ...

  8. ASP&period;NET 中的 Session 怎么正确使用

    Session对象用于存储从一个用户开始访问某个特定的aspx的页面起,到用户离开为止,特定的用户会话所需要的信息.用户在应用程序的页面切换时,Session对象的变量不会被清除. 对于一个Web应用 ...

  9. ASP&period;NET错误处理的方式(总结)

    转载至: http://www.cnblogs.com/chinhr/archive/2007/06/26/795947.html ASP.NET错误处理的方式(整理&总结)英文文章研究:ht ...

随机推荐

  1. Jquery实现特效滑动菜单栏

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 第6章 Java类中的方法

    1.如何定义java的方法 什么是方法:方法使用来解决一类问题的代码集合,是一个功能模块在类中定义个方法的方法是: 访问修饰符 返回值类型 方法名(参数列表){ 方法体 } 1.访问修饰符,是限制该方 ...

  3. arrayToJson将数组转化为json格式的js代码 &sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;zzzzzzzzzzzzzzzz

    //去除空格 function trim(str) {   return str.replace(/\s|\xA0/g,""); } /** *js数组转json * */ fun ...

  4. CSS3动画(动画已丢,看原文)

    原文:http://ued.1905.com:8880/sample/css3/base/test.html CSS3动画 简要展示了CSS3常用动画效果,以及所使用代码. bounce 复制 展开代 ...

  5. HDU 2846:Repository(Trie)

    http://acm.hdu.edu.cn/showproblem.php?pid=2846 题意:给出N个模式串,再给出M个文本串,问每一个文本串在多少个模式串中出现. 思路:平时都是找前缀的,这里 ...

  6. django - from django&period;db&period;models import F - class F

    F() 的执行不经过 python解释器,不经过本机内存,是生成 SQL语句的执行. # Tintin filed a news story! reporter = Reporters.objects ...

  7. mac&lowbar;Alfred&lowbar;快捷设置

    1.安装(不说了去 Google 吧) 2.基础快捷键:option+space 3.打开应用程序:Alfred 几乎是一切程序的入口,你再也不需要找妈妈要开始菜单了.用快捷键呼出Alfred,输入任 ...

  8. stm32 硬件错误

    进入该模式,程序死机. 一般来说都是内存错误 1. 数组越界,装入数据溢出, 2. 堆和栈设置不当,这里面硬件的堆和栈在汇编文件中,如果有freertos等,重点检查,任务堆栈使用情况,一般任务堆栈溢 ...

  9. oracle 自动备份

    此次操作是每分钟备份一张表到新表(测试) 准备: 有一张表name是test 注意事项: 1.任务中调用需要显示声明权限 AUTHID CURRENT_USER 或赋予相应权限 2.单独调用过程成功, ...

  10. iconfont阿里巴巴矢量图标库批量保存

    F12输入——var iconList = document.querySelectorAll('.icon-gouwuche1');for (var i = 0; i < iconList.l ...