【问题标题】:Persisting/caching data between requests - common approach在请求之间持久化/缓存数据 - 常用方法
【发布时间】:2009-08-11 23:48:27
【问题描述】:

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

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

所以我正在考虑如何以及在哪里最好地保留登录用户的 IUser 数据?

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

我看到的选择:

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

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

  1. 用户登录,从数据库中获取用户数据并以某种方式持久化以供以后请求
  2. 用户注销,用户数据必须自动从持久化介质中删除
  3. 用户更改了自己的个人资料,用户数据必须被丢弃并在下次从数据库请求时重新读取

我不希望所有这些都由 HttpModule(如果可能的话)自动处理,以消除开发人员忘记重置这些东西的错误。

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

问题

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

【问题讨论】:

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


    【解决方案1】:

    鉴于您的要求,我想最好的解决方案是从 cookie 中检索 ID 并使用它来索引 Http Cache (HttpContext.Current.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 服务器更新以及处理更新或手动更新它作为服务的一部分以保存更改。

    更多关于默认缓存的信息请见here。有关cache dependencies 的更多信息,请访问here

    在 HttpModule 本身中,我想你可以在 EndRequest 事件中做一些魔术来查看请求是否经过身份验证,然后根据 cookie 将用户注销,但我不确定这是否会像我一样工作'我从来没有尝试过。您可能想在 1.1 天前查看 MSDN 上的 this article,看看它是否回答了您正在尝试解决的一些问题。

    至于 SO 架构及其实现方式,我想他们会在需要时加载它,因为他们始终将大部分数据库保存在 RAM 中 (http://highscalability.com/stack-overflow-architecture)。

    【讨论】:

      猜你喜欢
      • 2011-01-29
      • 1970-01-01
      • 2021-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 2013-06-05
      相关资源
      最近更新 更多