Visual Studio 2008 non supporta .NET 1.0/1.1

Leggo con un certo disappunto dal blog di Irena Kennedy (uno dei miei preferiti, soprattutto per i suoi posts SYSK) che la prossima release di Visual Studio supporterà più versioni del .NET Framework, in modo da avere un unico ambiente di sviluppo installato (questo pensavo io). In realtà le versioni supportate del .NET Framework partono dalla 2.0, quindi 2.0, 3.0, 3.5. Quindi, in pratica, per gestire anche progetti scritti per .NET 1.0/1.1 (e sono veramente tanti in circolazione, soprattutto 1.1) occorrerà avere ancora installate più versioni di Visual Studio.

La cosa mi ha francamente deluso, e sono curioso di leggere (eventuali) feedback tecnici sul perchè di questa scelta apparentemente strana.

I want to be a developer

Chi svolge l’attività di consulente informatico, magari con mansioni di senior developer o affini, potrebbe a volte trovarsi nella condizione di vedersi offerta una attività di più alto livello rispetto al “semplice” sviluppatore, es. team leader, analista funzionale e via dicendo. Normalmente questa nuova attività porta inevitabilmente ad un progressivo allontanamento da quelli che sono gli aspetti tecnici più spinti, per concentrarsi maggiormente sul coordinamento di persone e/o attività. Questa tendenza è più accentuata in coloro che hanno maturato anni di esperienza nell’applicare sul campo la tecnologia appresa sui libri, e che arrivano ad un bel momento in cui si stancano di rincorrerre le nuove tecnologie, e preferiscono consolidare e mettere a disposizione la propria esperienza a favore di gente più giovane è più fortemente motivata a crescere. Questa è la situazione più comune in cui ci si può imbattere. Al contrario, chi mi conosce sa come la penso, ovvero che non esiste altra attività che possa regalarmi soddisfazioni se non quella di scrivere codice. Una volta, ad un colloquio di lavoro, non molto tempo fa, l’esaminatore mi chiese: “Ma Lei vuole fare il programmatore tutta la vita ?”. La mia risposta fu ovviamente SI. Non c’è nulla che possa regalarmi più soddisfazioni professionali di star dietro alle nuove tecnologie e di metterle in pratica.

Quindi:

I WANT TO BE A DEVELOPER !!!

How addicted to blogging are you ?

Ultimamente non sto bloggando molto, causa impicci di varia natura, e conto di recuperare velocemente il terreno perduto !. Ma la lettura dei blogs rappresenta un momento della giornata per me irrinunciabile, quasi paragonato a leggere la posta elettronica. Insomma, curare il proprio blog o leggere quello altrui è quasi “uno stile di vita”. A tal proposito trovo molto simpatica questa iniziativa che attraverso un breve test on line tira fuori un risultato su quanto si è “addicted to blogging”.

Sottili differenze in Visual Studio tra C# e VB .NET

Sviluppare una applicazione managed scegliendo un linguaggio piuttosto che un altro non è solo un fatto di preferenza, di predilezione o di semplice sintassi. E’ di più. Scegliere VB .NET o C#, ad esempio, significa accettare differenze che vanno al di là della preferenze personali, ma che coinvolgono anche alcune feature dell’ambiente di sviluppo. Un esempio ? In un progetto Windows Form scritto in VB .NET, l’ambiente Visual Studio visualizza il codice della form generato dal designer (la partial class per intenderci) solo se si seleziona la vista “mostra tutti i files” Nello stesso progetto scritto però in C# la stessa vista è abilitata di default. Una differenza sottile ma significativa che non ha nulla a che vedere con il linguaggio

Considerazioni molto personali sui blog ed i loro utilizzo

Questo post è da un pò di tempo che mi frullava per la testa. Riguarda l’utilizzo del proprio blog, o meglio di cosa scrivere e soprattutto non scrivere. L’occasione di decidermi (ma soprattutto di trovatre il tempo) finalmente a postare su questo argomento l’ho avuta leggendo la recentissima diatriba scatenatasi su ugidotnet sul  corretto utilizzo del proprio blog nel contronti dell’aggregatore, ovvero del muro. Premesso che il blog di ugidotnet è quello che leggo più spesso e più volentieri, insieme ai blogs di Devleap, perchè trovo interessanti i diari dei rispettivi blogger.

Qui sta il nocciolo della questione, ovvero l’utilizzo di uno strumento quale il blog viene a volte frainteso o forse viene frainteso il vero significato della parola blog.

Esso è un diario elettronico visibile pubblicamente, ma non obbligatoriamente, e di natura strettamente personale; quindi uno sul proprio blog può scrivere quello che preferisce e trattare gli argomenti che preferisce, entro i limiti della decenza e dell’educazione. Trovo assurdo il comportamento di chi si permette di censurare il contenuto dei post altrui solo perchè ritenuti fuori contesto o forse solo non graditi, o forse con il difetto di essere presenti sul muro. Leggere il blog altrui è assolutamente non obbligatorio; non è necessario sottoscrivere l’intero muro, basta sottoscrivere solo i blogs preferiti. Ma anche sottoscrivendo l’intero muro non occorre un grande sforzo a saltare i post ritenuti poco interessanti.

Molti blog che leggo o che mi passano sotto gli occhi nell’aggregator contengono post che reputo interessanti, ma anche post di autocompiacimento ed autocelebrazione, pensati soprattutto per far colpo su chi legge, moltissimi inerenti le certificazioni Microsoft o il superamento di un esame. Sia chiaro, non trovo nulla di male ad autocompiacersi per aver superato un esame di certificazione, fa parte del diario personale di una persona, e se lo trovassi noioso salterei il post, come mi capita spessissimo di fare. E’ invece un errore, a mio avviso, censurare i post altrui perchè ritenuti fuori luogo o addirittura nocivi all’immagine di una community. L’errore sull’errore sta nel pensare che altri debbano scrivere post in linea con i propri gusti, e nel sentirsi in dovere di censurarli. Questo post di Alessandro Scardova è la perfetta sistesi del mio pensiero, e su cui mi trovo perfettamente d’accordo.

Questo è anche il motivo per cui ho preferito scrivere i miei post su xplayn.org, da me fondata insieme ad un amico, e non su community certamente più affollate e sicurissimamente con un numero di pageview molto maggiore. Io non scrivo solo perchè altri possano leggere i miei post; anzi, se nessuno li leggesse per me non cambierebbe nulla, io scrivo per me stesso; se poi qualche lettore trova interessante quello che scrivo è tanto di guadagnato per me, ma non è certamente questo il mio obiettivo.

DevCon 2007, questa volta e’ vero

 

Questa volta è vero, riuscirò finalmente ad assistere ad un evento tecnico di alto spessore. Infatti mi sono iscritto alla DevCon 2007, conferenza organizzata dal gruppo Devleap che si terrà i giorni 15-16-17 Maggio a Milano, e di cui Xplayn.org ha l’onore di essere tra gli sponsor , come già comunicato qui. L’occasione di rivedere Marco Russo e la nutrita agenda di contenuti erano davvero troppo ghiotti per lascarseli sfuggire. Quindi, per una volta, le complicazioni inerenti il lavoro sono a più bassa priorità

Come già detto, chiunque assista alla conferenza e voglia condividere idee in merito può contattarmi attraverso la form contact o lasciare un commento a questo post

Deserializzazione in .NET 2.0

Il meccanismo di deserializzazione ha subito una modifica (a mio avviso migliorativa) in .NET 2.0 rispetto a quanto avveniva in .NET 1.1. La versione 2.0 ha la capacità di deserializzare un oggetto anche se questo presenta nella sua forma serializzata informazioni aggiuntive (es. membri pubblici) non presenti invece nella particolare versione dell’oggetto che  stiamo deserializzando. Mi spiego meglio. Supponiamo che abbiamo la nostra onnipresente classe Person con 3 campi pubblici, ovvero FirstName, LastName e Age, e che alcune istanze di questa classe siano serializzate in formato binario attraverso l’uso della classe BinaryFormatter utilizzando una applicazione scritta in .NET 2.0, e che il risultato della serializzazione sia memorizzato nel file BinaryPerson.dat. Un’altra applicazione, questa volta scritta in .NET 1.1, deserializza gli oggetti Person contenuti nel file binario, utilizzando però una vecchia versione dell’oggetto Person contenente solo 2 campi pubblici e non 3 (es. FirstName e LastName). In tale scenario il Framework 1.1 quando esegue il metodo Deserialize solleva una eccezione e precisamente:

