I have implemented the code for reading the active sessions using the reference Reading All Users Session and Get a list of all active sessions in ASP.NET.
Private List<String> getOnlineUsers()
{
List<String> activeSessions = new List<String>();
object obj = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
object[] obj2 = (object[])obj.GetType().GetField("_caches", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj);
for (int i = 0; i < obj2.Length; i++)
{
Hashtable c2 = (Hashtable)obj2[i].GetType().GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj2[i]);
foreach (DictionaryEntry entry in c2)
{
object o1 = entry.Value.GetType().GetProperty("Value", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(entry.Value, null);
if (o1.GetType().ToString() == "System.Web.SessionState.InProcSessionState")
{
SessionStateItemCollection sess = (SessionStateItemCollection)o1.GetType().GetField("_sessionItems", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(o1);
if (sess != null)
{
if (sess["loggedInUserId"] != null)
{
activeSessions.Add(sess["loggedInUserId"].ToString());
}
}
}
}
}
return activeSessions;
}
It is working fine in local system (in windows XP and Windows 7). While I hosted the application in Windows server 2003 (IIS version 6), it gives an NULL object reference error in the line
object[] obj2 = (object[])obj.GetType().GetField("_caches", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj);
Is this anything related to the permission issue or trust level settings related to IIS? Please let know anyone came across such an issue. Any help is highly appreciable.
I've tried Paully's solution, which didn't compile in some points and lead to runtime errors in others. Anyway, inspired on his suggestion (thanks a lot! My vote goes for that), I came to my own, which compiles and gets me the expected data.
Also, I'm returning a IEnumerable and I'm using "yield return", which makes it more performatic for big lists (kind of lazy loading of data). Here it goes:
Exactly for your business case there is Application state variable in asp.net. It is similar to session state, but visible for all users request.
I know this is an old thread, but this may save someone some time. Another thing to check is that obj is of type System.Web.Caching.CacheMultiple. I had this same problem and it was a platform-specific issue as Marc Gravell suggested. It turned out that on the Windows 2003 server, obj was type System.Web.Caching.CacheSingle and there was a null reference exception when trying to get the value for "_caches".
If that is the case, you can still get a list of active sessions with
(Hashtable)obj.GetType().GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj);
Try using this, _cachesRefs if _caches is NULL. The function below will return all user sessions collections for all multiple versions of Windows and including Windows Server.
It works.
}
It sounds like a different version (or update) of .NET is running on 2003 than you have on XP / Win7, although it could also just be a platform-specific difference. If it was permissions / trust, you would have seen an exception. Instead, it seems more likely that simply:
_caches
does not exist on whatever version is on the 2003 machine. If you use reflection to access private state: you should entirely expect it to explode between versions / updates / platforms / at-whim / etc.To investigate:
obj
isnull
obj.GetType().GetField("_caches", BindingFlags.NonPublic | BindingFlags.Instance)
isnull
(either of those things could cause this exception on the line you cite)