2010-01-29 9 views
6

Chiedersi se qualcuno sa in modo definitivo quale sia la serializzazione predefinita utilizzata da ASP.net HttpRuntime.Cache? È binario, XML, qualcos'altro?Qual è la serializzazione predefinita utilizzata da ASP.net HttpRuntime.Cache

Chiedo perché ho una situazione in cui sto compilando un Elenco generico con più oggetti dello stesso tipo personalizzato. Il tipo personalizzato è un POCO, non c'è niente di speciale. Tutte le sue proprietà sono pubbliche con {get; impostato; }, è pubblico, non ha ereditarietà, non ha interfacce. In effetti è molto meno complicato di molti altri oggetti che stiamo memorizzando nella cache e che funzionano senza problemi. Ho provato ad aggiungere l'attributo [Serializable] alla classe personalizzata e non ha alcun effetto.

Aggiungo l'elenco alla cache con una chiave univoca. L'elenco è stato verificato come popolato prima di essere inserito nella cache, anche gli oggetti nell'elenco sono stati verificati come popolati. Ma quando la lista viene estratta dalla cache è una lista vuota (NOT NULL), semplicemente non contiene elementi. Ciò significa che l'elenco viene aggiunto alla cache ed è recuperabile, ma per qualche motivo la cache ha problemi con la serializzazione degli oggetti nell'elenco.

Ho appena trovato questo strano strano perché ho un altro elenco di oggetti personalizzati che sono molto più complicati (costituiti da ereditarietà, interfacce e contenenti anche proprietà che sono elenchi generici di altri oggetti complessi) e la memorizzazione nella cache di tali elenchi funziona senza problemi.

Sia l'elenco di lavoro che quello non funzionante vengono gestiti in classi C# al di fuori dei controlli utente ASP.net che consumano i dati memorizzati nella cache. Entrambe queste classi di gestione della cache chiamano esattamente la stessa istanza di singleton della classe Cache Manager che avvolge HttpRuntime.Cache per fornire metodi tipizzati per l'estrazione e la spinta di oggetti nella cache.

Chiunque ha qualche idea su cosa potrebbe causare ciò. L'unica cosa che posso attenuare è che la proprietà 'Blurb' dell'oggetto Document può potenzialmente contenere HTML, ma se ASP.net utilizza la serializzazione binaria per la cache, non vedo come questo possa fare qualsiasi cosa.

Ecco la classe

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; } 
} 

Ecco la sottoclasse utilizzato nella proprietà Language

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

+1 Buona domanda! –

risposta

0

Un po 'più di dettaglio per quanto riguarda l'ambiente in cui si verifica questa anomalia di memorizzazione nella cache.

Ho un controllo utente ASP.net che rappresenta un contenitore a schede nella pagina. Questo controllo contiene un elenco di argomenti selezionati dall'utente. Per ogni argomento selezionato dall'utente questo controllo crea una nuova scheda per quell'argomento che contiene i documenti relativi a tale argomento.

Il controllo crea la nuova scheda utilizzando il metodo LoadControl fornito da ASP.net. Assegna quindi al nuovo Tab Control un argomento dal suo elenco. Ogni controllo a schede sa come individuare i documenti per il tema assegnato.

È all'interno di questo controllo a schede in cui è stata implementata la memorizzazione nella cache.La chiave cache utilizzata per memorizzare nella cache gli elenchi di documenti è completamente unica per il Sito + Argomento + Sesso + Età dell'utente che visualizza l'argomento. Ciò consente agli elenchi di documenti di essere memorizzati nella cache e recuperati attraverso il sito da tutti gli utenti che soddisfano tali criteri.

Bene quando gli elenchi di documenti sono stati passati alla cache, sono stati passati da normali riferimenti a oggetti vecchi (ad esempio List documents = _documents). ma quando estratti dalla cache la lista era vuota.

Sebbene ciascun controllo di tabulazione sia la propria istanza dello stesso controllo utente e tutte le variabili utilizzate all'interno del controllo struttura a schede siano private di tale controllo e dovrebbero essere specifiche per tale controllo. Ho raggiunto la fine della mia corda e, nonostante il fatto che le singole schede non siano in grado di sovrascrivere le altre liste private, ho deciso che doveva esserci una sorta di bug di riferimento pazzo in corso e se questo era il caso di cui avevo bisogno smettere di usare gli oggetti di riferimento nella cache e inviare solo alla cache copie completamente nuove degli elenchi che stavo cercando di memorizzare.

Ho quindi utilizzato il seguente metodo di estensione per l'Elenco < e clonato ogni elenco quando sono stati passati alla cache. Ciò ha fatto in modo che tutti gli oggetti passati alla cache fossero oggetti nuovi di zecca con il proprio spazio in memoria con i propri riferimenti unici a quella memoria.

FISSO. LA CACCIA ORA FUNZIONA. Gli elenchi vengono ora restituiti esattamente come sono stati aggiunti alla cache. Non ho idea del perché questo farebbe la differenza, se qualcuno avesse qualche idea mi piacerebbe ascoltarli.

/// <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

Secondo Reflector, HttpRuntime.Cache non serializza i dati a tutti, è semplicemente memorizza nella memoria in un Hashtable.

Si dice di includere le chiamate nella cache all'interno del proprio oggetto Singleton. Perchè fai questo? HttpRuntime.Cache è una proprietà statica e pertanto i metodi del wrapper possono essere anche statici.

+0

È un'applicazione web aziendale ed è stata una decisione architettonica fatta da coloro che hanno molto più potere di I :). – Schleichermann

+1

A meno che non si disponga di prove contrarie, sospetto il codice wrapper prima del runtime di ASP.NET. Ho scritto questo tipo di codice di architettura me stesso (incluso il mio involucro della cache!), E so quanto sia difficile avere ragione. Forse lo stai usando in un modo che non è stato progettato per gestire? Suggerisco di portare la questione con gli autori della tua classe wrapper. –

0

Le cache in genere non serializzano o clonano in altro modo gli oggetti inseriti. Associano semplicemente una chiave all'oggetto che si passa. E poiché gli elenchi sono tipi di riferimento, qualsiasi modifica apportata all'elenco sarà visibile quando la chiave viene utilizzata per recuperare dalla cache. Quindi la mia ipotesi è che stai rimuovendo gli articoli dalla lista dopo averlo inserito. Questo è il motivo per cui il clone su insert lo ha risolto.

Problemi correlati