繁体   English   中英

C#asp.net MVC:何时更新LastActivityDate?

[英]C# asp.net MVC: When to update LastActivityDate?

我正在使用ASP.NET MVC并创建一个公共网站。 我需要跟踪在线用户。 我看到asp.net中的标准方法是跟踪LastActivityDate 我的问题是我应该何时更新?

如果我每次用户点击某处都更新它,我会觉得性能退缩。 但是,如果我不这样做,那些只能浏览的人将被列为离线状态。

在asp.net MVC中执行此操作的最佳方法是什么?

只需在主页底部放置一个ajax javascript调用即可跟踪。

此时不要担心性能问题。 如果它已经实施并且您认为它是一个问题,那么回过头来寻找更好的解决方案。 如此简单的东西不应该是性能问题。

试想一下像谷歌分析。 它位于数百万页的底部,对这些网站的用户体验几乎没有影响。

刚遇到同样的问题,这是我对MVC用户的回答:

我们的想法是为每个页面加载触发Membership.GetUser(“..”,true)。 这将自动更新LastActivityDate。

我把它放在“RegisterGlobalFilters”下的global.asax中:

filters.Add(new MembershipTriggerLastActivityDate());

我创建了一个新类,如下所示:

class MembershipTriggerLastActivityDate : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            MembershipUser user = Membership.GetUser(filterContext.HttpContext.User.Identity.Name, true);
        }   
        base.OnActionExecuting(filterContext);
    }
}

我开始使用SimpleMembershipProvider 它非常简单,不再有LastActivityDate跟踪。 所以我不得不自己动手。

我刚刚在Users表中添加了一个LastActivityDate列,并且很好...

按照_Layout.cshtml 的提示并在ASP.NET MVC应用程序中使用_Layout.cshtml页面(母版页),我在jQuery的帮助下完成了这个:

$(document).ready((function () {

    var isUserAuthenticated = '@User.Identity.IsAuthenticated';

    if (isUserAuthenticated) {

        $.ajax({
            type: "POST",
            url: "@Url.Action(MVC.Account.ActionNames.UpdateLastActivityDate, MVC.Account.Name)",
            data: { userName: '@User.Identity.Name' },
            cache: false
        });
    }
});

这是动作方法:

public virtual ActionResult UpdateLastActivityDate(string userName)
{
    User user = Database.Users.Single(u => u.UserName == userName);

    user.LastActivityDate = DateTime.Now;

    Database.Entry(user).State = EntityState.Modified;

    Database.SaveChanges();

    return new EmptyResult();
}

只有133毫秒(YMMV):-)

在此输入图像描述

为什么不将LastActivityDate的更新实现为异步调用? 这样您就可以触发更新并继续处理。

正如@Jab所说,只是实现它,如果你将其视为未来的性能问题 - 那么就应该处理它。

这就是我在我的应用程序中完成它的方式:

protected void Application_EndRequest()
{
    if ((Response.ContentType == "text/html") && (Request.IsAuthenticated))
    {
        var webUser = Context.User as WebUser;
        if (webUser != null)
        {
            //Update their last activity
            webUser.LastActivity = DateTime.UtcNow;

            //Update their page hit counter
            webUser.ActivityCounter += 1;

            //Save them
            var webUserRepo = Kernel.Get<IWebUserRepository>(); //Ninject
            webUserRepo.Update(webUser);
        }
    }
}

我的表现没有任何问题。

HTHS,
查尔斯

我把它放入一个特殊的队列,只允许一个给定的密钥在队列中(在这种情况下使用userId作为密钥)。 然后我有一个低优先级的线程,通过这个队列进行数据库更新。 因此,用户不会减速,并且一个用户在一秒内完成100次更新不会造成任何伤害。 如果它成为一个问题,我将对数据库进行批量更新这些更新,但现在这种方法工作得很好。

如果应用程序崩溃,我会丢失几秒钟的最后一次活动数据,但这很好。 当然,我每次都会更新内存中的User对象,以便它反映在UI中,即使它还没有进入数据库。 通常它是在他们收到完整的页面之前就已经存在了。

如果您使用的是InProc SessionState,请使用SessionStateModule.End事件。 当会话状态从底层缓存存储中逐出时会发生这种情况。 通常,这在20分钟不活动后发生,您可以在web.config中设置时间。

好问题,也考虑过这些,以及这些机制在考虑性能方面有多准确,有几个想法:

1)跟踪上次登录日期

2)使用LastLoginDate +预期的会话长度来设置某种LastOnlineDate,可用于检查用户是否在线。

如果您在每个请求上获取当前登录用户并且每次都更新LastActivityDate字段,我认为性能不会受到很大的损失(如果您小心并且每个http调用一次登录用户的GetUser方法)请求)。 通过这种方式,您还可以确保始终拥有用户的数据,例如电子邮件,姓名等,以防他/她更新该数据。

我在Global.asax中尝试过Charlino的代码

        protected void Application_BeginRequest(object sender, EventArgs e)
    {
        if ((Response.ContentType == "text/html") && (Request.IsAuthenticated))
        {

        }
    }

但是我一直得到Request.IsAuthenticated false。 所以我将代码移动到我的Site.Master page的方法,就像这样

 public void RegisterActivity()
    {
        if ((Response.ContentType == "text/html") && (Request.IsAuthenticated))
        {
            string userName = Page.User.Identity.Name;

            UserManager userManager = new UserManager();
            AppUser appUser = userManager.FindByName(userName);
            appUser.LastActivityDate = DateTime.UtcNow;
            userManager.Update(appUser);
        }
    }

我从Master page Page_Load事件调用该方法,并在那里工作。

我使用asp.net Identity不是Membership ,但我添加了一个AppUser类从继承IdentityUser类,并在AppUser我添加类LastActivityDate property

这是在WebForms Applicaction而不是MVC

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM