May 2007 - Posts
La domanda, direbbe qualcuno, sorge spontanea. Non hanno fatto un'ottima impressione, infatti, nel rilasciare la SP per Vista ben oltre il 30 gennaio. E la situazione attuale non è un granché bella: per lavorare con Visual Studio su Vista (sono reduce da una reinstallazione completa) ho dovuto installare nell'ordine:
- Visual Studio
- SP1
- SP per Vista
- SQL Server Express con relativo SP
- ASP.NET 2.0 AJAX Extensions 1.0
seguiti da una serie di tools (AJAX futures CTP, AJAX Control Toolkit, starter kit vari, Web Deployment, ecc. ecc.). Senza contare che dopo questi aggiornamenti, Visual Studio (che ho in inglese) si presentava ibrido, ossia mezzo in italiano e mezzo in inglese, come visibile nel ritaglio seguente. E con una serie di conseguenze indesiderate, come l'assenza dei template di progetto, errore nell'apertura della guida in locale (funzionava solo quella on line).
Ci ho messo un po' per capire che per rimettere tutto a posto basta impostare di nuovo la lingua in inglese invece che "Come Microsoft Windows" (impostazione cambiata in automatico dall'aggiornamento).
Ieri, invece, un nuovo problema. Sto lavorando a dei siti web multilingua, per i quali sto cercando delle soluzioni eleganti che implementino la localizzazione dei contenuti tenendo conto anche di teniche di SEO. Di questo ne parlerò in un prossimo post, appena avrò trovato una soluzione ottimale, mentre quella ipotizzata in prima analisi in questo post è stata rivista proprio perché non è adeguata ad offrire visibilità ai motori di ricerca.
Per ora sto sperimentando tecniche di URL rewriting, che in fase di sviluppo hanno un inconveniente: è necessario, infatti, fornire un indirizzo assoluto alle risorse per le quali non si prevede la riscrittura dell'URL, come ad esempio le immagini.
Ma lavorando su un sito web sul filesystem locale, e non su IIS, il progetto parte non in una root, ma in una sottodirectory, come se fosse una directory virtuale su IIS, per cui si complica la scrittura degli handler delle immagini e si hanno problemi con gli indirizzi assoluti delle altre risorse.
Cercando su Internet sono arrivato a questo articolo, in cui è spiegato chiaramente come grazie al SP1 è molto semplice impostare in Visual Studio le proprietà del sito web affinché venga avviato in un virtual path di root.
A questo punto si verifica il problema: al momento di pubblicare il sito, la pubblicazione viene saltata a causa di un errore descritto come "Index was outside the bounds of the array"

