在请求之间保持/缓存数据 - 常用方法

时间:2009-08-11 23:48:27

标签: asp.net-mvc forms-authentication persistence user-data

我正在开发一个Asp.net(MVC,但这并不重要)应用程序。我有一个自定义IHttpModule负责PostAuthenticateRequest更改用户主体和&身份。

我在用户登录时将UserID和UserName存储在身份验证cookie中。我有一个IUser(由DAO和Business Objects层实现,每个都有自己的额外成员),我需要遍布业务服务类。当用户想要任何东西时,我必须提供IUser对象实例(通常来自Business Objects层),因此从auth票证中提供ID是不够的。

所以我在考虑如何以及在哪里最好坚持登录用户的IUser数据?

  1. 我不想每次从数据库中获取它(基于身份验证票据的UserID数据)
  2. 我无法将其存储在Session中,因为我必须在PostAuthenticateRequest中工作,其中Session还没有准备好
  3. 我希望所有功能都封装在我的自定义IHttpModule
  4. 我看到的选择:

    • 高速缓存
    • 曲奇
    • (会话) - 从PostAuthenticateRequest移动到PostAcquireRequestState事件并在那里更改主体/身份,但我想避免这种情况

    似乎使事情变得复杂的过程是:

    1. 用户登录,用户数据从数据库中提取并以某种方式保留以供以后的请求
    2. 用户注销,必须自动从持久媒体中删除用户数据
    3. 用户更改自己的个人资料,必须丢弃用户数据并在下一个来自数据库的请求中重新读取
    4. 我不希望所有这些都由HttpModule自动处理(如果可能的话),以消除开发人员忘记重置这些事情的错误。

      我也不想要的是写/读一些硬编码变量/键并在应用程序的其他部分操作它们。这只会出现技术债务。

      问题

      1. 你会建议什么?
      2. SO如何在请求之间保留用户数据?

1 个答案:

答案 0 :(得分:4)

鉴于您的要求,我认为最好的解决方案是从cookie中检索ID并使用它来索引Http Cache(HttpContext.Current.Cache)。

如果要维护用户访问它的方式,请将Cache包装在“UserCache”对象中。该对象可以由HttpModule构造并在缓存本身内存储为(等待它......)单例,或者更好的是,只需在从http缓存中提取时构造。这取决于您需要访问它的位置以及HttpContext.Current.Cache是​​否可直接使用。懒惰的实现如下。

同样,这是为了清楚,而不是我实际实现它的方式。

public class UserCache
{
  public IUser GetUser(object userKey)
  {
    return HttpContext.Current.Cache[userKey];
  }

  public void AddUser(object userKey, IUser user)
  {
    /* this could pull the key from the user object as well. */
    HttpContext.Current.Cache.Add(/* add the object with key and a sliding expiration that is slightly greater than session timeout */);
  }

  public void ExpireUser(object userKey)
  {
    HttpContext.Current.Cache.Remove(userKey);
  }

  /* If you don't want to do SQL cache dependency */
  public void UpdateUser(object userKey, IUser user)
  {
    HttpContext.Current.Cache.Insert(/* ... */);
  }
}

使用默认缓存机制(或者更好的是DI提供的缓存机制,因此您不依赖于实现),您可以设置过期以自动从缓存中删除用户,如注释中所述。您可以将缓存设置为依赖于SQL Server更新以及处理更新,或者将其作为服务的一部分手动更新以保存更改。

有关默认缓存的更多信息可用here。有关cache dependencies的更多信息可用here

在HttpModule本身,我想你可以在EndRequest事件中做一些魔术来查看请求是否经过身份验证,然后根据cookie记录用户,但我不确定这是否会像我一样工作从未尝试过。您可能希望在1.1天内查看MSDN上的this article,看看它是否解决了您要解决的一些问题。

至于SO架构以及它们是如何做到的,我想他们会在需要时加载它,因为它们始终将大部分数据库保存在RAM中(http://highscalability.com/stack-overflow-architecture)。