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.
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:
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