È ancora Scott Guthrie a fornirmi la soluzione, riferendosi ad una Public Hotfix Patch for VS "Index was outside the bounds of the array" Publish Website Issue. (Ovviamente il suo blog è entrato di prepotenza nel mio blogroll)
Pertanto ho effettuato il download della patch e l'ho installata. Risultato: di nuovo la lingua incasinata e l'errore nella pubblicazione tale e quale a prima.
Leggendo i commenti allo stesso post, scopro che altri utenti con Vista lamentavano l'inefficacia della patch, che invece aveva risolto il problema su altri OS.
Per fortuna in uno di questi commenti ho trovato la soluzione ai miei problemi. In pratica la patch avrebbe dovuto sostituire un file di Visual Studio (C:\Program Files\Microsoft Visual Studio 8\Common7\Packages\mswebprj.dll) portandolo indietro dalla versione 8.0.50727.867 datata 22/2/2007 alla 8.0.50727.813 datata 28/2/2007 (data successiva, numero versione precedente).
Per un motivo inspiegabile, però, questo su Windows Vista non avviene. È necessario pertanto applicare la patch ad una copia di Visual Studio installata su una macchina con un altro SO e copiare a mano il file incriminato sul PC con Windows Vista, risolvendo tutti i problemi.
Possibile che nessuno abbia avvisato il Team di sviluppo di Visual Studio dell'uscita di Windows Vista?
View blog reactions
Qualche giorno fa ho scaricato PureText, una mini-utility per incollare il testo della clipboard senza formattazione (dopo averne letto la recensione in questo post).
PureText non ha bisogno di installazione (si tratta di un singolo file eseguibile di 28KB) e una volta avviato, compare un'iconcina nella tray-area e dopo aver copiato un testo, basta la combinazione
+V per incollare il testo "purificato".
Nella finestra delle opzioni, inoltre, è possibile scegliere se avviare PureText in automatico.
Allora ho creato nella cartella programmi una sottocartella PureText e ho copiato lì l'eseguibile. Poi l'ho avviato ed ho settato l'opzione dell'avvio automatico.
Al successivo riavvio, però, mi è apparsa una schermata di un avviso di protezione, in cui mi si chiedeva se volessi eseguire il file PureText.exe.
Poco male, ho tolto la spunta dove dice "Avvisa sempre prima di aprire questo file" e l'ho eseguito, convinto che al prossimo riavvio sarebbe partito senza problemi. Invece non è stato così, perché il giorno dopo, riacceso il PC, di nuovo mi è apparsa la stessa richiesta. Sono andato perciò direttamente sul file eseguibile e nella finestra proprietà ho trovato che il file, essendo stato scaricato dalla rete, risultava bloccato.
Anche in questo caso, però, un comodo pulsante annulla blocco sembrava essere la risoluzione del problema. Ho perciò annullato il blocco, ma anche così facendo al riavvio ho ottenuto di nuovo l'avviso di protezione. Tornando a vedere le proprietà del file, questo risultava ancora bloccato.
Probabilmente ciò è dovuto al fatto che la cartella programmi richiede autorizzazioni speciali, sta di fatto che alla fine per risolvere il problema ho:
- copiato l'eseguibile sul desktop
- annullato il blocco
- copiato l'eseguibile dal desktop alla cartella programmi, sovrascrivendo l'esistente
ed al riavvio il programma è partito senza fare domande.
Adottando la stessa tecnica ho risolto un problema analogo sul PC di un collega, anche lui con Vista Business. Nel suo caso era un eseguibile nella cartella Programmi relativo alla scheda audio, che era stato impostato per essere eseguito al login dalla procedure di installazione dei driver della scheda audio, anche questi scaricati da Internet.
Per non avere questi problemi è necessario, perciò, annullare il blocco dei file scaricati da Internet prima di installarli o di copiarli in una cartella protetta come quella programmi.
Technorati tags:
vista,
windows View blog reactions
Windows Vista è il primo sistema operativo Microsoft che è stato lanciato nell'era dei blog. Pertanto è disponibile in rete un mare di informazioni su questo OS, sin da prima del lancio stesso. Insieme alle informazioni, però, è facile trovare anche un'enorme quantità di bufale, probabilmente anche in misura maggiore delle prime.
L'universo dei blog, infatti, comprende tantissimi utenti e spesso la qualità delle informazioni trovate in rete lascia a desiderare. Si assiste, inoltre, a catene in cui un blogger fornisce un'informazione sbagliata e centinaia di altri la ripetono, citandolo e citandosi come fonte, senza che nessuno si preoccupi di verificarne la veridicità.
Di questo tema ha scritto qualche giorno fa Jeff Atwood nel post intitolato "Apparently Bloggers Aren't Journalists", in cui sostanzialmente afferma che i blogger non sono giornalisti professionisti. Questi, infatti, sono tenuti a verificare da diverse fonti le informazioni, a cercare gli interessati per un contradditorio, a verificare l'affidabilità delle fonti stesse, ecc. (evidentemente Jeff non conosce il giornalismo italiano
), mentre i blogger no.
Però, secondo lui (ed io sottoscrivo), prima di mettere un link ad un claim qualsiasi, ogni blogger dovrebbe verificare la notizia ("do their homework").
In attesa che ogni blogger verifichi quello che scrive, può essere utile consultare Bufale in Vista. È una pagina web, da poco on line, dove paperino ha raccolto i post in cui smaschera alcune delle bufale che si possono leggere in giro su Windows Vista.
Conoscendo paperino, ma anche leggendo da tempo i suoi post, sono certo che non l'ha fatto per partecipare all'ennesima guerra di religione in ambito software. Semplicemente gli è proprio difficile accettare senza controbattere il FUD sparso in giro, per cui ha fatto i compiti a casa e fornito le prove che tanti claim in realtà sono semplicemente delle sciocchezze.
Technorati tags:
vista,
windows View blog reactions
Grazie a Beppe (o forse per colpa sua
) ho scoperto questo addon gratuito per Windows Live Messenger che, tra l'altro, permette di imitare il proprio interlocutore, ossia far sembrare che sia lui a scrivere.
Io sarei "ideologicamente" contrario a questi addon (spesso includono spyware, speriamo non sia questo il caso), però devo ammettere che è davvero esilarante vedere il proprio interlocutore andare nel panico 
View blog reactions
Nel poco tempo a disposizione nell'ultima settimana (una motherboard si è rotta e la nuova si è rivelata difettosa giusto alla fine delle reinstallazioni e ripristino dati) ho provato ad arricchire questo blog con alcuni accessori, come snapshot per i link. Dopo essermi registrato su Technorati, inoltre, ho aggiunto ai post già scritti (tanto sono ancora pochi) i Technorati tags e ho voluto provare ad aggiungere a ciascuno di essi il Link Count Widget, ossia un'indicazione di quanti sono i blog che linkano quel post (per la cronaca, ancora nessuno fino ad ora
).
Per aggiungere tale feature su Community Server bisogna inserire in ogni post questo snippet in HTML:
<script src="http://embed.technorati.com/linkcount" type="text/javascript">
</script>
<a class="tr-linkcount" href="http://technorati.com/search/{URL}">
View blog reactions</a>
In realtà la prima parte può essere messa una volta per tutte nell'header HTML delle pagine del blog, specificandolo nella Dashboard relativa al proprio account. Nella seconda parte, invece, bisogna sostituire a {URL} l'indirizzo completo del post in questione.
Il problema è che l'indirizzo del post non è noto fino a che il post non viene pubblicato, anche se è ricavato dal titolo dello stesso e dalla data di pubblicazione con un semplice algoritmo. Un metodo semplice per ovviare a questo inconveniente sarebbe di scrivere al posto di {URL} un'espressione di DataBind del tipo:
<%# BlogUrls.Instance().Post(WeblogControlUtility.Instance()
.GetCurrentWeblogPost(this)) %>
Purtroppo, per ovvi motivi di sicurezza, non è possibile inserire espressioni di DataBind in un post (sarebbero codificate e rese innocue). Pertanto, non avendo accesso alle impostazioni di administrator della piattaforma, l'unica scelta sembrava quella di una doppia pubblicazione, con l'inserzione manuale dello snippet e dell'URL solo in seconda battuta.
Una leggera semplificazione, però, si può ottenere grazie ad un semplice plugin per Live Writer, che sia in grado di automatizzare parte della procedura ed evitare di dover inviare due volte il post (suggerimento di Paperino).
Per farlo da qui ho scaricato da qui Windows Live Writer SDK, l'ho installato ed ho dato un'occhiata alla documentazione ed al plugin di esempio (HelloWorldPlugin), da cui ho capito che per risolvere il mio problema avrei dovuto scrivere un Simple Content Source Plugin. Come source per il content avrei dovuto un Insert Dialog.
I passi per la creazione di un Content Source Plugin dalle caratteristiche indicate sono i seguenti:
- creare un nuovo progetto Class Library in Visual Studio;
- aggiungere una reference all'assembly WindowsLive.Writer.Api (che si trova nella stessa cartella dell'eseguibile di Windows Live Writer, ad es: C:\Programmi\Windows Live Writer);
- creare una nuova classe, nel mio caso TLCWPlugin, derivata dalla classe ContentSource;
- aggiungere a questa classe gli attributi WriterPluginAttribute e InsertableContentSourceAttribute e scrivere l'override del metodo CreateContent.
Se si aggiunge alle opzioni di compilazione la nei post-build event command line
XCOPY /D /Y /R "$(TargetPath)" "C:\Programmi\Windows Live Writer\Plugins\"
allora la dll generata sarà copiata direttamente nella directory dei plugin di Live Writer per essere provata.
Il codice risultante è (in VB.NET):
Imports System
Imports System.Windows.Forms
Imports WindowsLive.Writer.Api
<WriterPlugin("ce9a848e-c786-4e54-a0e2-1abff354e396",
"Technorati Link Count Widget", ImagePath:="Technorati.png", _
Description:="Insert Technorati Link Count Widget in your post.", _
PublisherUrl:="http://www.webis.it")> _
<InsertableContentSource("Technorati Link Count Widget", _
SidebarText:="Link Count Widget")> _
Public Class TLCWPlugin
Inherits ContentSource
Public Overrides Function CreateContent( _
ByVal dialogOwner As System.Windows.Forms.IWin32Window, _
ByRef newContent As String) As System.Windows.Forms.DialogResult
Using InsertForm As TLCWInsertForm = New TLCWInsertForm
Dim risultato As DialogResult = InsertForm.ShowDialog
If risultato = DialogResult.OK Then
newContent = InsertForm.Stringa
End If
Return risultato
End Using
End Function
End Class
Come si può vedere nell'attributo WriterPluginAttribute, oltre a id e nome, è possibile specificare anche altre informazioni, quali l'icona del plugin (una immagine embedded di dimensioni 20x18). Nell'attributo InsertableContentSource, inoltre, si può specificare un testo per la Sidebar diverso da quello del menù (c'è meno spazio).
Nel corpo del metodo CreateContent, invece, il codice non fa altro che aprire una finestra di dialogo con la form TLCWInsertForm, in cui sarà fatto tutto il lavoro.
Se la finestra è chiusa con DialogResult.OK (Insert), allora verrà inserito il nuovo contenuto, prelevandolo dalla proprietà pubblica Stringa della classe TLCWInsertForm.
Il codice per la proprietà è semplicemente:
Private _Stringa As String
Public Property Stringa() As String
Get
Return _Stringa
End Get
Set(ByVal Value As String)
_Stringa = Value
End Set
End Property
(scritto ancora più velocemente grazie a questa macro di Francesco Balena, leggermente modificata, che trasforma field in proprietà)
Al caricamento della form viene eseguito il codice seguente, che carica (se presenti) le impostazioni memorizzate per il plugin, ossia l'URL del blog[1] e la presenza nell'header HTML del tag script:
Private Sub TLCWInsertForm_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
Me.DateTimePicker1.Value = Date.Today
Me.Stringa = ""
Me.LoadSettings()
Me.TextBoxBlogUrl.Text = Me._blogUrl
Me.CheckBoxJsInHeader.Checked = Me._checked
Me.LabelNote.Visible = Not Me.CheckBoxJsInHeader.Checked
End Sub
Private Sub LoadSettings()
Dim fs As FileStream = Nothing
Dim rd As StreamReader
Me._blogUrl = Me._defaultBlogUrl
Me._checked = Me._defaultChecked
Try
fs = New FileStream(Me._configPath & Path.DirectorySeparatorChar & _
Me._configFileName, FileMode.Open)
rd = New StreamReader(fs)
Me._blogUrl = rd.ReadLine().Trim
If CBool(rd.ReadLine) = True Then
Me._checked = True
End If
Catch ex As Exception
Finally
If fs IsNot Nothing Then
fs.Close()
End If
End Try
End Sub
Invece alla pressione di Insert, vengono effettuati controlli sulla presenza dei campi obbligatori, viene calcolato l'url in base alla data (di default è impostata quella di sistema) ed al titolo (attraverso la funzione UrlEncode), si imposta la proprietà Stringa e vengono salvate le impostazioni se sono cambiate.
Private Sub ButtonOK_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles ButtonOK.Click
If DatiValidi() Then
Dim url As String
url = TextBoxBlogUrl.Text
If Not url.EndsWith("/") Then
url &= "/"
End If
url &= DateTimePicker1.Value.Year.ToString & "/" & _
DateTimePicker1.Value.Month.ToString("00") & "/" & _
DateTimePicker1.Value.Day.ToString("00") & "/" & _
UrlEncode(TextBoxPostTitle.Text, _
New Regex("([^A-Za-z0-9 ]+|\.| )", _
(RegexOptions.Singleline Or RegexOptions.Compiled)), "-"c, "_"c) & _
".aspx"
Me.Stringa = String.Format(Me._technoratiString, url)
If CheckBoxJsInHeader.Checked = False Then
Me.Stringa = Me._technoratiJavascript & Me.Stringa
End If
If Not Me.SaveSettings() Then
MsgBox("Error while saving your settings.")
End If
Else
Me.DialogResult = Windows.Forms.DialogResult.None
End If
End Sub
Private Function SaveSettings()
Dim risultato As Boolean = True
' salva solo se le impostazioni sono cambiate
If (Me._blogUrl <> TextBoxBlogUrl.Text) OrElse _
(Me._checked <> CheckBoxJsInHeader.Checked) Then
Dim wr As StreamWriter = Nothing
Try
If Not Directory.Exists(Me._configPath) Then
Directory.CreateDirectory(Me._configPath)
End If
wr = My.Computer.FileSystem.OpenTextFileWriter(Me._configPath & _
Path.DirectorySeparatorChar & Me._configFileName, False)
wr.WriteLine(TextBoxBlogUrl.Text)
wr.WriteLine(CheckBoxJsInHeader.Checked.ToString)
Catch ex As Exception
risultato = False
Finally
If wr IsNot Nothing Then
wr.Close()
End If
End Try
End If
Return risultato
End Function
Per quanto riguarda la funzione:
Private Function UrlEncode(ByVal titolo As String, _
ByVal pattern As Regex, _
ByVal spaceReplacement As Char, _
ByVal escapePrefix As Char) As String
è stato abbastanza semplice estrapolarla dal binario di Community Server, grazie a Reflector for .NET ed è disponibile insieme al codice completo qui.
Nota bene: per chi non potesse o non volesse mettere nell'header HTML il tag script, è presente anche una checkbox apposita, il cui valore rimane memorizzato per la volta successiva. Attenzione: questa feature deve essere utilizzata in modalità HTML Code, posizionando il cursore al di fuori di qualsiasi container HTML, altrimenti il tag script verrà semplicemente ignorato da Live Writer. Non sono riuscito, infatti, a trovare un modo per costringere il plugin ad aggiugere il content alla fine di tutto il testo (forse non esiste).
Il plugin è scaricabile liberamente da qui (TechnoratiLinkCountWidget.zip - 12KB), mentre il codice completo è qui (TLCWplugin.zip - 570KB).
View blog reactions
[1] L'URL del blog deve comprendere anche la subdirectory dove vengono archiviati gli articoli, ad esempio su dotnetside per il mio blog si avrebbe: http://www.dotnetside.org/blogs/lucab/archive
Un esercizio potrebbe essere di aggiungere alle opzioni del plugin un piccolo parser che costruisca l'URL in base ad un formato impostato dall'utente.
Ho trovato alcuni siti interessanti su Windows Vista, che mi sembrano utili da consultare per cominciare a prendere confidenza con questo sistema operativo.
Windows Vista for beginners è un sito che costituisce un'utile guida alle nuove caratteristiche ed ai cambiamenti introdotti da questo sistema operativo rispetto a Windows XP. Il sito è in inglese ed è consultabile anche per sezioni (Tutorials, Where to find..., New Apps, Extra, ecc.). Ottimo per cominciare, come dice il nome del resto.
Molto interessante e ricca di suggerimenti è l'ampia sezione dedicata a Windows Vista del sito the How-To Geek. Gli How To sono elencati per categorie (Desktop Customisation, Managing Files and Folders, Network and Internet, Security, System Administration, Windows Aero Glass, Tips and Tweaks) e tra essi ce ne sono di molto utili e difficili da trovare altrove. Anche questo sito è in inglese.
PuntoDiVista è un blog monotematico su Windows Vista in italiano, costantemente aggiornato (più volte al giorno) con notizie di ogni tipo relative al nuovo sistema operativo.
I miei guai con Vista è un blog (in italiano) in cui l'autore ci racconta in diretta "le avventure e soprattutto le disavventure" del suo passaggio a Vista (e grazie al quale ho scoperto i primi due siti di questo post).
Technorati tags:
vista,
windows View blog reactions
Ho ricevuto da Giuseppe Marchi la segnalazione di questo concorso per sviluppatori .NET, con in palio due licenze di Visual Studio .NET 2005 Professional Edition.
La prima licenza viene assegnata per estrazione, tra l'elenco di utenti che hanno inviato almeno un tip, ossia un breve e semplice estratto di codice .NET, al sito web del concorso.
La seconda licenza viene assegnata da una giuria che valuta dei progetti inviati dagli utenti sempre allo stesso sito.
Partecipare non costa nulla, ma chi fosse interessato deve affrettarsi, perché l'estrazione avverrà il 19 maggio 2007.
Tutte le informazioni su http://www.vs-trophy.net
View blog reactions
Superfetch è una delle caratteristiche di Windows Vista per me più sorprendente, per come riesce a velocizzare il tempo necessario all'apertura dei programmi che uso sul mio PC.
Grazie al solito paperino, qui possiamo leggerne un'analisi approfondita ma allo stesso tempo molto semplice da capire (almeno per me
).
Nello stesso post, inoltre, si chiariscono alcune delle fesserie alcuni dei falsi miti che si possono leggere in giro a proposito di questa feature. Per smentirli è bastato semplicemente adottare un metodo che sembra sconosciuto ad alcuni tra i troppi esperti della materia: il metodo scientifico.
Technorati tags:
vista,
windows View blog reactions
Internet Explorer Developer Toolbar è una toolbar per IE6 e IE7 molto comoda per chi deve lavorare ad un sito web. È disponibile nella versione Beta 3, che può essere scaricata da qui, dove si trova anche un elenco completo delle feature. Qui invece se ne trova una descrizione dettagliata.
Oltre ai classici strumenti di navigazione e modifica del DOM e dei CSS presenti nella toolbar, trovo molto utili:
- Tools->Resize: ridimensiona la finestra del browser permettendo di vedere come apparirebbe un sito a diverse risoluzioni;
- Tools->ColorPicker: per "catturare" il colore di un qualsiasi punto della pagina (ed evitare di telefonare al grafico per farselo dire o aprire un programma apposta)
- Validate: consente, tra l'altro, di testare dal punto di vista della validazione W3C la versione off line della pagina HTML (Local HTML) e del CSS (Local CSS) con un solo click.
Tra le cose che, secondo me, andrebbero riviste (del resto è una Beta), ci metto:
- l'interfaccia un po' troppo invasiva (nella Beta 2 mi sembrava più discreta, questa non mi convince ancora);
- la visualizzazione dei source DOM in cui i tag e gli stili sono tutti in maiuscolo (anche se non lo sono in Original).
Con Windows Vista, inoltre, l'installazione della IE Developer Toolbar (fornita come file .msi) mi ha dato alcuni problemi. Ho fatto doppio click sul file di installazione e tutto è sembrato
svolgersi regolarmente. Alla fine in IE7 è apparsa l'icona della toolbar, ma cliccandoci sopra non accadeva nulla. Anche seguendo il suggerimento di fare log off e log on (sempre da The Microsoft Internet Explorer Weblog) non sembrava sortire alcun effetto, come pure il riavvio della macchina.
Sono riuscito a risolvere solamente eseguendo un prompt dei comandi come amministratore e facendo partire da lì l'installazione della IE Developer Toolbar. Alla fine dell'installazione cliccando sul pulsante è apparso finalmente il pannello inferiore della toolbar.
Dato che la Beta 3 è stata rilasciata il 9 gennaio 2007, prima del lancio di Vista, credo che questo problema sarà risolto già nella prossima release.
View blog reactions
Sto lavorando ad alcuni siti web che, tra l'altro, dovranno essere visualizzabili in diverse lingue. Con ASP.NET 2.0 il lavoro dello sviluppatore viene semplificato notevolmente, come è possibile capire leggendo questo articolo di Tiziana Loporchio e quest'altro di Giuseppe Marchi, grazie anche ai tool di Visual Studio 2005 e al Resource Refactoring Tool (dal 13/2/2007 è disponibile la 1.0).
Nel mio caso il problema sarebbe anzitutto di non rinunciare all'impostazione della cultura in automatico dalle impostazioni del browser, attraverso la configurazione nel file web.config del tag globalization (nella sezione system.web):
<globalization culture=”auto:it-IT” uiCulture=”auto:it”>
In questo modo un utente che avesse tra le impostazioni del suo browser una delle lingue supportate per quel sito, vedrebbe direttamente ogni pagina nella lingua impostata.
C'è però il caso di un utente che ha impostata una lingua non supportata, oppure che vorrebbe consultare il sito in una lingua diversa da quella impostata sul browser.
Ho pensato di risolvere il problema trovando nella masterpage uno spazio per degli ImageButton (magari le solite bandierine), che al click eseguano il codice seguente:
Protected Sub ImageButtonEnUs_Click(ByVal sender As Object, _
ByVal e As System.Web.UI.ImageClickEventArgs) Handles ImageButtonEnUs.Click
If Session("lingua") IsNot Nothing Then
Dim lingua As String = CStr(Session("lingua"))
If lingua <> "en-US" Then
Session("lingua") = "en-US"
Response.Redirect(Me.Request.Url.PathAndQuery)
End If
End If
End Sub
A questo punto è necessario fare in modo che ogni pagina visitata dallo stesso utente venga visualizzata nella lingua selezionata. La soluzione migliore mi è sembrata quella di creare una classe ereditata da System.Web.UI.Page, da cui derivare tutte le pagine del sito, ed in essa scrivere un override del metodo InitializeCulture:
Public Class PaginaLocalizzata
Inherits System.Web.UI.Page
Protected Overrides Sub InitializeCulture()
If Session("lingua") IsNot Nothing Then
Dim ci As New CultureInfo(CStr(Session("lingua")))
Thread.CurrentThread.CurrentCulture = ci
Thread.CurrentThread.CurrentUICulture = ci
Else
MyBase.InitializeCulture()
End If
End Sub
End Class
Probabilmente la cosa si può migliorare, però lo scopo è raggiunto: ogni pagina è visualizzata nella lingua impostata nel browser (o in quella di default), ma se l'utente decide di volerla visualizzare in una delle altre lingue supportate, basta un click e da quel momento il sito gli apparirà nella lingua selezionata.
View blog reactions
Ancora non conoscevo questa feature di Windows Vista: il nuovo partition manager, che consente di cambiare la dimensione delle partizioni senza riavviare, grazie alle funzionalità di shrink e extend.
Qui si trova una descrizione più dettagliata.
Technorati tags:
vista,
windows View blog reactions
Una delle prime cose che ho fatto su questo blog è stato provare i diversi skin. La gestione del look del blog dà anche la possibilità di sovrascrivere il css, il che ad esempio è utile se si vuole cambiare un'immagine impostata come background di un elemento div.
E se volessi cambiare l'immagine visualizzata come background dell'intestazione scegliendola in maniera casuale, oppure a seconda dell'ora in cui si visualizza la pagina?
Ho pensato, ad esempio, di preparare 5 immagini diverse: 5 fotoritocchi dello stesso panorama (eseguiti malamente da me, ma appena si libera Nico[1] mi faccio aiutare) che, cambiandone la luce, danno le versioni "mattino.jpg", "giorno.jpg", "pomeriggio.jpg", "sera.jpg" e "notte.jpg", tra cui scegliere quale visualizzare a seconda dell'ora.
Avendo a disposizione un server web, ho scritto una piccola applicazione che utilizza un HttpHandler.
Basta creare un progetto web con VS e, all'interno di questo, aggiungere un un HttpHandler, come illustrato in figura (ho usato VS Web Developer 2005 Express Edition):

