Distribuzione di XAML Browser Applications con ClickOnce
a cura di Alessandro Del Sole (requisiti: conoscenze di base su Windows Presentation Foundation)

Introduzione
Come molti di voi sapranno, Windows Presentation Foundation consente di creare applicazioni in grado di essere eseguite all'interno di un browser web, come Internet Explorer, in alternativa alle classiche applicazioni Windows (sempre basate su WPF). Questo genere di applicazioni prende il nome di XAML Browser Applications, definite anche, per brevità, con l'acronimo di XBAP.
Sia che utilizziate Visual Studio 2005 che Visual Studio 2008 (comprese le edizioni Express) avrete la possibilità di creare questo genere di applicazioni all'interno del consueto ambiente visuale di sviluppo, con la differenza che il modello di progetto per Visual Studio 2005 si chiama XAML Browser Application e quello per Visual Studio 2008 prende il nome di WPF Browser Application.
Trattandosi di applicazioni che possono essere eseguite in un browser web, i file che le costituiscono debbono poi essere pubblicati su un sito (che può essere, ad esempio, il sito di Internet Information Services o un sito FTP). Una volta eseguita la pubblicazione, la nostra XBAP sarà eseguibile mediante la digitazione del link corrispondente nella barra degli indirizzi del browser.

In questo articolo ci proponiamo di realizzare una semplice XAML Browser Application per poi vedere come distribuirla su un sito tramite la tecnologia ClickOnce. Abbiamo così la scusa di vedere più da vicino come funziona una XBAP e di capire come distribuirla. Nel corso dell'articolo, inoltre, daremo cenno ad alcune specifiche novità introdotte da .NET Framework 3.5.

Il progetto dimostrativo è disponibile, come di consueto, nell'area download di VB T&T, sia per Visual Basic che per Visual C#. E' stato predisposto con Visual Studio 2008, pertanto se utilizzate l'edizione 2005 dovrete creare da zero il progetto e fare copia-incolla del codice di seguito indicato. Anche se il consiglio è sempre lo stesso, stavolta più che mai è bene che leggiate tutto l'articolo prima di scaricarlo, poiché alcune tecniche illustrate, come quelle relative alla pubblicazione vera e propria, non possono essere incluse in un archivio zip ma debbono essere eseguite manualmente.

Se poi siete interessati a Windows Presentation Foundation e alle XBAP in modo più articolato, potrebbe interessarvi dare un'occhiata al mio nuovo libro dedicato a .NET Framework 3.x.

Cosa occorre
Per realizzare una XAML Browser Application potete utilizzare indistintamente Visual Studio 2005 o Visual Studio 2008 (comprese le edizioni Express), tenendo a mente che le edizioni Express di Visual Studio 2005 non supportano il designer WPF. Visual Studio 2005, inoltre, permette di creare XBAP basate esclusivamente sulla versione 3.0 di .NET Framework. Un buon compromesso può essere quello di utilizzare una delle edizioni Express di Visual Studio 2008, che integrano il designer WPF e permettono di sfruttare, oltre alle caratteristiche tipiche di .NET 3.0, anche le novità introdotte dalla nuova versione 3.5. A suffragio di questo, l'articolo è stato redatto sulla base di una XBAP creata con Visual Basic 2008 Express. Potete scaricare questo ambiente (o Visual C# Express) dal sito microsoft. Per chi preferisce utilizzare Visual C#, riporto i corrispondenti frammenti di codice anche se, ovviamente, dovrete utilizzarli all'interno dell'apposito IDE.

Particolarità delle XAML Browser Applications
Le XAML Browser Application sono delle applicazioni WPF a tutti gli effetti. Per tale motivo, potremo utilizzare tutte le tecniche che conosciamo nell'ambito di WPF anche in questi frangenti. Continueremo, quindi, ad utilizzare XAML per gestire la fase di design e a scrivere codice gestito per quanto concerne la parte logica, in maniera del tutto analoga a quanto visto per le applicazioni Windows.

