2010-01-29 71 views
6

想知道是否有人確切地知道ASP.net HttpRuntime.Cache使用的默認序列化是什麼?它是二進制,XML還是別的?什麼是ASP.net使用的默認序列化HttpRuntime.Cache

我問,因爲我有一種情況,我用相同的自定義類型的多個對象填充泛型列表。自定義類型是POCO,沒有什麼特別的。它的所有屬性都是公開的{get;組; },它是公共的,它沒有繼承,它沒有接口。事實上,它比我們緩存沒有問題的許多其他對象複雜得多。我曾嘗試將[Serializable]屬性添加到自定義類中,但它沒有任何作用。

我使用唯一鍵將列表添加到緩存中。該列表在插入緩存之前已驗證爲已填充,列表中的對象也已驗證爲已填充。但是當列表退出緩存時它是一個空列表(NOT NULL),它只是沒有任何項目。這意味着該列表正在被添加到緩存中,並且是可檢索的,但由於某種原因,緩存在序列化列表中的對象時遇到了問題。

我剛剛發現這個奇怪的怪異,因爲我有另一個更復雜的自定義對象列表(包括繼承,接口,也包含屬性是其他複雜對象的通用列表)和這些列表的緩存工作沒有問題。

在使用緩存數據的ASP.net用戶控件之外的C#類中管理工作和非工作列表。這兩個緩存處理類都調用完全相同的緩存管理器類singleton實例,該實例封裝了HttpRuntime.Cache以提供用於將對象拖入緩存中的類型化方法。

任何人都有什麼想法可能導致這種情況發生。我唯一能做的是,Document對象的'Blurb'屬性可以包含HTML,但是如果ASP.net使用二進制序列化緩存,我不會看到這會做什麼。

這裏是類

public class Document 
{ 
    public string ContentTypeId { get; set; } 
    public string ContentId { get; set; } 
    public bool IsCustom { get; set; } 
    public Language DocLanguage { get; set; } 
    public string RegularTitle { get; set; } 
    public string InvertedTitle { get; set; } 
    public string Blurb { get; set; } 
} 

這裏是語言屬性

public class Language 
{ 
    public string Name { get; set; } 
    public string Code { get; set; } 
} 
+0

+1好問題! – 2010-06-30 17:03:00

回答

0

有關此緩存異常發生環境的更多細節。

我有一個ASP.net用戶控件,它代表頁面上的選項卡式容器。該控件包含用戶選擇的主題列表。對於用戶選擇此控件的每個主題,都會爲該主題創建一個新選項卡,其中包含與該主題相關的文檔。

該控件通過使用ASP.net提供的LoadControl方法創建新選項卡。然後它會從列表中爲新創建的Tab Control分配一個主題。每個選項卡控件都知道如何爲其分配的主題定位文檔。

它在執行緩存的此選項卡控件中。用於緩存文檔列表的緩存鍵對於查看該主題的用戶的站點+主題+性別+年齡來說是完全獨特的。這允許所有符合該標準的用戶在整個站點上緩存和檢索文檔列表。

當文檔列表被傳遞到緩存時,它們被傳統的舊對象引用(即List documents = _documents)傳遞。但是當從緩存中拉出時,列表是空的。

儘管每個選項卡控件都是它自己的同一個用戶控件的實例,並且選項卡控件內使用的所有變量都是該控件的專用對象,並且應該專用於該控件。儘管事實上單個標籤沒有辦法覆蓋每個其他人的私人列表,但我決定必須出現某種瘋狂的參考錯誤,如果那是我需要的情況停止使用緩存中的引用對象,只發送緩存完全新的我試圖存儲的列表副本。

然後,我使用列表<>的下列擴展方法>並在傳遞到緩存時克隆每個列表。這使得傳遞給緩存的所有項目都是全新的對象,並在內存中擁有自己的空間,並擁有自己對該內存的唯一引用。

FIXED IT。現在緩存工作。這些列表現在完全按照它們被添加到緩存的方式返回。我不知道爲什麼這會有所作爲,如果有人有任何想法我很樂意聽到他們。

/// <summary> 
    /// Clones the specified list to clone. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="listToClone">The list to clone.</param> 
    /// <returns></returns> 
    public static IList<T> Clone<T>(this IList<T> listToClone) where T : ICloneable 
    { 
     return listToClone.Select(item => (T)item.Clone()).ToList(); 
    } 
5

使用的子類,根據反射器,HttpRuntime.Cache不序列的所有數據,它只是將其存儲在存儲器中在Hashtable

你說你把調用包裝到你自己的單例對象中的緩存中。你爲什麼這麼做? HttpRuntime.Cache是一個靜態屬性,所以你的包裝方法也可以是靜態的。

+0

這是一個公司的網絡應用程序,是一個由比我更強大的人做出的架構決定:)。 – Schleichermann 2010-01-29 16:00:03

+1

除非您有相反的證據,否則我會懷疑ASP.NET運行時之前的包裝代碼。我自己寫了這樣的架構代碼(包括我自己的緩存包裝器!),並且我知道如何正確使用它。也許你碰巧用它不是爲了處理?我建議把你的包裝類的作者提出來。 – 2010-01-29 16:34:49

0

緩存一般不會序列化或以其他方式克隆放入它們的對象。它們只是將一個關鍵字與傳入的對象關聯起來。由於列表是引用類型,因此當使用關鍵字從緩存中檢索時,對列表所做的任何更改都將可見。所以我的猜測是,你插入後從列表中移除項目。這就是插入克隆解決它的原因。