在 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. DEPRECATED: Use of this script to execute hdfs command is deprecated.

    DEPRECATED: Use of this script to execute hdfs command is deprecated. 本人安装的hadoop版本是2.4.0的,但每次执行命令时都 ...

  2. 对html进行SEO的一点点总结

    1. 要考虑用户用哪些关键在查找您的网页 2. SE无法识别图形中的内容 3. 确保title和alt中的内容准确 4. 尽量用静态页,如果是动态页,参数要少 5. 每个图片都尽量用alt 6. 不用 ...

  3. treeview 点击时选中节点

    private void tv_WebList_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { Point clickPo ...

  4. mysql sql灵活运用

    1.mysq获取表的字段及属性 SELECT * FROM information_schema.COLUMNS WHERE table_name = 'item_url'; 2.正则表达式 SELE ...

  5. No Pain No Game

    hdu4630:http://acm.hdu.edu.cn/showproblem.php?pid=4630 题意:给定一个排序,求区间最大GCD. 题解:离散树状数组.首先把查询按左端点从大到小排序 ...

  6. android TabActivity的局限性 是否还有存在的必要性

     TabActivity的局限性 是否还有存在的必要性 其实谷歌有此举动,我们也应该早就想到了,为什么会这么说呢?那就要从TabActivity的原理开始说起了. 做个假定先: 比如我们最外面的Act ...

  7. C调用OPENSSL做REST服务客户端的例子

    //SSL-Client.c #include <stdio.h> #include <errno.h> #include <unistd.h> #include ...

  8. java复制文件的4种方式

    尽管Java提供了一个可以处理文件的IO操作类.但是没有一个复制文件的方法.复制文件是一个重要的操作,当你的程序必须处理很多文件相关的时候.然而有几种方法可以进行Java文件复制操作,下面列举出4中最 ...

  9. tbody添加垂直滚动条

    法一: 用2个table: <table width="300" border="0" cellpadding="0" cellspa ...

  10. matlab安装和入门

    下载iso镜像: ISO镜像下载地址链接: http://pan.baidu.com/s/1i31bu5J 密码: obo1 单独破解文件下载链接: http://pan.baidu.com/s/1c ...