.NET下Session使用很简单,对写入Session值无类型限制,设置Session有效时间也很简单,直接设置Session的timeout属性即可,类型为int,单位为分钟。
1 Session["time"] = DateTime.Now.ToString("yyyymmddHHMMss"); 2 Session.Timeout = 60;
但若要设置多个有效时间不同的Session,就不那么友好了。后设置的有效时间会覆盖之前值。
1 //写入用户登录状态到Session。 2 Session["state"] = "On"; 3 //设置用户登录状态有效时间为1天,除非登录清空Session,否则整天登录状态有效。 4 Session.Timeout = 60 * 24; 5 6 //设置类似验证码类似的session,假设有效时间为1分钟。 7 Session["time"] = DateTime.Now.ToString("yyyymmddHHMMss"); 8 Session.Timeout = 1;
如上,设置了两个Session,两个Session有效时间不同,后写入Session有效时间一定会覆盖前面写入Session有效时间。
简易解决思路
构建结构为:
1 Tuple.Create<string, object, int>(key, value, time)
的tuple元组,将tuple写入Session中。(按照顺序依次代表session名、写入值、有效时间)
1 private void SetSingleSession(string key , object value, int? timeout) 2 { 3 int time = timeout ?? Session.Timeout; 4 var tuple = Tuple.Create<string, object, int>(key, value, time); 5 Session[key] = tuple; 6 }
但这样设置存在一个问题,的确写入值到Session,但并没有实现Session的功能。
也就是说,这个Session有效时间并不会到达有效时间后就失效!!!这很关键,怎么办呢?有个关键点必须注意到,一定不能修改Session的timeout参数。
在此考虑的替代方案是:写入时根据传入有效时间计算出过期时间,将过期时间存入,获取Session时判断是否已经超过过期截止时间,超过返回空,并且清空Session。
重写SetSingleSession方法
1 private void SetSingleSession(string key, object value, int? timeout) 2 { 3 int time = timeout ?? Session.Timeout; 4 DateTime endTime = DateTime.Now + new TimeSpan(0,time,0); 5 var tuple = Tuple.Create(key, value, endTime); 6 Session[key] = tuple; 7 }
获取Session方法
1 private object GetSingleSession(string key) 2 { 3 var tuple = Session[key] as Tuple<string, object, DateTime>; 4 var diff = DateTime.Compare(tuple.Item3, DateTime.Now); 5 object result = null; 6 if (diff > 0) result = tuple.Item2;//有效时间截止之前正常返回值 7 else Session.Remove(key);//超过有效时间清空Session 8 return result; 9 }
只是一个基础的方案,后续有更好的方案再更新。