An unhandled exception of type ‘System.Runtime.Serialization.SerializationException’ occurred in mscorlib.dll

Additional information: È possibile che la versione non corrisponda. Il tipo Person ha 2 membri, di cui 3 deserializzati.

In pratica in .NET 1.1 non è possibile deserializzare un oggetto (Person, nell’esempio) se lo stesso è serializzato con un numero eccedente di membri. Questo comportamento è cambiato in .NET 2.0, in quanto tutti i membri eccedenti riscontrati sono ignorati e nessuna eccezione viene sollevata.

Per completezza, nel caso di uno scenario esattamente opposto a quello descritto, cioè l’applicazione A serializza l’oggetto Person con 3 campi e l’applicazione B cerca di deserializzarlo mentre nel frattempo all’oggetto Person è stato aggiunto il quarto campo, si avrà sempre una eccezione a prescindere dalla versione del Framework utilizzata, tranne se il campo appena aggiunto viene decorato con l’attributo OptionalField. Il tal caso il nuovo campo è deserializzato con il valore null impostato.

DevCon 2007

Come già detto qui, anche quest’anno Xplayn.org sponsorizza la DevConn 2007, a mio avviso (e non solo) la conferenza italiana di più alto spessore tecnico su prodotti e tecnologie Microsoft, sia per i contenuti, sempre molto interessanti ed innovativi, sia per la valenza degli speakers.

Basta leggere l’agenda dei contenuti per rendersene conto: ASP .NET Ajax, Presentation Foundation, Workflow Foundation, SharePoint 2007, Visual Studio Team System, DSL, Reporting Services, Communication Foundation, II7, SQL Compact Edition, BizTalk, Data Warehouse. L’insieme di questi argomenti costituisce lo stato dell’arte su tecnologie e prodotti Microsoft. Per farla breve, una conferenza di altissimo livello.

Impegni lavorativi permettendo, quest’anno farò tutto il possibile per assistervi. Chiunque fosse interessato a assistere alla conferenza ed a condividere idee in merito agli argomenti trattati può contattarmi attraverso la form contact o lasciare un commento a questo post.

Uso di reflection per invocare metodi interni

In un post precedente ho parlato dell’uso dell’attributo AllowPartiallyTrustedCallers a proposito della sicurezza applicata all’invocazione di metodi pubblici definiti all’interno di un assembly strong-named.  Rimanendo sempre sullo stesso tema, un altro attributo utile a “limitare” i possibili chiamanti di un determinato metodo è StrongNameIdentityPermissionAttribute, usato in questo modo:

[StrongNameIdentityPermissionAttribute(SecurityAction.LinkDemand, PublicKey = “public key”)]
public string MyMethod(string parameter) {}

