在 Asp.net Mvc 自定义Session (一)中我们把数据缓存工具类写好了,今天在我们在这篇把 剩下的自定义Session写完

  首先还请大家跟着我的思路一步步的来实现,既然我们要自定义Session肯定要继承和重写什么东东(因为在框架设计中肯定考虑这些东西,asp.net mvc 架构师不傻的),好吧 确实要继承 SessionStateStoreProviderBase 这个基类。下面我先把代码贴出来,在慢慢解释

  

/// <summary>
/// 分布式session
/// </summary> public class ClusterSessionStoreProvider : SessionStateStoreProviderBase
{
private CacheManager _Client = CacheManager.Instance; private static readonly int _DefaultSessionExpireMinute = ;
private int _timeout; /// <summary>
/// 构造函数
/// </summary>
public ClusterSessionStoreProvider()
{
}
/// <summary>
/// 请求初始化的时候
/// </summary>
/// <param name="context"></param>
public override void InitializeRequest(HttpContext context)
{ } public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
// string applicationVirtualPath = AppDomain.CurrentDomain.BaseDirectory; if (string.IsNullOrWhiteSpace(config["timeout"]))
{
this._timeout = _DefaultSessionExpireMinute;
}
else
{
this._timeout = Convert.ToInt32(config["timeout"]);
}
}
public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
{
return new SessionStateStoreData(new SessionStateItemCollection()
, SessionStateUtility.GetSessionStaticObjects(context), timeout);
} /// <summary>
///将新的会话状态添加到数据区中
/// </summary>
/// <param name="context"></param>
/// <param name="id"></param>
/// <param name="timeout"></param>
public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
{
SessionDataObject sessionObject = new SessionDataObject
{
Content = null,
Locked = false,
SetTime = DateTime.Now,
LockId = ,
ActionFlag =
};
_Client.Put(id, sessionObject, timeout);
} public override void Dispose()
{
//调用dispose 需要的操作
} public override void EndRequest(HttpContext context)
{
//请求结束时调用
}
public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
SessionStateStoreData sessionStateStoreDate = null;
SessionDataObject memcachedSessionObject = null;
DateTime setTime = DateTime.Now; lockAge = TimeSpan.Zero;
lockId = null;
locked = false;
actions = SessionStateActions.None;
memcachedSessionObject = _Client.Get(id) as SessionDataObject; if (memcachedSessionObject != null)
{
//如果已经锁定
if (memcachedSessionObject.Locked)
{
lockAge = memcachedSessionObject.LockAge;
lockId = memcachedSessionObject.LockId;
locked = memcachedSessionObject.Locked;
actions = (SessionStateActions)memcachedSessionObject.ActionFlag;
return sessionStateStoreDate;
} memcachedSessionObject.LockId++;
memcachedSessionObject.SetTime = setTime;
_Client.Put(id, memcachedSessionObject); actions = (SessionStateActions)memcachedSessionObject.ActionFlag;
lockId = memcachedSessionObject.LockId;
lockAge = memcachedSessionObject.LockAge; if (actions == SessionStateActions.InitializeItem)
{
sessionStateStoreDate = this.CreateNewStoreData(context, _timeout);
}
else
{
sessionStateStoreDate = this.Deserialize(context, memcachedSessionObject.Content, _timeout);
}
return sessionStateStoreDate;
}
return sessionStateStoreDate;
} //从缓冲区中读取只读属性
public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
return GetItem(context, id, out locked, out lockAge, out lockId, out actions);
} //释放锁定
public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
{
SessionDataObject memcachedSessionObject = _Client.Get(id) as SessionDataObject;
if (memcachedSessionObject != null)
{
memcachedSessionObject.Locked = false;
memcachedSessionObject.LockId = (Int32)lockId;
_Client.Put(id, memcachedSessionObject, _timeout);
}
}
//删除缓存数据
public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
{
_Client.Delete(id);
} public override void ResetItemTimeout(HttpContext context, string id)
{
object obj = _Client.Get(id);
if (obj != null)
{
_Client.Put(id, obj, _timeout);
}
}
//更新值
public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
{
DateTime setTime = DateTime.Now;
byte[] bytes = this.Serialize((SessionStateItemCollection)item.Items);
SessionDataObject memcachedSessionObject = new SessionDataObject()
{
LockId = ,
Locked = false,
Content = bytes,
ActionFlag = ,
SetTime = setTime
};
_Client.Put(id, memcachedSessionObject, item.Timeout);
} public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
{
return false;
} private SessionStateStoreData Deserialize(HttpContext context, byte[] bytes, int timeout)
{
MemoryStream stream = new MemoryStream(bytes); SessionStateItemCollection collection = new SessionStateItemCollection();
if (stream.Length > )
{
BinaryReader reader = new BinaryReader(stream);
collection = SessionStateItemCollection.Deserialize(reader);
}
return new SessionStateStoreData(collection, SessionStateUtility.GetSessionStaticObjects(context), timeout);
} private byte[] Serialize(SessionStateItemCollection items)
{
MemoryStream ms = new MemoryStream();
BinaryWriter writer = new BinaryWriter(ms);
if (items != null)
items.Serialize(writer); writer.Close();
return ms.ToArray();
} }

  


  1.   在代码中有一个SessionDataObject类,这个类是存储Session的一些基本信息,以保证访问时还能取得上次设置的值(这个类一定要序列还 不然嘻嘻。。)

   这个类的代码如下:

  

    [Serializable]