Tuttavia, ci sono alcune regole da rispettare che riguardano, in particolar modo, il discorso "sicurezza". Poiché le XBAP vengono eseguite all'interno di un browser web, e quindi tipicamente vengono lanciate da un sito Internet, esse vengono considerate come parzialmente attendibili (partially-trusted in gergo .NET) e sono state progettate per essere eseguite all'interno di una sand-box di sicurezza secondo il set di permessi definito Internet Zone. Questo set di permessi, definito all'interno del Code Access Security di .NET Framework (quella parte del run-time che si occupa di stabilire a quali risorse di sistema e con quali modalità possono accedere le applicazioni gestite), è il più ristretto in assoluto.
Per fare un esempio, questo set non consente di intervenire direttamente sui file o sul registro di sistema. Diventa quindi importante progettare la propria applicazione XBAP tenendo conto di determinate limitazioni.
A dire il vero, tramite la scheda Security della finestra My Project (Properties in C#), è possibile modificare il set di permessi da attribuire all'applicazione, sia mediante la personalizzazione del set esistente (ad esempio è possibile aggiungere o rimuovere l'accesso a determinate risorse) sia selezionando il set di permessi denominato Local Intranet, meno restrittivo del precedente e specifico per l'esecuzione delle applicazioni in reti locali aziendali. Tuttavia, si preferisce lasciare invariata la selezione del set di permessi Internet Zone affinché si abbia la sicurezza che l'applicazione venga da un lato ritenuta affidabile da chi la esegue, dall'altro che non ci siano rischi di tentare l'accesso a risorse di sistema che il set Internet non consente, evitando la generazione di spiacevoli eccezioni.

Un'ultima considerazione va fatta a riguardo della nuova versione 3.5 di .NET Framework: questa introduce una migliore gestione dei cookie da parte delle XBAP e, soprattutto, ora questo tipo di applicazioni può essere eseguito anche all'interno del browser FireFox (precedentemente le XBAP erano prerogativa esclusiva di Internet Explorer).
Fatte queste brevi ma doverose considerazioni, possiamo passare a creare la nostra XBAP.

Creazione del progetto di esempio
Una volta avviato Visual Basic 2008 Express, create un nuovo progetto vuoto selezionando il modello di progetto chiamato WPF Browser Application ed assegnategli il nome adsXBAPDemo, come in figura:

Fatto questo, l'IDE si presenta sostanzialmente analogo a quanto siete abituati a vedere al riguardo di applicazioni WPF per Windows, come potete vedere in figura (solo la parte centrale):

Due differenze devono subito essere rilevate. La prima, fondamentale, riguarda l'implementazione di un controllo Page (tipico delle applicazioni XBAP) al posto del controllo Window (che caratterizza le applicazioni Windows). La seconda riguarda l'aggiunta di uno strong-name al progetto, un file contenente un nome sicuro che contrassegna come univoca la nostra applicazione. L'aggiunta automatica dello strong-name non è casuale: si tratta, infatti, di un requisito fondamentale per la distribuzione dell'applicazione tramite ClickOnce. Sulla sinistra potete notare la consueta casella degli strumenti, che contiene tutti i controlli WPF che avevamo già utilizzato in applicazioni Windows. Questo ci conferma che le tecniche di programmazione già conosciute possono essere riutilizzate anche nella realizzazione di una XBAP.

La nostra applicazione si occuperà di calcolare la tangente di un angolo. Come sempre, l'approccio logico è quello di scrivere codice XAML per la gestione dell'interfaccia grafica e il classico codice managed per la parte operativa dell'applicazione. Ciò posto, aggiungiamo al layout alcuni controlli: una TextBox, un pulsante e un controllo TextBlock che, come vedremo, ci consente una migliore formattazione del testo. Digitate, quindi, quanto segue:

    <StackPanel Orientation="Vertical">
        <Label Margin="10,10,10,10">Inserire l'angolo:</Label>

        <TextBox Margin="10,10,10,10" Name="TangenteTextBox"/>

        <Button Name="CalculateButton" Margin="10,10,10,10" 
                Width="100" Height="30" Click="OnCalculateButton">Calcola tangente</Button>

        <Label Margin="10,10,10,10">Il risultato del calcolo \u232 ?:</Label>

        <TextBlock Margin="10,10,10,10" Name="ResultBlock" 
                   FontFamily="Verdana" FontSize="14" FontWeight="Bold">
        
              <TextBlock.Foreground>
                  <LinearGradientBrush>
                      <GradientStop Offset="0" Color="Blue"/>
                      <GradientStop Offset="0.7" Color="DarkGreen"/>
                      <GradientStop Offset="1" Color="Violet"/>
                  </LinearGradientBrush>
              </TextBlock.Foreground>
        </TextBlock>

    </StackPanel>

L'implementazione dell'interfaccia è piuttosto essenziale: all'interno di un contenitore StackPanel abbiamo inserito una serie di controlli per l'inserimento di un angolo e il calcolo della sua tangente. Unica nota degna di attenzione è l'utilizzo di un controllo TextBlock, al posto di una Label o di una TextBox, che consente, come potete vedere nel codice markup, di specificare ulteriori proprietà per la formattazione del testo, come il font e il colore di primo piano, che abbiamo definito tramite un gradiente. Se avete letto i miei precedenti articoli introduttivi a WPF, avrete familiarità con questa tecnica.

Una volta implementati gli elementi dell'interfacci grafica, si passa a definire la parte operativa dell'applicazione mediante l'aggiunta di codice al file di code-behind. Definiamo, in primo luogo, un metodo chiamato calcolaTangente, che riceve un argomento di tipo Double, corrispondente all'angolo su cui eseguire il calcolo, e che restituisce la tangente dell'angolo stesso. Eccone il codice:

  'Presuppone una direttiva Imports System.Math
  Private Function calcolaTangente(ByVal angolo As Double) As Double

    Dim radians As Double = angolo * (PI / 180)

    Return Tan(radians)
  End Function
    private double calcolaTangente(double angolo)
    {
      double radians = angolo * (Math.PI / 180);
      return Math.Tan(radians);
    }

Il passaggio successivo è quello di definire il gestore dell'evento Click per il nostro pulsante:

  Private Sub OnCalculateButton(ByVal sender As Object, ByVal e As RoutedEventArgs) _
                                Handles CalculateButton.Click

    If String.IsNullOrEmpty(TangenteTextBox.Text) = False Then

      Dim angolo As Double = CDbl(TangenteTextBox.Text)

      Try
        ResultBlock.Text = calcolaTangente(angolo).ToString
        Exit Sub
      Catch ex As Exception
        MessageBox.Show("Si è verificato il seguente errore: " + Environment.NewLine + _
                        ex.Message)
        Exit Sub
      End Try
    Else
      MessageBox.Show("Non hai inserito alcun valore")
      Exit Sub
    End If
  End Sub
    private void OnCalculateButton(object sender, RoutedEventArgs e)
    {
      if (string.IsNullOrEmpty(TangenteTextBox.Text) == false)
      {
        double angolo = (double)(TangenteTextBox.Text);

        try
        {
          ResultBlock.Text = calcolaTangente(angolo).ToString();
        }

        catch (Exception e)
        {
          MessageBox.Show("Si è verificato il seguente errore: " + Environment.NewLine + e.Message);
        }
        finally
        {
          return;
        }
      }
      else
      {
        MessageBox.Show("Non hai inserito alcun valore");
      }

    }

Il codice verifica, innanzitutto, che la TextBox non sia vuota, quindi esegue la conversione del contenuto in Double e richiama il metodo per il calcolo della tangente del valore specificato. Il risultato del calcolo viene assegnato alla proprietà Text del controllo ResultBlock, il cui aspetto viene automaticamente aggiornato. Come potete vedere, il codice è piuttosto semplice. Elabora l'angolo immesso nella TextBox e ne calcola la tangente, riportando il risultato del calcolo nel controllo TextBlock. Ovviamente, il codice può essere ulteriormente migliorato, prevedendo, ad esempio, l'inserimento di soli valori numerici o l'intercettazione di eccezioni più specifiche (pratica che dovrebbe costituire la regola in .NET). Questi spunti vengono lasciati al lettore come approfondimento personale, in questa sede è importante focalizzare l'attenzione sui concetti più che sulle best-practices di scrittura del codice.

Bene, la creazione della nostra XBAP è terminata. Siamo pronti ora ad avviarne l'esecuzione all'interno del nostro browser web predefinito.

Esecuzione dell'applicazione
Premendo il tasto F5, è possibile avviare l'esecuzione della nostra XBAP in maniera analoga a come siamo abituati a fare per le applicazioni Windows. La differenza sta nel fatto che l'applicazione viene eseguita all'interno del browser web predefinito. Una volta avviata la generazione, Visual Basic 2008 produce tutti i file necessari alla XBAP, li pone nella sottocartella Bin del progetto ed esegue l'applicazione nel browser, come in figura:

Così facendo ci siamo accertati del corretto funzionamento della nostra XBAP. Non ci resta che completare l'opera, predisponendo una procedura di distribuzione tramite ClickOnce e pubblicare la nostra XBAP su un sito web.

Creazione della procedura di distribuzione
In maniera analoga a quanto avviene per le applicazioni .NET classiche, anche la distribuzione delle XBAP può avvenire distribuendo i file contenuti nella cartella Bin\Debug o Bin\Release, utilizzando la modalità XCopy. L'IDE di Visual Studio 2005/2008, però, ci mette a disposizione un metodo decisamente più funzionale. Infatti, per pubblicare e distribuire la nostra XBAP, possiamo utilizzare la tecnologia ClickOnce. Questa scelta offre diversi vantaggi: innanzitutto si tratta di una opzione disponibile all'interno dell'IDE di Visual Studio 2005/2008 e non ci costringe a ricorrere né a installer di terze parti, né a una procedura di distribuzione manuale. Inoltre, ClickOnce è disponibile anche nelle edizioni Express di Visual Studio e, come nella sua tradizione, consente di distribuire l'applicazione con pochi clic di mouse, tenendo anche conto di alcune piccole ma specifiche evoluzioni introdotte dalla versione 3.5 di .NET Framework.

Per semplificare la procedura di distribuzione, pubblicheremo l'applicazione sul sito locale di Internet Information Services. Nel caso utilizziate Windows Vista, prima di procedere dovrete accertarvi (tramite l'utilità Programmi e funzionalità del Pannello di Controllo) che siano installati i componenti relativi alla compatibilità di IIS 7.0 con la versione 6.0.

