6

参照ReadingAllUsers Sessionを使用してアクティブなセッションを読み取るためのコードを実装し、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;
}

ローカルシステム(WindowsXPおよびWindows7)では正常に動作しています。Windows Server 2003(IISバージョン6)でアプリケーションをホストしているときに、行にNULLオブジェクト参照エラーが表示されます

object[] obj2 = (object[])obj.GetType().GetField("_caches", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(obj);

これは、IISに関連するアクセス許可の問題または信頼レベルの設定に関連するものですか?誰かがそのような問題に遭遇したことを知らせてください。どんな助けでも非常に高く評価されます。

4

6 に答える 6

3

Paully のソリューションを試してみましたが、いくつかの点でコンパイルされず、他の点で実行時エラーが発生しました。とにかく、彼の提案に触発されて (どうもありがとう! 私の投票はそれに賛成です)、私は自分の考えにたどり着き、コンパイルして期待されるデータを取得しました。

また、私は IEnumerable を返し、「yield return」を使用しています。これにより、大きなリスト (データの遅延読み込みのようなもの) のパフォーマンスが向上します。ここに行きます:

public static System.Collections.Generic.IEnumerable<SessionStateItemCollection> GetAllUserSessions()
{
    List<Hashtable> hTables = new List<Hashtable>();
    object obj = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
    dynamic fieldInfo = obj.GetType().GetField("_caches", BindingFlags.NonPublic | BindingFlags.Instance);

    //If server uses "_caches" to store session info
    if (fieldInfo != null)
    {
        object[] _caches = (object[])fieldInfo.GetValue(obj);
        for (int i = 0; i <= _caches.Length - 1; i++)
        {
            Hashtable hTable = (Hashtable)_caches[i].GetType().GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_caches[i]);
            hTables.Add(hTable);
        }
    }
    //If server uses "_cachesRefs" to store session info
    else
    {
        fieldInfo = obj.GetType().GetField("_cachesRefs", BindingFlags.NonPublic | BindingFlags.Instance);
        object[] cacheRefs = fieldInfo.GetValue(obj);
        for (int i = 0; i <= cacheRefs.Length - 1; i++)
        {
            var target = cacheRefs[i].GetType().GetProperty("Target").GetValue(cacheRefs[i], null);
            Hashtable hTable = (Hashtable)target.GetType().GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(target);
            hTables.Add(hTable);
        }
    }

    foreach (Hashtable hTable in hTables)
    {
        foreach (DictionaryEntry entry in hTable)
        {
            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)
                     yield return sess;
            }
        }
    }
}
于 2016-09-10T04:04:06.333 に答える
1

_caches が NULL の場合は、_cachesRefs を使用してみてください。以下の関数は、Windows Server を含むすべての複数バージョンの Windows のすべてのユーザー セッション コレクションを返します。

できます。

public List<SessionStateItemCollection> GetAllUserSessions() {

List<Hashtable> hTables = new List<Hashtable>();

PropertyInfo propInfo = typeof(HttpRuntime).GetProperty("CacheInternal", BindingFlags.NonPublic | BindingFlags.Static);

object CacheInternal = propInfo.GetValue(null, null);

dynamic fieldInfo = CacheInternal.GetType().GetField("_caches", BindingFlags.NonPublic | BindingFlags.Instance);

if (fieldInfo != null) {
    object[] _caches = (object[])fieldInfo.GetValue(CacheInternal);
    for (int i = 0; i <= _caches.Length - 1; i++) {
        Hashtable hTable = (Hashtable)_caches(i).GetType().GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_caches(i));
        hTables.Add(hTable);
    }
} else {
    fieldInfo = CacheInternal.GetType().GetField("_cachesRefs", BindingFlags.NonPublic | BindingFlags.Instance);
    dynamic cacheRefs = fieldInfo.GetValue(CacheInternal);
    foreach (void cacheRef_loopVariable in cacheRefs) {
        cacheRef = cacheRef_loopVariable;
        dynamic target = cacheRef.Target;
        fieldInfo = target.GetType().GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance);
        Hashtable hTable = fieldInfo.GetValue(target);
        hTables.Add(hTable);
    }
}

List<SessionStateItemCollection> sessionlist = new List<SessionStateItemCollection>();

foreach (void hTable_loopVariable in hTables) {
    hTable = hTable_loopVariable;
    foreach (DictionaryEntry entry in hTable) {
        object value = entry.Value.GetType().GetProperty("Value", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(entry.Value, null);
        if (value.GetType().ToString() == "System.Web.SessionState.InProcSessionState") {
            SessionStateItemCollection sCollection = (SessionStateItemCollection)value.GetType().GetField("_sessionItems", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(value);
            if (sCollection != null)
                sessionlist.Add(sCollection);
        }
    }
}

return sessionlist;

}

于 2016-04-27T10:32:03.160 に答える
0

まさにあなたのビジネスケースのために、asp.netにアプリケーション状態変数があります。これはセッション状態に似ていますが、すべてのユーザーの要求に対して表示されます。

于 2012-11-19T07:11:28.553 に答える
0

プラットフォーム固有の違いである可能性もありますが、XP / Win7 とは異なるバージョン (または更新) の .NET が 2003 で実行されているようです。アクセス許可/信頼の場合は、例外が表示されます。代わりに、単純に: 2003 マシン上のどのバージョンにも_caches 存在しない可能性が高いようです。リフレクションを使用してプライベートな状態にアクセスする場合: バージョン / 更新 / プラットフォーム / 気まぐれ / などの間で爆発することを完全に予期する必要があります。

調べる:

  • かどうかを確認しobjますnull
  • かどうかを確認しobj.GetType().GetField("_caches", BindingFlags.NonPublic | BindingFlags.Instance)ますnull

(これらのいずれかが、引用した行でこの例外を引き起こす可能性があります)

于 2012-11-19T07:07:12.020 に答える