在 asp.net-MVC 中捕获每个用户的页面浏览量的最佳方法是什么

本文关键字:浏览量 最佳 是什么 方法 用户 net-MVC asp | 更新日期: 2023-09-27 17:57:02

什么是在不降低网站性能的情况下按人捕获页面浏览量的最佳方法。 我看到堆栈溢出到处显示页面浏览量。 他们是否在每次我单击页面时都插入到数据库中?

在 asp.net-mvc 中,是否有任何推荐的方法来跟踪每个用户的页面浏览量(我的网站有一个登录屏幕),以便我可以查看人们要访问的页面以及频率

在 asp.net-MVC 中捕获每个用户的页面浏览量的最佳方法是什么

首先,如果你真正关心的是客户如何使用我的网站,那么你很可能想看看谷歌分析或类似的服务。

但是,如果您想要一个快速而肮脏的页面浏览记录,并且您正在使用 ASP.Net MVC 3,那么正如Chris Fulstow所提到的,您将希望混合使用全局操作过滤器和缓存。 下面是一个示例。

PageViewAttribute.cs 
    public class PageViewAttribute : ActionFilterAttribute
{
    private static readonly TimeSpan pageViewDumpToDatabaseTimeSpan = new TimeSpan(0, 0, 10);
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var calledMethod = string.Format("{0} -> {1}",
                                         filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
                                         filterContext.ActionDescriptor.ActionName);
        var cacheKey = string.Format("PV-{0}", calledMethod);
        var cachedResult = HttpRuntime.Cache[cacheKey];
        if(cachedResult == null)
        {
            HttpRuntime.Cache.Insert(cacheKey, new PageViewValue(), null, DateTime.Now.Add(pageViewDumpToDatabaseTimeSpan) , Cache.NoSlidingExpiration, CacheItemPriority.Default,
                                  onRemove);
        }
        else
        {
            var currentValue = (PageViewValue) cachedResult;
            currentValue.Value++;
        }
    }
    private static void onRemove(string key, object value, CacheItemRemovedReason reason)
    {
        if (!key.StartsWith("PV-"))
        {
            return;
        }
        // write out the value to the database
    }
    // Used to get around weird cache behavior with value types
    public class PageViewValue
    {
        public PageViewValue()
        {
            Value = 1;
        }
        public int Value { get; set; }
    }
}

在你的Global.asax中.cs

public class MvcApplication : HttpApplication 
{
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new PageViewAttribute());
        }
}

对于 pre-ASP.Net MVC 3,您必须手动将相同的属性应用于所有操作。

[PageView]
public ActionResult CallOne()
{
}
[PageView]
public ActionResult CallTwo()
{
}

最好的方法可能是全局操作筛选器,该筛选器拦截对所有控制器上所有操作的请求,然后在数据库中为当前用户和页面递增计数器。 为了避免过多地访问数据库,您可以缓存这些值并每隔几分钟使它们失效,具体取决于您正在处理的流量。

我们使用开源的Piwik:http://piwik.org/,它是在自己的服务器上设置的。_Layout页面中的一行Javascript在页面加载后调用Piwik(将JS放在末尾),并且根本不影响页面加载性能。

除了计数之外,您还将获得大量有关用户来自何处的信息,浏览器,屏幕分辨率,已安装的插件。此外,您可以跟踪转化并使用相同的工具来跟踪营销活动等。

<肥皂盒>

我想不出在MVC或一般的Web应用程序中实现这一点会更好的情况。这些东西根本不属于您的 Web 应用程序,并且是一个应该分离出来的元关注点。这种方法使我们能够以统一的方式跟踪所有应用程序的分析(其中32个:mvc 2/3,webforms,php...)。

如果您真的不想为此目的使用其他工具,我建议您利用您的 IIS 日志并从那里获取统计信息。同样,要从中获得任何真正的决策能力,您需要在其上安装一个好的分析器。我推荐Splunk:http://www.splunk.com/

我想为感兴趣的人发布Shane答案的更新版本。需要考虑的一些事项:

  1. 在装饰您的使用如下语法的方法:

    [ServiceFilter(typeof(PageViewAttribute))]

  2. 据我所知,HttpRuntime.Cache.Insert 在 .NET Core 中不是一个东西,所以我使用了 IMemoryCache 的简单实现(您可能需要将此行添加到您的启动.cs才能使用该接口):

    服务业。AddMemoryCache();

  3. 因为我们将 IMemoryCache 注入到一个不是控制器的类中,所以我们需要在 startup.cs 中将我们的属性注册为服务,如下所示:

    服务业。AddScoped<[PageViewAttribute]>();- 没有括号!

  4. 创建 cacheKey 时返回的任何对象都将分配给 OnRemove 方法的"value"参数。

下面是代码。

public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var controllerActionDescriptor = filterContext.ActionDescriptor as ControllerActionDescriptor;
        var arguments = filterContext.ActionArguments;
        ActionId = arguments["id"].ToString();
        var calledMethod = string.Format("{0} -> {1}",
                                         controllerActionDescriptor.ControllerName,
                                         controllerActionDescriptor.ActionName);
        var cacheKey = string.Format("PV-{0}", calledMethod);
        var cachedResult = _memoryCache.Get(cacheKey);
        if (cachedResult == null)
        {
            //Get cacheKey if found, if not create cache key with following settings
            _memoryCache.GetOrCreate(cacheKey, cacheKey =>
            {
                cacheKey.AbsoluteExpirationRelativeToNow
                              = pageViewDumpToDatabaseTimeSpan;
                cacheKey.SetValue(1);
                cacheKey.RegisterPostEvictionCallback(onRemove);
                return cacheKey.Value;
            });
        }
        else
        {
            _memoryCache.Get(cacheKey);
        }
    }
    //Called when Memory entry is removed
    private void onRemove(object key, object value, EvictionReason reason, object state)
    {
        if (!key.ToString().StartsWith("PV-"))
        {
            return;
        }
        // write out the value to the database
        SaveToDataBase(key.ToString(), (int)value);
    }

作为参考,这是为.NET Core 5 MVC应用完成的。

问候。