La presenza di questo attributo permette la chiamata al metodo MyMethod dell’esempio solo al codice contenuto in un assembly firmato con strong name e che presenta la chiave pubblica specificata nell’attributo stesso. Qualsiasi altro codice che tentasse di invocare il metodo in questione provoca una eccezione del tipo SecurityException. Questa forma di sicurezza è la più affidabile a disposizione se vogliamo proteggere ad esempio metodi sensibili dall’invocazione da parte di codice maligno. Se invece il metodo in questione non è invocato dall’esterno dell’assembly, in altre parole non è public, potremmo pensare che basterebbe limitare il suo ambito di visibilità (es.: private, internal in C# oppure friend in VB.NET) per renderlo sicuro da chiamate da parte di codice non affidabile. Putroppo questa convinzione è errata, poichè attraverso l’uso delle tecniche di reflection può essere invocato qualsiasi metodo con qualsiasi ambito di visibilità, quindi anche i metodi marcati come internal o private. Infatti, utilizzando il tool Reflector oppure semplicemente ildasm è possibile leggere la firma di metodi con qualsiasi visibilità (quindi public, private, protected ed internal). Se il metodo MyMethod fosse “internal”, conoscendo la sua firma è possibile invocarlo da un altro assembly via reflection in questo modo:

object x = Activator.CreateInstanceFrom(“MyAssembly.dll”, “MyAssembly.MyNamespace”).Unwrap();
string result = x.GetType().InvokeMember(“MyMethod”, System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance  
      | System.Reflection.BindingFlags.NonPublic, null, x, new object[] { “string parameter” }) as string;

bypassando quindi la protezione imposta dal livello di visibilità.

Da notare che richiamare un metodo non pubblico attraverso reflection richiede il permesso ReflectionPermission, impostabile attraverso l’uso dell’attributo ReflectionPermissionAttribute (in modo dichiarativo), oppure in modo programmatico.

In assenza di questo permesso è possibile invocare via reflection solo i metodi pubblici.

String intern pool

L’Intern pool, di cui non è la prima volta che ne parlo, è un hashtable mantenuto internamente dal CLR contenente stringhe generalmente usate per memorizzare valori costanti. In questo hashtable sono memorizzate le costanti stringa a livello di compilazione ed ogni stringa aggiunta esplicitamente attraverso l’utilizzo del metodo string.Intern, il quale aggiunge una stringa nell’intern pool (quindi nell’hashtable) e ne ritorna il riferimento se la stessa non è già presente, in caso contrario  ritorna sempicemente il riferimento ad essa. In questo modo è garantito che se due stringhe (o più) contengono gli stessi valori letterali sarà utilizzato (e quindi sarà presente in memoria) un unico riferimento, con evidente risparmio di risorse. Oltre a questo metodo, il metodo string.IsInterned ritorna il riferimento alla stringa nell’intern pool se presente, null in caso contrario.

L’intern pool è utile in opportuni scenari, ma ha un grosso svantaggio: poichè ogni stringa memorizzata nel pool è mantenuta all’interno di un hashtable interno del CLR, ne consegue che ogni stringa risulterà sempre raggiungibile dall’applicazione e quindi sopravviverà ad ogni garbage collector (poichè l’hashtable ne mantiene un riferimento). L’hashtable (e le stringhe in esso memorizzate) sarà distrutto e la memoria occupata reclamata solo quando il relativo appDomain (o processo) terminerà.

Come già detto, tutte le stringhe costanti sono inserite nell’intern pool automaticamente e quindi la memoria occupata non sarà reclamata fino a che il processo termina.  Questo comportamento è dimostrato dal seguente codice:

string a = “teststring”;
string b = “teststring”;
string x = string.IsInterned(a);
string y = string.IsInterned(b);
if (x != null)
    Console.WriteLine(“string a is interned”);
if (y != null)
    Console.WriteLine(“string b is interned”);
Console.WriteLine(object.ReferenceEquals(a,b));

L’output prodotto è il seguente:

string a in interned
string b is interned
true

Se questo comportamento non è quello desiderato è possibile utilizzare l’attributo a livello di assembly CompilationRelaxationsAttribute (namespace System.Runtime.CompilerServices), il quale permette disabilitare l’utilizzo dell’intern pool di stringhe da parte dell’assembly in cui l’attributo è definito, in questo modo:

[assembly: CompilationRelaxations(CompilationRelaxations.NoStringInterning)]

Applicando questo attributo sarebbe lecito aspettarsi che l’intern pool di stringhe non sia più gestito. Invece non è così, nonostante la documentazione MSDN affermi il contrario. Sembra che questo attributo non abbia alcun effetto pratico se non negli assembly precompilati in codice nativo con l’utility NGEN. In altre parole, inserendo o non inserendo l’attributo, l’intern pool è comunque gestito dal CLR, a meno che non si precompili l’assembly con NGEN.

Come controprova di quanto affermato è possibile eseguire il codice sopraindicato con o senza l’attributo CompilationRelaxations. L’output sarà in ogni caso identico, e dimostrerà che le 2 stringhe sono inserite nell’intern pool.

Mi piacerebbe conoscere pareri di eventuali altri sviluppatori che hanno già riscontrato questo comportamento.

TechEd 2007 sto arrivando (lo spero)

Anche quest’anno parto con lo stesso obiettivo ben preciso: assistere ad una conferenza Microsoft oltreoceano.

L’obiettivo è puntato sul TechEd 2007 che si terrà in quel di Orlando, Florida, dal 4 al 8 Giugno prossimi. Non mi faccio troppe illusioni perchè la mia attività (frenetica) di consulente mi ha sempre impedito per un motivo o per l’altro di assistere in passato ad altre conferenze simili.

Comunque, prima o poi l’occasione capita, e non me la lascerò certo sfuggire . Approfitto di questo post per estendere l’invito ad assistere al TechEd 2007 a tutti coloro che fossero interessati a partecipare, ma che, magari sono restii ad andare da soli . Quindi chiunque voglia farsi un viaggetto in Florida in occasione del TechEd 2007 può lasciare un commento a questo post oppure attraverso il form contact può inviarmi il proprio indirizzo mail o MSN, e sarà da me ricontattato.

Statistiche in ADO .NET 2.0

In ADO .NET 2.0 è possibile programmaticamente ottenere delle informazioni statistiche circa l’uso di una connessione ad un database. Bastano infatti solo 2 righe di codice:

connSQL.StatisticsEnabled = true;
System.Collections.IDictionary statsDict = connSQL.RetrieveStatistics();

per ottenere un dictionary di valori statistici validi nel momento in cui il metodo RetrieveStatistics() è invocato.
Tratto dalla documentazione MSDN, ecco un elenco (parziale) dei valori statistici più interessanti:

NetworkServerTime

Restituisce il tempo cumulativo atteso dal provider prima di ricevere una risposta dal database server, a partire dal momento in cui le statistiche sono abilitate.

PreparedExecs

Restituisce il numero dei comandi precompilati eseguiti, a partire dal momento in cui le statistiche sono abilitate.

Prepares

Restituisce il numero delle istruzioni precompilate eseguite, a partire dal momento in cui le statistiche sono abilitate.

SelectCount

Restituisce il numero delle istruzioni SELECT eseguite, a partire dal momento in cui le statistiche sono abilitate, incluse le istruzioni FETCH usate per leggere le righe da un cursore; il conteggio delle SELECT è aggiornato quando viene raggiunta la fine di un SqlDataReader

SelectRows

Ritorna il numero delle righe interessate, a partire dal momento in cui le statistiche sono abilitate. Il conteggio comprende tutte le righe generate da istruzioni SQL, anche se non utilizzate dal chiamante, ad esempio eventuali righe derivanti da un data reader chiuso prima di leggere l’intero resultset oppure le righe di un cursore.

ServerRoundtrips

Ritorna il numero di volte in cui viene inviato un comando al server ed attesa la conseguente risposta, a partire dal momento in cui le statistiche sono abilitate.

Transactions

Restituisce il numero delle transazioni utente iniziate, a partire dal momento in cui le statistiche sono abilitatea prescindere se andate a buon fine o no. In caso di auto commit impostato su on ogni comando è considerato una transazione.

UnpreparedExecs

Ritorna il numero delle istruzioni non compilate eseguite, a partire dal momento in cui le statistiche sono abilitate.

Curiosando il metodo RetrieveStatistics() con il tool Reflector si nota che esso utilizza una classe interna dell’assembly System.Data, precisamente SqlStatistics, marcata appunto come “internal sealed” (C#), oppure “Friend NotInheritable” (Visual Basic .NET). Quindi la suddetta classe non è nè visibile dall’esterno dell’assembly System.Data nè tantomeno ereditabile.

Taggato !!

Speravo di farla franca ma l’amico Mighell ha pensato bene di taggarmi ! Quindi adesso tocca a me: ecco le 5 cose che pochissime persone (forse nessuna…) conosce di me:

1) Ho tante passioni che non riesco a vivere come vorrei causa mancanza di tempo (chiamateli hobby….) e sono, in ordine sparso: astronomia, astrofisica, fisica quantistica, scacchi (il mio sogno è stato sempre battermi con l”International Woman Grandmaster Alexandra Kosteniuk, senza però che pensate a male ), tecnologia in generale. Insomma, roba pesante, e qui mi fermo perchè altrimenti divento prolisso! E’ chiaro che sono sempre stato attratto dalle cose complesse….il primo linguaggio di programmazione che ho affrontato sul serio è stato il C.

2) All’età di 5-6 anni ho rischiato seriamente di morire bevendomi, a causa della mia curiosità già supersviluppata, nientepopodimeno che …..la varechina ! Mi ha salvato una immediata lavanda gastrica (fortunatamente l’ospedale era giusto di fronte a casa mia…)