Prima di procedere alla pubblicazione vera e propria, curiamo alcuni dettagli. Attivate, in primo luogo, la finestra My Project (Properties in C#), quindi selezionate la scheda Security, che si presenta come in figura:

Da questa scheda è possibile modificare i permessi che l'applicazione avrà nell'accedere a specifiche risorse di sistema. Come potete osservare, Visual Studio imposta per default il set di permessi Internet Zone, di cui abbiamo dato cenno in precedenza. Al contrario di quanto avviene per le altre tipologie di progetto, in questo caso è possibile selezionare solo le zone Internet e Intranet locale, modificando, se necessario, i singoli permessi. Sconsiglio vivamente di modificare le impostazioni predefinite e di lasciare attivo sempre il set di permessi Internet Zone. Non è superfluo precisare, infatti, che l'utente che esegue la nostra XBAP si aspetta che questa rispetti proprio il set di permessi menzionato (non si aspetta, in altre parole, che un'applicazione eseguita da un sito Internet vada a toccare le risorse del suo sistema), pertanto questa è la scelta più opportuna.

Attivate ora la scheda Publish e fate clic sul pulsante Options. In questo modo si potranno indicare alcune informazioni sull'applicazione, come riportato nella seguente figura esemplificativa:

Fate poi clic su OK per tornare alla scheda Publish. Disattivate l'incremento automatico del numero di versione per ogni nuova pubblicazione (in questo caso non ci serve) togliendo il segno di spunta dalla casella chiamata Automatically increment revision with each publish. In alto, nel campo chiamato Publishing folder location, digitate l'indirizzo: http://localhost/adsXBAPDemo. Fate poi clic sul pulsante Publish e attendete che l'IDE completi il suo lavoro.
Quando le operazioni di pubblicazione si concludono, la nuova XBAP viene avviata automaticamente all'interno del browser web predefinito. Come potete osservare anche dalla figura, l'applicazione XBAP viene lanciata da un URL, proprio come se fosse stata avviata da un sito internet:

