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

求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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:50:16