IntroduzioneÂ
Sono circa due settimane che il mio blog gira con Subtext 2.0, la nuova ed ultima release del noto blog engine, che annovera fra i suoi creatori anche il buon Simone Chiaretta.
Decido di dare oggi l’ufficialità di questa cosa, perchè la migrazione è stata sì indolore, ma un po’ preoccupante per alcuni sintomi.
- Parecchi di voi mi hanno detto via mail e via messenger che ogni tanto il mio blog si apriva senza skin. Urgh!
- Nella parte Admin del blog ogni tanto avevo una strana exception, che veniva tracciato correttamente nell’ErrorLog. Questo errore mi impediva di salvare dalla pagina Options –> Configure. In pratica, dove ci sono le impostazioni generali del blog: titolo del blog, skin da utilizzare, timezone e via dicendo. Urgh!
Primi passi per la risoluzione
Ho deciso di indagare, perchè il mio blog engine deve girare al meglio.
Dopo essermi consultato con Simone, ho operato nel modo seguente:
- Ho scaricato i sorgenti di Subtext 2.0 da SourceForge.net
- Ho fatto un backup del database SQL Server dal mio hosting
- Ho ripristinato il backup del punto (2) sul mio database SQL Server locale
- Ho aperto i sorgenti di Subtext 2.0 con Visual Studio 2008 con il file .sln dedicato
- Ho configurato la stringa di connessione nel file web.config, così da far usare il mio database locale
La comodità di tutto questo è che non c’è bisogno di avere un web-server installato: è sufficiente quello integrato di Visual Studio. Basta impostare il progetto Subtext.Web come StartUp Project ed il gioco è fatto.
Debug
Non sto qui a raccontarvi tutti i giri di debug che mi sono fatto: non sono nemmeno da lontano la persona più adatta a parlarvene, giusto? Partiamo solo dallo StackTrace che mi veniva segnalato dall’ErrorLog di Subtext 2.0. Lo StrackTrace diceva quanto segue:
System.ArgumentException: An item with the same key has already been added. at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at Subtext.Framework.UI.Skinning.SkinTemplateCollection.GetTemplate(String skinKey) at Subtext.Framework.UI.Skinning.StyleSheetElementCollectionRenderer.GetStylesToBeMerged(String skinName, String media, String title, String conditional) at Subtext.Framework.Web.Handlers.CssHandler.HandleRequest(HttpContext context) at Subtext.Extensibility.Web.BaseHttpHandler.ProcessRequest(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
L’Exception veniva sollevata dal metodo GetTemplate() della classe SkinTemplateCollection. Li ho marcati in rosso qui sopra per evidenziarli meglio. Pare che in questo metodo ci sia un .Add() su un Dictionary, e che tale .Add() tenti di inserire per due volte la stessa key. Perchè? Perchè? Perchè?
Sono andato a beccarmi il codice incriminato. La classe SkinTemplateCollection è implementata nel namespace Subtext.Framework.UI.Skinning, nell’assembly Subtext.Framework. Ecco il metodo:
1 public SkinTemplate GetTemplate(string skinKey)
2 {
3 if (_ht == null)
4 {
5 _ht = new Dictionary<string, SkinTemplate>();
6 for (int i = 0; i < this.Count; i++)
7 {
8 _ht.Add(this[i].SkinKey, this[i]);
9 }
10 }
11
12 if (_ht.ContainsKey(skinKey.ToUpper(System.Globalization.CultureInfo.InvariantCulture)))
13 {
14 return _ht[skinKey.ToUpper(System.Globalization.CultureInfo.InvariantCulture)];
15 }
16 return null;
17 }
Riga 8 : all’interno del ciclo for c’è la chiamata .Add() incriminata, che cerca di aggiungere al Dictionary _ht, definito come privato di classe, una chiave doppia. Non sono stato lì a farmi troppe paturnie mentali. So solo che se quel ciclo for viene interrotto per qualche motivo, la return di riga (14) non verrà mai eseguita – semmai verrà restituito al chiamante un bell null. Quindi…Mi sono chiesto semplicemente: non è che all’interno dei files .config ho referenziato due volte lo stesso skin?
Dove devono essere referenziati gli skin di Subtext 2.0 ?
Io non lo sapevo: me lo sono fatto spiegare da Simone – e chi da chi altri sennò?
Gli skins vengono installati dentro la directory Skins di una normale installazione Subtext. Ogni skin viene installato in un folder separato: AnotherEnd001, DayDreaming, Gradient, KeyWest, Lightz e così via. Ma non basta, perchè bisogna gestire due files .config: uno è /Admin/Skins.config, l’altro è /Admin/Skins.user.config. Li ho scaricati in locale e li esaminati a mano, se non altro perchè hanno strutture differenti.
Mi sono quindi accorto che effettivamente lo skin GlossyBlue era referenziato due volte, puntando alla stessa directory ma scritta in modo diverso (“GlossyBlue†e “glossyblueâ€). Che sia questo il problema? Ho semplicemente cancellato il file /Admin/Skins.user.config, ho cancellato l’ErrorLog di Subtext e…stiamo a vedere. Adesso tutto sembra girare bene.
Intanto i problemi segnalati prima non li ho più: lo skin appare sempre, e posso salvare le impostazioni.
Forse, sì, dai…fra qualche lustro potrò anche fare lo sviluppare Web (cit.).
Technorati Tags: Blog subtext Open-source .NET Framework ASP.NET CodeClimber