最近在做微信公众号,经理提出当用户关注公众号后并绑定则把用户的绑定信息写到表中,如果取消关注从表中把用户信息删除。一开始感觉很简单,微信推送给服务器的事件中包含有用户的openid。用openid查询用户信息后,再写到表中就行。用户绑定登录后,需要将用户信息放到缓存中,这样用户就不用每次都登录。问题来了,用户取消关注后,再次访问上一个页面还有以前的用户信息,又不能贸然清空缓存。后来查看微软已公开的源码,发现有根据id清除缓存的方法,不过需要反射调用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using System.Web.SessionState;
using System.Threading;
using System.Collections.Concurrent;
namespace TestProject.TestCode
{
public static class SessionHelper
{
private readonly static ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
#region ConcurrentDictionary
private static bool _initialize;
private static ConcurrentDictionary<string, string> _dic = null;
private static object _lock = new object();
private static ConcurrentDictionary<string, string> sessionDic
{
get
{
return LazyInitializer.EnsureInitialized<ConcurrentDictionary<string, string>>(ref _dic, ref _initialize, ref _lock, () =>
new ConcurrentDictionary<string, string>());
}
}
#endregion
#region SessionStateStoreProviderBase
private static bool _initializeStore;
private static SessionStateStoreProviderBase _store;
private static object _lockStore = new object();
private static SessionStateStoreProviderBase SessionStore
{
get
{
return LazyInitializer.EnsureInitialized<SessionStateStoreProviderBase>(ref _store, ref _initializeStore, ref _lockStore, () =>
{
IHttpModule module = HttpContext.Current.ApplicationInstance.Modules["Session"];
return module.GetType()
.GetField("_store", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(module) as SessionStateStoreProviderBase;
});
}
}
#endregion
public static SessionStateStoreData GetSession(string id)
{
if (string.IsNullOrEmpty(id)) return null;
if (SessionStore != null)
{
bool isLock = false;
object lockId = new object();
TimeSpan lockAge = TimeSpan.Zero;
SessionStateActions state = SessionStateActions.InitializeItem;
return SessionStore.GetItem(HttpContext.Current, id, out isLock, out lockAge, out lockId, out state);
}
return null;
}
public static void RemoveSession(string id)
{
if (SessionStore != null)
{
SessionStore.RemoveItem(HttpContext.Current, id, 0, null);
}
}
public static string GetSessionId(string openId)
{
string sessionId = null;
return sessionDic.TryGetValue(openId, out sessionId) ? sessionId : null;
}
public static bool AddOrUpdate(string openId)
{
string sessionId = null;
if (HttpContext.Current.Session != null)
{
sessionId = HttpContext.Current.Session.SessionID;
}
if (string.IsNullOrEmpty(sessionId)) return false; ;
return sessionDic.AddOrUpdate(openId, sessionId, (id, val) => val) == sessionId;
}
}
}