2016-09-18 64 views
2

我有一個Web API提供一個Angular.JS Web應用程序的後端。後端API需要跟蹤用戶活動的狀態。 (例如:需要注意用戶最近從API中檢索的內容ID)ASP.NET Web API:如何跨請求創建持久集合?

對API的大部分訪問都通過用戶名/密碼進行驗證。對於這些實例,我可以將用戶狀態存儲在我們的數據庫中。

但是,我們確實需要允許「訪客」訪問該服務。對於客人而言,該州確實需要進行跟蹤,但不應長期持續(例如會話級別跟蹤)。我真的很希望不必在我們的用戶表中生成「僞用戶」來存儲訪客用戶的狀態,這不需要在很長一段時間內維護。

我的計劃是生成一個隨機值並將其作爲cookie存儲在客戶端中。 (僅適用於客人 - 我們使用承認身份驗證用戶身份)。然後,我會使用隨機值作爲關鍵字在內存對象(如Dictionary)中存儲任何必需的狀態。我可以定期從字典中刪除項目。如果Web API重新啓動,那麼這些數據就會丟失是完全可以接受的,甚至在特定時間每天都可以重置字典甚至是可以接受的。

我不知道如何做的WebAPI是創建字典對象,以便它將持續跨Web API調用。我基本上需要一個singleton字典對象,只要服務器運行Web API,它就會保持它的內容(禁止計劃清除或程序性沖洗)

我有一個想法,即每次將字典轉儲到磁盤進行API調用,然後在需要時再讀取它,但這不允許多個同時發送的請求。我現在唯一能想到的方法是添加另一個數據庫表(guest_state或其他)並複製users表,然後設置某種手動方法來定期清除guest表中的數據。

摘要:我需要的是

  • 持久地存儲在Web API後端一些數據的方式,而不必去開了一個數據庫
  • 最好存儲在Dictionary對象這個數據,所以我可以使用隨機生成的會話ID作爲密鑰,並存儲對象以存儲狀態
  • 數據可以在設定的時間段內或定期清除(不是也可以是,也可以是最少的6小時持久性)

回答

1

我想出使用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文件可能會更有用。

+1

重要的兩點:您需要使用'ConcurrentDictionary'而不是Dictionary。字典不是線程安全的,只要多個用戶開始使用您的應用程序,您就會遇到異常(請記住請求是同時處理的)。其次,一個建議,'System.Web.Caching.Cache'基本上就是你正在尋找的東西,它也爲你提供了過期邏輯:https://msdn.microsoft.com/en-us/library/ system.web.caching.cache(v = vs.110).aspx在一個ASP.net應用程序中,緩存的單例實例可以在'HttpContext.Cache'中使用 –