A questo punto dobbiamo scrivere il codice. Stiamo scrivendo un HttpHandler, ossia implementando l'interfaccia IHttpHandler, per cui dovremo specificare il metodo ProcessRequest e la proprietà IsReusable.
IsReusable può essere impostata a False o a True: come dice la parola stessa, indica se il nostro oggetto handler può essere riutilizzato (True) o se ogni volta se ne deve creare una nuova istanza (False). Poiché l'handler non andrà a modificare nulla, ma solo a leggere dati, il codice può essere considerato threadsafe, per cui la impostiamo a True.
ProcessRequest rappresenta cosa deve fare praticamente l'handler quando riceve una richiesta, cioè nel nostro caso deve inviare al client l'immagine opportuna in base all'ora del sistema. Ad esempio il codice in VB.NET potrebbe essere questo (non tenendo conto di stagioni, ora legale, ecc.
)
Dim nomiFileImmagine() As String = _
{"mattino", "giorno", "pomeriggio", "sera", "notte"}
Dim n, ora As Integer
ora = DateTime.Now.Hour
Select Case ora
Case 22 To 24, 0 To 6
n = 4
Case 7 To 9
n = 0
Case 17 To 19
n = 2
Case 20 To 21
n = 3
Case Else
n = 1
End Select
Adesso basta inviare al client il file binario che rappresenta l'immagine jpg scelta utilizzando Response.WriteFile riferito all'HttpContext (argomento della ProcessRequest).
Alla fine il codice completo è il seguente:
<%@ WebHandler Language="VB" Class="ImmagineOraria" %>
Imports System
Imports System.Web
Public Class ImmagineOraria : Implements IHttpHandler
Const DIRIMMAGINI = "directoryimmagini/headerblog/"
Public Sub ProcessRequest(ByVal context As HttpContext) _
Implements IHttpHandler.ProcessRequest
Dim nomiFileImmagine() As String = _
{"mattino", "giorno", "pomeriggio", "sera", "notte"}
Dim n, ora As Integer
ora = DateTime.Now.Hour
Select Case ora
Case 22 To 24, 0 To 6
n = 4
Case 7 To 9
n = 0
Case 17 To 19
n = 2
Case 20 To 21
n = 3
Case Else
n = 1
End Select
Dim response As Web.HttpResponse = context.Response
response.ContentType = "image/jpeg"
response.Cache.SetCacheability(HttpCacheability.Public)
response.BufferOutput = False
response.WriteFile(context.Server.MapPath(DIRIMMAGINI & _
nomiFileImmagine(n) & ".jpg"))
response.End()
End Sub
Public ReadOnly Property IsReusable() As Boolean _
Implements IHttpHandler.IsReusable
Get
Return True
End Get
End Property
End Class
Nella dashboard del blog basta fare un override del css impostando (per il div di intestazione):
background-image: url(http://miowebserver/ImmagineOraria.ashx);
ed il gioco è fatto.
Per provare l'handler localmente prima di farne l'upload sul server, basta aggiungere al progetto una semplice pagina HTML che contenga nel body:
<img src="ImmagineOraria.ashx" alt="immagine"/>
Un'altra possibilità potrebbe essere quella di far scegliere l'immagine a caso tra quelle presenti all'interno di una cartella sul server. In questo caso il codice in VB potrebbe essere:
<%@ WebHandler Language="VB" Class="ImmagineCasuale" %>
Imports System
Imports System.Web
Public Class ImmagineCasuale : Implements IHttpHandler
Const DIRIMMAGINI = "directoryimmagini/headercasuale"
Public Sub ProcessRequest(ByVal context As HttpContext) _
Implements IHttpHandler.ProcessRequest
Dim nomiFileImmagine() As String = _
System.IO.Directory.GetFiles(context.Server.MapPath(DIRIMMAGINI), "*.jpg")
If nomiFileImmagine.Length > 0 Then
Dim n As Integer
Dim vMax As Integer
vMax = nomiFileImmagine.GetUpperBound(0)
Randomize()
n = CInt(Int((vMax + 1) * Rnd()))
Dim response As Web.HttpResponse = context.Response
response.ContentType = "image/jpeg"
response.Cache.SetCacheability(HttpCacheability.Public)
response.BufferOutput = False
response.WriteFile(nomiFileImmagine(n))
response.End()
End If
End Sub
Public ReadOnly Property IsReusable() As Boolean _
Implements IHttpHandler.IsReusable
Get
Return True
End Get
End Property
End Class
[1]Il mio amico Nico lavora come grafico nella mia stessa ditta e con Photoshop è in grado di realizzare in 2 minuti quello che riesco a fare in 1 ora, ma con risultati decisamente migliori. Del resto la tecnologia avanza, ma (come disse
Vito a proposito di WPF nel corso di un
evento) la grafica creata dagli sviluppatori fa sempre abbastanza schifo.
View blog reactions