2009-08-13 108 views
1

我正在修復大量使用會話來跟蹤每頁數據的ASP.NET應用程序。其中一個問題是會話在頁面之間流血。使用像ViewState這樣的會話

ViewState的將是一個更好的解決辦法,除非:

  • 的數據是不可序列
  • 有太多的數據每次回發

所以我想被髮送來回:

  • 爲會話數據創建頁面密鑰(即在隱藏字段中粘貼一個隨機GUID)
  • 從一個廢棄的頁面過期數據,即使整個會話活躍

是否有到期部分會話的數據的好方法嗎?

+0

有點信息將是有益的。您是否試圖爲每個頁面存儲相同的數據結構,或者每個頁面有唯一的數據結構?爲什麼會話數據在用戶離開後閒逛會出現問題? – 2009-08-13 13:32:16

+0

@Christian Hayter他的問題意味着多個頁面使用相同的會話密鑰。因此,針對頁面A的數據將留在會話中供頁面B查找。 – AaronSieb 2009-08-13 13:51:26

+0

AaronSieb是正確的。 – Korey 2009-08-13 15:43:41

回答

2

下的臨時存儲位置可供選擇:

  1. 會議。這跟隨用戶並使用cookie。它可以配置爲使用URL參數來檢索。會話也可以配置爲存儲在Web服務器,SQL Server或狀態服務器上的進程(inproc)中。 InProc可以存儲任何數據類型,但其他類型需要可序列化的類型。
  2. 緩存。存儲在緩存中的數據可供任何用戶在會話中使用。它與會話類似,因爲對象可以通過密鑰進行檢索。緩存的一個更好的功能是可以控制事物的存儲時間,並且可以在事件過期時使用事件。你可以在這裏存儲任何東西,但是你可能會遇到在webfarm中使用它的問題。
  3. HttpContext。這是針對當前請求的範圍。請記住,請求可以是web服務調用,調用獲取HTML的網頁或調用返回圖像的服務。任何東西都可以存儲在這裏。
  4. ViewState。視圖狀態的範圍是一個頁面。必須是可序列化的。

您可能需要檢查緩存。如果您使用的是網站農場,它不起作用,但您可以使用某種類型的GUID作爲您映射回會話的密鑰。

+0

如果我可以保證緩存可能會在會話持續20分鐘左右的時間內完成。 – Korey 2009-08-13 15:34:32

+0

這裏是我使用的緩存代碼: Cache.Insert(key,value,null,System.Web.Caching.Cache.NoAbsoluteExpiration,new TimeSpan(0,20,0),System.Web.Caching.CacheItemPriority.NotRemovable , 空值); – Korey 2009-08-14 20:54:29

+0

CacheItemPriority.NotRemovable阻止Cache由於內存壓力而刪除數據。 – Korey 2009-08-14 20:55:02

0

也許在每個頁面!IsPostBack或通過基本頁面,您可以清空所有對與該頁面無關的會話數據的引用。每次用戶轉到站點中的其他頁面時,這會使數據「過期」。

如果用戶離開網站或處於非活動狀態,則在會話過期之前可以做的事情不多,但在這種情況下,每個用戶只有一頁會話數據。

+0

我確實希望允許查看多個頁面(同一頁面,但具有不同的請求數據)。我不希望一個頁面自動銷燬另一個會話數據,我只是希望它能夠過期。 – Korey 2009-08-13 15:35:34

1

我可能會做這種方式:

  1. 創建一個對象來存儲你想成爲特定頁面的狀態信息。如果不同的頁面需要不同的信息,請創建多個類。
  2. 將此對象存儲在單個會話密鑰中:Session [「PageSpecific」];例如。
  3. 創建一個繼承自System.Web.UI.Page的類。
  4. 在基類的OnLoad事件中,如果頁面未執行回發,請清除會話密鑰。
  5. 創建並調用可重載的方法來填充會話對象。
  6. 不是從每個頁面的System.Web.UI.Page繼承,而是從新的基類繼承。

像這樣的東西(警告:空氣代碼可能包含語法錯誤):更多

public class PageBase 
    : System.Web.UI.Page 
{ 
    protected overrides OnInit(System.EventArgs e) { 
     base.OnInit(e); 

     if(!this.IsPostBack) { 
      Guid requestToken = System.Guid.NewGuid(); 
      ViewState["RequestToken"] = requestToken; 

      Session["PageSpecific" & requestToken.ToString()] = InitializePageSpecificState(); 
     } 
    } 

    protected virtual object InitializePageSpecificState() { 
     return new GenericPageState(); 
    } 

    //You can use generics to strongly type this, if you want to. 
    protected object PageSpecificState { 
     get { 
      return Session["PageSpecific" & ViewState["RequestToken"].ToString()]; 
     } 
    } 
} 
+0

這與以前的答案有相同的問題。我的問題可能不夠清楚。 某些用戶可能在多個選項卡中查看Default.aspx,並使用不同的請求數據(甚至相同)。我希望每個人都有自己的服務器端存儲空間。 – Korey 2009-08-13 15:42:15

+0

@Korey這將是一個好東西編輯到您原來的問題。它也很容易解決:在初始加載時生成某種形式的令牌(如Guid)。將其附加到會話密鑰(會話[「PageSpecific」&requestToken])。將密鑰存儲在ViewState中。 – AaronSieb 2009-08-13 16:30:05

+0

@Korey允許多個選項卡打開的主要困難是您無法從請求中清除會話,直到整個會話過期爲止......這可能會也可能不會成爲問題,具體取決於您的大小用戶羣。 – AaronSieb 2009-08-13 16:35:45

相關問題