代码之家  ›  专栏  ›  技术社区  ›  Oskar Kjellin

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

  •  12
  • Oskar Kjellin  · 技术社区  · 15 年前

    我正在使用ASP.NETMVC并创建一个公共网站。我需要跟踪在线用户。我看到在asp.net中这样做的标准方法是跟踪 LastActivityDate

    如果每次用户点击某个地方时我都更新它,我会感到性能下降。但是,如果我不这样做,那些只在网上冲浪的人将被列为离线。

    在asp.net MVC中实现这一点的最佳方法是什么?

    10 回复  |  直到 12 年前
        1
  •  6
  •   Jab    15 年前

    只需在母版页的底部放置一个ajaxjavascript调用来跟踪它。

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

        2
  •  6
  •   Ralph N    13 年前

    刚刚遇到同样的问题,下面是我给MVC用户的答案:

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

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

    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);
        }
    }
    
        3
  •  4
  •   Community CDub    7 年前

    SimpleMembershipProvider . 太简单了,再也没有了 LastActivityDate

    我刚加了一个 在用户表中的列,并很好地去。。。

    跟随 @Jab's tip 使用 _Layout.cshtml 页面(母版页)在ASP.NET MVC应用程序中,我是在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();
    }
    

    仅133ms(YMMV):-)

    enter image description here

        4
  •  2
  •   Steve Horn    15 年前

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

        5
  •  2
  •   Charlino    15 年前

    我在申请表中是这样做的:

    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公司,
    查尔斯

        6
  •  2
  •   Ian Mercer    15 年前

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

        7
  •  1
  •   driis    15 年前

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

        8
  •  0
  •   Mark Redman    15 年前

    好问题,我也考虑过这一点,以及这些机制考虑性能的准确度,有几个想法:

    1) 跟踪上次登录日期

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

        9
  •  0
  •   uvita    15 年前

    我认为,如果在每个请求中获取当前登录的用户并更新 LastActivityDate GetUser 方法(每个http请求一次)。通过这种方式,您还可以确保用户的数据总是新鲜的,比如电子邮件、姓名等,以防他/她更新数据。

        10
  •  0
  •   Dov Miller    8 年前

    我试过了 查理诺

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

    但是我得到了 Request.IsAuthenticated 一直都是假的。 所以我把代码移到了我的 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 班级和班级 应用程序用户 增加了I类 LastActivityDate property .

    WebForms Applicaction MVC .