ASP.NET Web API:如何跨请求创建持久集合?

时间:2016-09-18 20:53:46

标签: c# asp.net-web-api

我有一个Web API,为Angular.JS Web应用程序提供后端。后端API需要跟踪用户活动的状态。 (例如:需要注意用户上次从API检索的内容ID)

对API的大多数访问都通过用户名/密码进行身份验证。对于这些实例,我可以将用户状态存储在我们的数据库中。

但是,我们确实需要允许"客人"访问该服务。对于客人,需要跟踪州,但不应长期持久(例如,会话级跟踪)。我真的不想生成"伪用户"在我们的用户表中只是为访客用户存储状态,不需要在很长一段时间内维护。

我的计划是生成一个随机值并将其作为cookie存储在客户端中。 (仅限访客 - 我们对经过身份验证的用户使用承载身份验证。)然后,我将使用随机值作为密钥存储内存对象(如Dictionary)中所需的任何状态。然后我可以定期将字典中的项目过期。如果重新启动Web API,则完全可以接受这些数据丢失,并且甚至可以接受字典重置,例如,每天在特定时间重置。

我不知道如何在WebAPI中创建字典对象,以便它可以在Web API调用中保持不变。我基本上需要一个单例字典对象,只要服务器运行Web API,就会维护其内容(除非计划清算或程序化刷新)

我有想法在每次进行API调用时将字典转储到磁盘,然后在需要时将其读回,但这不允许多个同时在线请求。我现在能想到的唯一方法是添加另一个数据库表(guest_state或其他东西)并复制users表,然后设置某种手动方法来定期清理guest表中的数据。

总结:我需要的是

  • 一种将一些数据持久存储在Web API后端而无需转到数据库的方法
  • 最好将此数据存储在Dictionary对象中,以便我可以使用随机生成的会话ID作为密钥,以及存储状态的对象
  • 数据可以在一段时间后或定期清除(不是频繁,可能至少持续6小时)

1 个答案:

答案 0 :(得分:4)

我找到了使用Singleton模式的解决方案:

public static class Services 
{
    private static Dictionary<string, string> cache;

    private static object cacheLock = new object();
    public static Dictionary<string,string> AppCache
    {
        get
        {
            lock (cacheLock)
            {
                if (cache == null)
                {
                    cache = new Dictionary<string, string>();
                }
                return cache;
            }
        }
    }
}

public class testController()
{
    [HttpGet]
    public HttpResponseMessage persist()
    {
        HttpResponseMessage hrm = Request.CreateResponse();
        hrm.StatusCode = HttpStatusCode.OK;

        Services.AppCache.Add(Guid.NewGuid().ToString(), DateTime.Now.ToString());

        string resp = "";

        foreach (string s in Services.AppCache.Keys)
        {
            resp += String.Format("{0}\t{1}\n", s, Services.AppCache[s]);
        }
        resp += String.Format("{0} records.", Services.AppCache.Keys.Count);

        hrm.Content = new StringContent(resp, System.Text.Encoding.ASCII, "text/plain");
        return hrm;
    }        
}

似乎Services.AppCache对象成功保留数据,直到空闲超时到期或应用程序池回收为止。幸运的是,我可以控制IIS中的所有内容,因此我将应用程序移动到自己的AppPool,并根据我刷新数据的时间,根据需要设置空闲超时和回收。

可悲的是,如果您无法控制IIS(或者无法要求管理员为您设置设置),如果您的默认过期时间太短,这可能无效...此时使用类似LocalDB文件甚至平面JSON文件的东西可能更有用。