3) Il mio più grande cruccio è quello di non aver affrontato sul serio la scuola (anche se sono riuscito comunque a diplomarmi), e soprattutto di non aver intrapreso gli studi universitari (non è mai troppo tardi direbbe qualcuno, ma…)

4) Adoro la musica rock-blues e la chitarra elettrica; la folgorazione è avvenuta all’età di 15-16 anni ascoltando i mitici Led Zeppelin, e la musica dei Doors

5) Ho 4 nipotini a cui voglio un mondo di bene; uno in particolare, si chiama Alessandro, mi somiglia tantissimo, in tutti i sensi, è come se vedessi me stesso allo specchio quando avevo 8-9 anni.

E adesso, tagghiamo, tagghiamo, anche se sono arrivato tardi e la lista si è alquanto ristretta: Francesco Quaratino, Gianluca Cannalire, Marco Russo, Vito Carella, Antonello Tesoro

Verificare che il .NET Framework sia installato e relative versioni

Per verificare che il .NET Framework sia installato ed eventualmente in quali versioni è possibile procedere in questo modo:

  • La semplice presenza del file MSCOREE.DLL (Microsoft .NET Runtime Execution Engine) nella directory %SYSTEMROOT\system32 è sintomo che almeno una versione del CLR è installata
  • La chiave del registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy contiene delle sottochiavi, una per ogni versione installata, nella forma vX.X (es. v2.0)
  • La versione 2.0 del  .NET Framework contiene una nuova utility denominata CLRVer.exe, che, come il suo nome lascia intuire, elenca tutte le versioni del CLR installate sulla macchina su cui viene eseguita. Molto interessanti sono i parametri -all, che elenca tutte le applicazioni managed in esecuzione con la relativa versione del CLR con cui girano, e -PID, con cui è possibile ottenere lo stesso risultato ma relativamente ad un singolo processo identificato dal suo process ID