public class SessionDataObject
{
public byte[] Content { get; set; }
public bool Locked { get; set; }
public DateTime SetTime { get; set; }
public int LockId { get; set; }
public int ActionFlag { get; set; }
public TimeSpan LockAge { get; set; }
}

  2.  增删改查都要重写,如 GetItemExclusive  重写这个方法时,每次获取session(如:session['test'])都会调用这个方法,你根据sessionId往 缓存工具类中读取返回就行

  3.  重写完了指定方法后,要在配置文件中加上,才能使用

 /************************************************
*
* <sessionState mode="Custom" customProvider="SessionProvider" >
<providers>
<add name="SessionProvider" type="NanHuaDDD.ClusterSession.ClusterSessionStoreProvider,NanHuaDDD" timeout="1" accessKey="你好" />
</providers>
*
* ******************************************************************/

  到这里 我就不一 一列出每个方法的意思了,差不多大家一看方法名就知道,分布式用的是memcache,如果在后面系统升级,要求集群是不是很方便啊

  如果有什么疑问可以联系我 QQ:209229923

  

Asp.net Mvc 自定义Session (二)的更多相关文章

  1. Asp.net Mvc 自定义Session (一),

    大家都知道用系统默认的session 会存在这样的问题 如果用户过多的话 session 会自动消亡,而且不能支持分布式和集群. 这系列博客主要讲解  怎样 解决用户过多的session自动消亡,和分 ...

  2. ASP.NET MVC 自定义Razor视图WorkContext

    概述 1.在ASP.NET MVC项目开发的过程中,我们经常需要在cshtml的视图层输出一些公用信息 比如:页面Title.服务器日期时间.页面关键字.关键字描述.系统版本号.资源版本号等 2.普通 ...

  3. ASP.NET MVC Model验证(二)

    ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...

  4. ASP.NET MVC Model绑定(二)

    ASP.NET MVC Model绑定(二) 前言 上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程 ...

  5. ASP.NET MVC Model元数据(二)

    ASP.NET MVC Model元数据(二) 前言 在上篇中,给大家留个对Model元数据的印象,并没有对Model元数据有过多的讲解,而在本篇中也不会对Model元数据的本身来解释,而是针对于它的 ...

  6. 表现层及ASP.NET MVC介绍(二)

    表现层及ASP.NET MVC介绍(二) 最近的更新速度越来越慢,主要是项目上比较忙,封装EasyUi也要花很多时间.不过大家请放心,本系列不会半途夭折,并且代码干货也会持续更新.本文继续介绍表现层和 ...

  7. 转载ASP.NET MVC中Session的处理机制

    本文章转载自 http://www.cnblogs.com/darrenji/p/3951065.html ASP.NET MVC中的Session以及处理方式   最近在ASP.NET MVC项目中 ...

  8. ASP.NET MVC 描述类型(二)

    ASP.NET MVC 描述类型(二) 前言 上个篇幅中说到ControllerDescriptor类型的由来过程,对于ControllerDescriptor类型来言ActionDescriptor ...

  9. ASP.NET MVC 控制器激活(二)

    ASP.NET MVC 控制器激活(二) 前言 在之前的篇幅中,用文字和图像来表示了控制器的激活过程,描述的角度都是从框架默认实现的角度去进行描述的,这样也使得大家都可以清楚的知道激活的过程以及其中涉 ...

随机推荐

  1. 防止横竖屏时,iphone自动缩放的一段js代码

    function orientation_change() {     var viewport = document.querySelector('meta[name="viewport& ...

  2. [BZOJ 3774] 最优选择 【最小割】

    题目链接:BZOJ - 3774 题目分析 此题与“文理分科”那道题目有些类似.都是使用最小割来求解,先加上可能获得的权值,在减掉必须舍弃的权值(最小割). 文理分科是规定每个人和 S 连就是选文,和 ...

  3. ubuntu下的翻译软件goldendict

    转自ubuntu下的翻译软件 看着一些API虽然能看懂一个大概,但总想知道每个单词的意思.问题是英语水平有限,所以只能来找一些翻译软件,像windows下来用的有道估计是不行了(也没去试到定行不行), ...

  4. 李洪强iOS开发之-环信04_消息

    李洪强iOS开发之-环信04_消息 消息:IM 交互实体,在 SDK 中对应的类型是 EMMessage.EMMessage 由 EMMessageBody 组成. 构造消息   构造文字消息 EMT ...

  5. [codility]Prefix-set

    这题很简单,一开始用了set.但后来一想这样其实是n*logn的,而且没有利用所有的数都在0..N-1之间.那么可以直接用vector当hashset. // you can also use inc ...

  6. thinkphp 调用函数

    1,定义为Common.php文件.自动加载. 2,配置文件config.php文件里配置'LOAD_EXT_FILE'=>'function'.则会自动加载function.php文件 3,使 ...

  7. Android 自定义对话框(Dialog)位置,大小

    代码: package angel.devil; import android.app.Activity; import android.app.Dialog; import android.os.B ...

  8. Android:MD5加密

    /** * @author gongchaobin * * MD5加密 * * @version 2013-8-22 */ public class MD5Util { // 用来将字节转换成 16 ...

  9. 为什么要重写equals()方法与hashCode()方法

    在java中,所有的对象都是继承于Object类.Ojbect类中有两个方法equals.hashCode,这两个方法都是用来比较两个对象是否相等的. 在未重写equals方法我们是继承了object ...

  10. 理解Java ClassLoader机制

    当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构: bootstrap classloader                |       extension cla ...