求ASP.NET Core 2.2网站访客统计计数器实现方案
ASP.NET Core 2.2 访客统计完整实现方案
下面是适配ASP.NET Core 2.2的访客统计实现,包含在线人数、今日访问量、当月访问量、总访问量四个功能,替代你提供的ASP.NET MVC Global.asax逻辑:
1. 核心中间件实现
中间件负责处理每个请求的统计逻辑,替代原Global.asax的请求拦截:
using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; using System.Threading.Tasks; public class VisitorCounterMiddleware { private readonly RequestDelegate _next; private readonly IMemoryCache _cache; public VisitorCounterMiddleware(RequestDelegate next, IMemoryCache cache) { _next = next; _cache = cache; } public async Task InvokeAsync(HttpContext context) { var today = DateTime.Today; var currentMonth = new DateTime(today.Year, today.Month, 1); const string visitorIdCookie = "VisitorId"; const string lastVisitCookie = "LastVisitDate"; // 生成或获取访客唯一标识 if (!context.Request.Cookies.TryGetValue(visitorIdCookie, out var visitorId)) { visitorId = Guid.NewGuid().ToString(); context.Response.Cookies.Append(visitorIdCookie, visitorId, new CookieOptions { Expires = DateTime.Now.AddYears(1), HttpOnly = true, IsEssential = true }); } // 更新在线人数(30分钟无活动视为离线) var onlineUsersKey = "OnlineUsers"; var onlineUsers = _cache.GetOrCreate(onlineUsersKey, entry => new HashSet<string>()); // 清理超时用户 onlineUsers.RemoveWhere(id => _cache.TryGetValue($"LastActive_{id}", out DateTime lastActive) && DateTime.Now - lastActive > TimeSpan.FromMinutes(30)); onlineUsers.Add(visitorId); _cache.Set(onlineUsersKey, onlineUsers, TimeSpan.FromHours(1)); _cache.Set($"LastActive_{visitorId}", DateTime.Now, TimeSpan.FromMinutes(35)); // 判断是否为今日/当月新访问 bool isNewToday = false; bool isNewMonth = false; if (context.Request.Cookies.TryGetValue(lastVisitCookie, out var lastVisitStr) && DateTime.TryParse(lastVisitStr, out var lastVisit)) { isNewToday = lastVisit.Date != today; isNewMonth = lastVisit.Year != today.Year || lastVisit.Month != today.Month; } else { isNewToday = true; isNewMonth = true; } // 更新访问量统计 if (isNewToday) { var todayKey = $"TodayVisits_{today:yyyyMMdd}"; _cache.Set(todayKey, (_cache.Get<int?>(todayKey) ?? 0) + 1, TimeSpan.FromDays(1)); var totalKey = "TotalVisits"; _cache.Set(totalKey, (_cache.Get<int?>(totalKey) ?? 0) + 1, TimeSpan.FromDays(365)); } if (isNewMonth) { var monthKey = $"MonthVisits_{currentMonth:yyyyMM}"; _cache.Set(monthKey, (_cache.Get<int?>(monthKey) ?? 0) + 1, TimeSpan.FromDays(31)); } // 更新最后访问日期Cookie context.Response.Cookies.Append(lastVisitCookie, today.ToString("yyyy-MM-dd"), new CookieOptions { Expires = DateTime.Now.AddDays(1), HttpOnly = true, IsEssential = true }); // 继续处理后续请求 await _next(context); } }
2. 配置Startup.cs
在Startup.cs中注册缓存服务和中间件:
ConfigureServices方法
添加内存缓存支持:
public void ConfigureServices(IServiceCollection services) { services.AddMemoryCache(); // 其他服务注册(如AddMvc等) services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
Configure方法
添加中间件(确保放在UseStaticFiles之后,UseRouting/UseMvc之前):
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 其他中间件(如UseStaticFiles、UseDeveloperExceptionPage等) app.UseStaticFiles(); // 添加访客统计中间件 app.UseMiddleware<VisitorCounterMiddleware>(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
3. 获取统计数据的API控制器
创建API控制器用于前端或后端获取统计数据:
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using System; [Route("api/visitor-stats")] [ApiController] public class VisitorStatsController : ControllerBase { private readonly IMemoryCache _cache; public VisitorStatsController(IMemoryCache cache) { _cache = cache; } [HttpGet] public IActionResult GetStats() { var today = DateTime.Today; var currentMonth = new DateTime(today.Year, today.Month, 1); var stats = new { OnlineUsers = _cache.Get<HashSet<string>>("OnlineUsers")?.Count ?? 0, TodayVisits = _cache.Get<int?>($"TodayVisits_{today:yyyyMMdd}") ?? 0, MonthVisits = _cache.Get<int?>($"MonthVisits_{currentMonth:yyyyMM}") ?? 0, TotalVisits = _cache.Get<int?>("TotalVisits") ?? 0 }; return Ok(stats); } }
关键说明
- 缓存机制:使用
IMemoryCache存储统计数据,单服务器场景下足够;如果是多服务器集群,需替换为IDistributedCache(如Redis)实现跨节点数据共享 - 数据持久化:内存缓存数据会在应用重启后丢失,若需持久化,可添加定时任务将每日/每月统计数据写入数据库,重启时从数据库加载历史数据
- 在线人数逻辑:通过访客ID的最后活动时间判断,30分钟无活动自动移除,避免统计无效在线用户
- Cookie处理:遵循ASP.NET Core的Cookie操作规范,设置
IsEssential确保合规性
内容的提问来源于stack exchange,提问作者Sina
相关产品推荐
相关产品推荐

