You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ASP.NET应用获取IIS中所有Session变量的值?

获取ASP.NET中所有活跃Session及用户信息的解决方案

针对你无法追踪用户直接关闭浏览器的退出行为、需要统计活跃用户的需求,以下是几种可行的实现方式:

一、自定义全局用户Session跟踪(推荐生产环境使用)

放弃依赖ASP.NET默认的Session集合,自己维护一个线程安全的全局映射表,全程跟踪用户的Session生命周期:

  1. 定义全局跟踪类和用户Session信息模型:
using System.Collections.Concurrent;
using System;

public static class ActiveUserTracker
{
    // 用SessionID作为键,存储用户核心信息
    public static ConcurrentDictionary<string, UserSessionDetail> ActiveSessions = new ConcurrentDictionary<string, UserSessionDetail>();
}

public class UserSessionDetail
{
    public string UserId { get; set; }
    public string Username { get; set; }
    public DateTime LoginTime { get; set; }
    public DateTime LastActiveTime { get; set; }
}
  1. 在用户登录成功时,将信息加入全局表:
// 假设登录验证通过后执行
var sessionInfo = new UserSessionDetail
{
    UserId = "user123",
    Username = "JohnDoe",
    LoginTime = DateTime.Now,
    LastActiveTime = DateTime.Now
};
ActiveUserTracker.ActiveSessions.TryAdd(Session.SessionID, sessionInfo);
  1. 在Global.asax中处理Session销毁和用户活跃更新:
void Session_End(object sender, EventArgs e)
{
    // InProc模式下Session超时会触发该事件,移除对应记录
    ActiveUserTracker.ActiveSessions.TryRemove(Session.SessionID, out _);
}

void Application_BeginRequest(object sender, EventArgs e)
{
    // 每次请求更新用户最后活跃时间
    if (Session != null && ActiveUserTracker.ActiveSessions.ContainsKey(Session.SessionID))
    {
        var sessionInfo = ActiveUserTracker.ActiveSessions[Session.SessionID];
        sessionInfo.LastActiveTime = DateTime.Now;
        // 因为是引用类型,无需重新加入字典
    }
}
  1. 获取所有活跃用户:
public List<UserSessionDetail> GetCurrentActiveUsers()
{
    // 过滤掉超过Session超时时间的用户(示例超时20分钟)
    var timeout = TimeSpan.FromMinutes(20);
    return ActiveUserTracker.ActiveSessions.Values
        .Where(u => DateTime.Now - u.LastActiveTime <= timeout)
        .ToList();
}

二、InProc模式下直接遍历Session(仅限单服务器/调试)

如果你的应用使用默认的InProc Session存储,可以通过反射访问内部Session集合,但这依赖ASP.NET未公开的内部实现,版本更新可能失效,不建议生产环境使用:

using System.Reflection;
using System.Web.SessionState;
using System.Collections.Generic;

public List<string> GetAllActiveSessionIds()
{
    var appInstance = HttpContext.Current.ApplicationInstance;
    var sessionModule = typeof(HttpApplication).GetField("_sessionStateModule", BindingFlags.NonPublic | BindingFlags.Instance)
        .GetValue(appInstance) as SessionStateModule;
    
    var sessionStore = sessionModule.GetType().GetField("_store", BindingFlags.NonPublic | BindingFlags.Instance)
        .GetValue(sessionModule);
    
    var getAllSessionsMethod = sessionStore.GetType().GetMethod("GetAllSessionIds", BindingFlags.Public | BindingFlags.Instance);
    var sessionIds = getAllSessionsMethod.Invoke(sessionStore, null) as string[];
    
    return sessionIds?.ToList() ?? new List<string>();
}

三、StateServer/SQL Server Session存储场景的处理

  • StateServer:可以通过Windows性能计数器查看活跃Session总数,但要获取具体用户信息,需要自行实现Socket通信读取StateServer数据(无官方API,复杂度高),建议结合自定义跟踪方案。
  • SQL Server:Session数据存储在ASPStateTempSessions表中,可直接查询超时时间内的Session,再反序列化获取用户信息:
    1. 查询活跃Session的SQL:
    SELECT SessionId, SessionItemShort, Expires FROM ASPStateTempSessions WHERE Expires > GETDATE()
    
    1. 反序列化Session数据:
    using System.Web.SessionState;
    using System.IO;
    
    public string GetUserIdFromSessionData(byte[] serializedData)
    {
        using var ms = new MemoryStream(serializedData);
        using var reader = new BinaryReader(ms);
        var sessionItems = SessionStateItemCollection.Deserialize(reader);
        return sessionItems["UserId"]?.ToString();
    }
    

注意事项

  • 多服务器负载均衡场景下,InProc模式不可用,必须使用StateServer/SQL Server或分布式缓存(如Redis)存储Session和跟踪信息。
  • 全局跟踪表要考虑内存占用,定期清理超时的Session记录。
  • Session超时时间需与IIS站点设置保持一致,避免统计误差。

内容的提问来源于stack exchange,提问作者Tim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:55:28