如何在.NET Core Razor Pages中获取已登录在线用户列表
基于Microsoft Identity 实现 Razor Pages 在线用户列表查询方案
核心逻辑是扩展Identity用户模型存储用户最后活跃时间,通过请求中间件自动更新该时间,最终通过查询指定时间范围内有活跃记录的已登录用户得到在线列表。
1. 扩展Identity用户实体,添加最后活跃时间字段
首先在你的自定义用户类中添加LastActiveAt属性,用于记录用户最后一次操作的时间:
// 你的自定义User类,继承自IdentityUser public class ApplicationUser : IdentityUser { // 存储UTC时间,避免时区问题 public DateTime LastActiveAt { get; set; } }
添加完成后在包管理控制台运行迁移命令更新数据库:Add-Migration AddLastActiveAtToUserUpdate-Database
2. 添加请求中间件自动更新用户活跃时间
新增中间件,在用户已登录的情况下每次请求都更新其最后活跃时间:
public class UpdateUserActiveTimeMiddleware { private readonly RequestDelegate _next; public UpdateUserActiveTimeMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context, UserManager<ApplicationUser> userManager) { // 只有已登录的用户才更新活跃时间 if (context.User.Identity?.IsAuthenticated == true) { var user = await userManager.GetUserAsync(context.User); if (user != null) { user.LastActiveAt = DateTime.UtcNow; await userManager.UpdateAsync(user); } } // 执行后续中间件逻辑 await _next(context); } }
在Program.cs中注册中间件,注意必须放在身份认证中间件之后,否则无法获取到已登录用户信息:
// 先注册身份认证相关中间件 app.UseAuthentication(); app.UseAuthorization(); // 再注册自定义的活跃时间更新中间件 app.UseMiddleware<UpdateUserActiveTimeMiddleware>();
3. 在线用户列表页面实现
后台PageModel代码
注入UserManager<ApplicationUser>,查询最近15分钟内有活跃记录的用户(15分钟为常规在线判定阈值,可自行调整):
public class OnlineUsersModel : PageModel { private readonly UserManager<ApplicationUser> _userManager; public OnlineUsersModel(UserManager<ApplicationUser> userManager) { _userManager = userManager; } // 存储在线用户列表供前端渲染 public List<ApplicationUser> OnlineUsers { get; set; } public async Task OnGetAsync() { var cutoffTime = DateTime.UtcNow.AddMinutes(-15); OnlineUsers = await _userManager.Users .Where(u => u.LastActiveAt >= cutoffTime) .ToListAsync(); } }
注意查询时需要引用
Microsoft.EntityFrameworkCore命名空间才能使用ToListAsync扩展方法。
前端Razor页面代码
遍历展示在线用户信息即可:
@page @model OnlineUsersModel <h1>当前在线用户</h1> <table class="table"> <thead> <tr> <th>用户名</th> <th>邮箱</th> </tr> </thead> <tbody> @foreach (var user in Model.OnlineUsers) { <tr> <td>@user.UserName</td> <td>@user.Email</td> </tr> } </tbody> </table>
可选优化
- 如果需要更高的实时性,可以结合SignalR实现:用户建立SignalR连接时更新活跃状态,断开连接时标记离线,适合需要秒级更新在线列表的场景。
- 高并发场景下可将活跃时间先存入Redis/内存缓存,定时批量同步到数据库,减少数据库写入压力。
内容的提问来源于stack exchange,提问作者مهدی
相关产品推荐
相关产品推荐

