我有一个Web API,为Angular.JS Web应用程序提供后端。后端API需要跟踪用户活动的状态。 (例如:需要注意用户上次从API检索的内容ID)
对API的大多数访问都通过用户名/密码进行身份验证。对于这些实例,我可以将用户状态存储在我们的数据库中。
但是,我们确实需要允许"客人"访问该服务。对于客人,需要跟踪州,但不应长期持久(例如,会话级跟踪)。我真的不想生成"伪用户"在我们的用户表中只是为访客用户存储状态,不需要在很长一段时间内维护。
我的计划是生成一个随机值并将其作为cookie存储在客户端中。 (仅限访客 - 我们对经过身份验证的用户使用承载身份验证。)然后,我将使用随机值作为密钥存储内存对象(如Dictionary)中所需的任何状态。然后我可以定期将字典中的项目过期。如果重新启动Web API,则完全可以接受这些数据丢失,并且甚至可以接受字典重置,例如,每天在特定时间重置。
我不知道如何在WebAPI中创建字典对象,以便它可以在Web API调用中保持不变。我基本上需要一个单例字典对象,只要服务器运行Web API,就会维护其内容(除非计划清算或程序化刷新)
我有想法在每次进行API调用时将字典转储到磁盘,然后在需要时将其读回,但这不允许多个同时在线请求。我现在能想到的唯一方法是添加另一个数据库表(guest_state或其他东西)并复制users表,然后设置某种手动方法来定期清理guest表中的数据。
总结:我需要的是
答案 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文件的东西可能更有用。