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

ASP.NET Core 2如何获取所有活动会话?需展示登录用户(原ASP.NET方法无效)

Hey there! I totally get where you’re coming from—trying to pull up all logged-in users (active sessions) in ASP.NET Core 2, only to find the old ASP.NET method you found doesn’t work anymore. That’s super common because ASP.NET Core did a full rewrite of session management, ditching a lot of the old static collections like HttpContext.Current.Application["Sessions"].

No worries though—here’s a practical, working approach to track active users in ASP.NET Core 2:

解决方案:自定义活跃用户跟踪服务

Since ASP.NET Core doesn’t include a built-in way to list active sessions, we’ll build a custom service to track logged-in users, plus handle cleanup when sessions expire or users log out.

Step 1: Create an Active User Tracking Service

First, we’ll make a thread-safe service to store and manage active user data. We’ll use ConcurrentDictionary to avoid race conditions since multiple requests will access this service.

// Define a model to hold active user details
public class ActiveUser
{
    public string SessionId { get; set; }
    public string UserId { get; set; }
    public string UserName { get; set; }
    public DateTime LoginTime { get; set; }
}

// Interface for the service (good for dependency injection and testing)
public interface IActiveUserService
{
    void AddActiveUser(string sessionId, string userId, string userName);
    void RemoveActiveUser(string sessionId);
    IEnumerable<ActiveUser> GetAllActiveUsers();
}

// Concrete implementation of the service
public class ActiveUserService : IActiveUserService
{
    private readonly ConcurrentDictionary<string, ActiveUser> _activeUsers = new();

    public void AddActiveUser(string sessionId, string userId, string userName)
    {
        _activeUsers.TryAdd(sessionId, new ActiveUser
        {
            SessionId = sessionId,
            UserId = userId,
            UserName = userName,
            LoginTime = DateTime.UtcNow
        });
    }

    public void RemoveActiveUser(string sessionId)
    {
        _activeUsers.TryRemove(sessionId, out _);
    }

    public IEnumerable<ActiveUser> GetAllActiveUsers()
    {
        return _activeUsers.Values;
    }
}

Step 2: Register the Service in Startup

We need to register this service as a singleton so it’s shared across the entire application:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // ... other service registrations (like Identity, MVC)

        // Register our active user service as a singleton
        services.AddSingleton<IActiveUserService, ActiveUserService>();

        // Enable session support (required to get SessionId)
        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromMinutes(30); // Match your session timeout
            options.Cookie.HttpOnly = true;
            options.Cookie.IsEssential = true;
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // ... other middleware (like error handling, static files)

        // Use session middleware (must come before MVC)
        app.UseSession();
        app.UseMvcWithDefaultRoute();
    }
}

Step 3: Track Users on Login/Logout

Update your login and logout actions to add/remove users from the service:

Login Action

public class AccountController : Controller
{
    private readonly IActiveUserService _activeUserService;
    private readonly SignInManager<IdentityUser> _signInManager;
    private readonly UserManager<IdentityUser> _userManager;

    public AccountController(IActiveUserService activeUserService,
                             SignInManager<IdentityUser> signInManager,
                             UserManager<IdentityUser> userManager)
    {
        _activeUserService = activeUserService;
        _signInManager = signInManager;
        _userManager = userManager;
    }

    [HttpPost]
    public async Task<IActionResult> Login(LoginViewModel model)
    {
        if (ModelState.IsValid)
        {
            var result = await _signInManager.PasswordSignInAsync(
                model.UserName, 
                model.Password, 
                model.RememberMe, 
                lockoutOnFailure: false);

            if (result.Succeeded)
            {
                // Get the current session ID and user details
                var sessionId = HttpContext.Session.Id;
                var user = await _userManager.FindByNameAsync(model.UserName);
                
                // Add the user to our active list
                _activeUserService.AddActiveUser(sessionId, user.Id, user.UserName);

                return RedirectToAction("Index", "Home");
            }
            ModelState.AddModelError("", "Invalid login attempt.");
        }
        return View(model);
    }
}

Logout Action

[HttpPost]
public async Task<IActionResult> Logout()
{
    // Remove the user from active list before signing out
    var sessionId = HttpContext.Session.Id;
    _activeUserService.RemoveActiveUser(sessionId);

    await _signInManager.SignOutAsync();
    return RedirectToAction("Index", "Home");
}

Step 4: Clean Up Expired Sessions

ASP.NET Core doesn’t have a built-in Session_End event, so we’ll add a background service to periodically remove users whose sessions have expired:

public class SessionCleanupService : IHostedService, IDisposable
{
    private readonly IActiveUserService _activeUserService;
    private Timer _cleanupTimer;
    private readonly TimeSpan _sessionTimeout = TimeSpan.FromMinutes(30); // Match your session timeout

    public SessionCleanupService(IActiveUserService activeUserService)
    {
        _activeUserService = activeUserService;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // Run cleanup every 5 minutes (adjust as needed)
        _cleanupTimer = new Timer(CleanupExpiredSessions, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));
        return Task.CompletedTask;
    }

    private void CleanupExpiredSessions(object state)
    {
        var activeUsers = _activeUserService.GetAllActiveUsers().ToList();
        foreach (var user in activeUsers)
        {
            // Check if the session has expired
            if (user.LoginTime.Add(_sessionTimeout) < DateTime.UtcNow)
            {
                _activeUserService.RemoveActiveUser(user.SessionId);
            }
        }
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _cleanupTimer?.Change(Timeout.Infinite, 0);
        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _cleanupTimer?.Dispose();
    }
}

Register this background service in Startup.cs:

services.AddHostedService<SessionCleanupService>();

Step 5: Display Active Users

Now you can inject IActiveUserService into any controller or view to show the list of logged-in users:

public class HomeController : Controller
{
    private readonly IActiveUserService _activeUserService;

    public HomeController(IActiveUserService activeUserService)
    {
        _activeUserService = activeUserService;
    }

    public IActionResult ActiveUsers()
    {
        var activeUsers = _activeUserService.GetAllActiveUsers();
        return View(activeUsers);
    }
}

For Multi-Server Deployments

If your app runs on multiple servers, the in-memory ConcurrentDictionary won’t work (each server will have its own list). Instead, use a distributed cache like Redis or SQL Server to store active user data. You’d modify ActiveUserService to use IDistributedCache instead of the in-memory dictionary, serializing/deserializing the ActiveUser objects.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:46:32