我正在使用ASP.NET MVC创建一个公共网站,需要跟踪在线用户。我发现ASP.NET的标准方法是跟踪LastActivityDate
。我的问题是,何时应该更新它?
如果每次用户点击某个地方都更新它,那么性能会下降。但是如果不这样做,只浏览网页的人将被列为离线状态。
在ASP.NET MVC中,最好的方法是什么?
我正在使用ASP.NET MVC创建一个公共网站,需要跟踪在线用户。我发现ASP.NET的标准方法是跟踪LastActivityDate
。我的问题是,何时应该更新它?
如果每次用户点击某个地方都更新它,那么性能会下降。但是如果不这样做,只浏览网页的人将被列为离线状态。
在ASP.NET MVC中,最好的方法是什么?
我遇到了同样的问题,这是我为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);
}
}
$(document).ready
里面了... 在这里看 https://dev59.com/rHE85IYBdhLWcg3wkkfK#12720372。 - Leniel MaccaferriLastActivityDate
跟踪功能。因此,我不得不自己创建。LastActivityDate
列,就完成了..._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();
}
正如@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);
}
}
}
我在性能方面没有遇到任何问题。
希望对你有所帮助,
Charles
如果您正在使用InProc SessionState,请使用SessionStateModule.End事件。当会话状态从底层缓存存储中驱逐时,就会发生这种情况。通常在20分钟的不活动后会发生这种情况,您可以在web.config中设置时间。
我尝试在 Global.asax 中像这样使用 Charlino 的代码
protected void Application_BeginRequest(object sender, EventArgs e)
{
if ((Response.ContentType == "text/html") && (Request.IsAuthenticated))
{
}
}
然而,我一直得到Request.IsAuthenticated
的false。
所以我把代码移到了我的Site.Master页面
中的一个方法中,像这样
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_Load
事件中调用了该方法,并且它起作用了。
我正在使用asp.net Identity
而不是Membership
,但我添加了一个继承自IdentityUser
类的AppUser
类,在AppUser
类中我添加了LastActivityDate属性
。
这是一个WebForms应用程序
而不是MVC
。
好问题,我也考虑过这个问题,考虑到性能如何准确地实现这些机制,有几个想法:
1)跟踪上次登录日期
2)使用LastLoginDate + 预期会话长度来设置某种LastOnlineDate,以便检查用户是否在线。
我认为如果您在每个请求中获取当前已登录用户并每次更新LastActivityDate
字段(如果您小心并为每个http请求调用GetUser
方法以获取已登录用户),则性能上不会有太大的惩罚。通过这种方式,您还可以确保始终拥有用户的最新数据,例如电子邮件、姓名等,以防他/她更新了这些数据。