I più attenti avranno subito notato che il file che permette l'avvio dell'applicazione ha estensione .Xbap. Si tratta di un file di manifesto, che contiene i dati necessari all'avvio dell'applicazione vera e propria, costituita ancora da un file eseguibile .Exe. La procedura utilizzata per Internet Information Services può essere analogamente utilizzata anche per la pubblicazione su un server FTP o un sito Web. Ad esempio, nel caso di un server FTP, potrete specificare l'indirizzo del server stesso laddove in precedenza abbiamo indicato il percorso locale di IIS. In tali fattispecie, Visual Studio vi richiederà di specificare le vostre credenziali per accedere allo spazio specificato.

Ulteriori riferimenti
A complemento di questa lettura, vi lascio i riferimenti relativi ad alcuni post che ho pubblicato nel mio blog e che riguardano lo sviluppo e la distribuzione di XAML Browser Applications, rimandandovi alla documentazione ufficiale MSDN per i dettagli:

Conclusioni
Lo sviluppo di XAML Browser Applications costituisce una importante caratteristica di Windows Presentation Foundation ma, ovviamente, non si esaurisce con gli argomenti trattati in questo articolo. Inoltre, se desiderate realizzare applicazioni Web dagli elevati contenuti multimediali, è molto probabile che preferiate interessarvi a tecnologie specifiche come Microsoft SilverLight, appositamente progettato per questo scopo. In ogni caso avete imparato a creare una XBAP di partenza e a distribuirla nel modo più semplice, appositamente previsto da .NET Framework. Per gli approfondimenti potete consultare la documentazione MSDN ufficiale mentre, per commenti e quant'altro di vostro interesse, potete contattarmi al mio indirizzo visitare il mio blog.
Come al solito, il codice a corredo di questo articolo è scaricabile dall'area download.