Chat su metodologie Agili

Anche questa chat è stata per me molto interessante, un vivace incontro virtuale in cui ognuno ha cercato di esporre le proprie idee sulla base della esperienza professionale quotidiana. Nonostante condivida in pieno metodologie quali TDD, Refactoring, user story, ecc, mi sorge spontanea la riflessione, dettata unicamente dalla mia esperienza sul campo, che spesso queste metodologie sono inapplicabili nella vita reale. L’inapplicabilità deriva dal fatto che queste metodologie non sono riconosciute e neanche comprese dall’utente finale delle applicazioni, ovvero il cliente. A me sinceramente riesce difficile, se non impossibile, schedulare il tempo per eseguire Unit Test, quando so perfettamente che questa attività, benche la ritenga fondamentale, non è riconosciuta dal management tecnico oppure, nel migliore dei casi, non c’è il tempo materiale per metterla in atto, spesso per mancanza di conoscenza sull’argomento dei vari membri del team di sviluppo. Io personalmente questa attività la svolgo al di fuori del contesto lavorativo, per i motivi sopracitati, perchè la ritengo fondamentale per essere certi di rilasciare codice funzionante in ogni contesto. Molto interessante è stato il dialogo con Tiziana sulla qualità del software. Sono consapevole che scrivere software di qualità costa tanto, se non di meno, quanto scrivere codice di scarsa qualità, ma dipende dal contesto e dalla realtà in cui ci si trova. A volte non è proprio possibile, perchè purtroppo si preferisce la soluzione più rapida nell’immediato (ma solo in apparenza), ma che il più delle volte risulta onerosa da gestire e niente affatto scalabile.

Altra chat

Vista la buona riuscita del primo esperimento, Emanuele ha deciso di riprovarci. Sto parlando della seconda chat tecnica che avrà come oggetto le metodologie “Agili”, con la partecipazione di Luca Minudel. E’ davvero una bella esperienza partecipare a queste “tavole rotonde virtuali”, al di là dell’argomento trattato. La chat si terrà nuovamente via Messenger il 19 dicembre prossimo alle ore 21.00. Chiunque volesse partecipare può contattarmi attraverso la form contact oppure lasciando un commento a questo post, inviandomi il suo indirizzo MSN. Non mancate !

Chat tecnica sui Design Pattern e dintorni

Stasera ho partecipato alla prima chat tecnica organizzata da Emanuele, a cui ha partecipato anche Riccardo Golia, Vito Arconzo, Alessandro MelchioriRoberto Vespa e MatteoB. La chat si è svolta via MSN, e l’argomento era “i design pattern”. Devo ammettere che ero un pò scettico sulla riuscita della iniziativa, temevo che una cosa del genere fatta via Messenger avrebbe retto poco. Sono contento di essermi sbagliato, perchè non solo siamo riusciti bene o male a seguire quello che gli altri avevano da dire sull’argomento, in poche parole ad interagire nonostante a volte partissero 2 o 3 thread contemporaneamente, ma siamo anche riusciti ad “accendere” le discussioni su argomenti per me molto di attualità e sentiti, legati chiaramente al nostro mestiere di consulente informatico. Quindi è stata una bella esperienza, che ripeterei senza lasciarmelo dire 2 volte. La prossima volta Emanuele ha in mente di dedicare la chat alla programmazione “Agile”, e per tenere alto il livello dovrebbe essere dei nostri un vero esperto in materia, Luca Minudel. Chiunque voglia partecipare può contattarmi attraverso il form contact di questo blog.

App_offline.htm e i 512 byte

Nonostante qualche commento negativo letto in Rete, a me il comportamento di ASP .NET 2.0 in presenza del file app_offline.htm nella root della web application mi sembra abbastanza comodo e funzionale. Ricordo che questo file è utile quando si è in fase di manutenzione della propria applicazione web e si vuol fornire un messaggio “user friendly” agli utenti informandoli che l’applicazione non è momentaneamente disponibile, o qualsiasi cosa si voglia. In presenza di un file con tale nome infatti, l’engine di ASP .NET 2.0 effettua lo shutdown dell’applicazione, scarica l’appDomain e risponde ad ogni richiesta dei files normalmente gestiti dallo stesso engine con il file app_offline.htm appunto, permettendo in questo modo di non far incorrerere in errori eventuali richieste che avvengono mentre il sito è in manutenzione. Basterà poi rinominare, cancellare o spostare il suddetto file affinchè le pagine richieste siano elaborate nel modo consueto. Comodo no ? Ma cè un problema, aggirabile, ma pur sempre un problema. Internet Explorer 6.0 ha una impostazione chiamata “Mostra messaggi di errore HTTP brevi”. Questa impostazione di default è vera, e significa che qualsiasi messaggio HTTP diverso da 200 il cui contenuto non eccede il 512 byte, verrà mostrato da IE in modo cosiddetto “user frendly” per l’utente, fornendo un messaggio generico di errore che non lascia capire nulla circa la vera causa dell’errore. Qui nasce il problema: se il file app_offline.htm è più piccolo di 512 byte non è correttamente visualizzato ma al suo posto viene ritornato un errore HTTP (quindi un codice diverso da 200) che, in presenza della impostazione “Mostra messaggi HTTP brevi” su “on” provoca un errore generico. Non capisco come un messaggio di errore generico possa essere ritenuto “user friendly” per l’utente. Per la mia esperienza non fa altro che disorientarlo ancor di più. La soluzione al problema è ovviamente creare il file app_offline con una dimensione maggiore di 512 byte (oppure fare in modo che lo sia aggiungendo ad esempio commenti fittizi nel codice HTML), oppure disabilitare l’impostazione “mostra messaggi di errore http brevi”

Failed to open a table in Sql Profiler

Applicare un service pack è una operazione che andrebbe meditata un pò, almeno andrebbe fatta dopo aver letto quali sono le fix apportate e quali sono gli eventuali impatti. A volte un però l’applicazione di un service pack provoca che una qualche funzionalità smette di ….funzionare. A parte gli scherzi, applicando il service pack 4 a Sql Server 2000 diventa impossibile aprire un trace table con Sql Profiler a causa del seguente errore bloccante:

“Failed to open a table”.

Soluzione immediata ? Aprirlo con il profiler di Sql Server 2005.

Il tutto è ampiamente documentato in questo articolo della KB Microsoft