Technology Experience

.NET World

Programmazione, libri, snippet di codice, articoli tecnici

.NET World

Sistema di push notification per Windows Phone e Windows 8 rivendibile a terzi

Facciamola breve: mi sono stancato di dover – per ciascun app Windows Phone o Windows 8 che necessiti di push notification – di dover implementare bene o male le stesse cose. Ovvero, in breve:

  1. una tabella “Subscribers” sul database SQL Server che mantenga i subscriber per quella specifica app
  2. implementare sul servizio WCF specifico dell’app i metodi Subscribe/Unsubscribe invocati internamente all’app per permettere all’utente di attivare/disattivare le notifiche

Dal punto di vista server, ogni mia app (Duello in Cucina, Deputati Italiani, la futura Diretta Volley, Piloti Virtuali Italiani, etc.) ha bene o male una certa parte di sistema ripetuta, cosa che cominciava a non andarmi del tutto a genio. Inoltre può sembrare poca roba, ma vi assicuro che non è così. Ed anche se fosse poca roba, è comunque una cosa da ripetere e scrivere ogni volta, con rischio ovviamente di codice ripetuto, a rischio di bug, etc. etc. Quindi, mi sono detto, sarebbe fattibile creare un’unica infrastruttura database & WCF talmente generica da poter essere sfruttata in ogni mia futura app, indipendentemente dal fatto che sia Windows Phone o Windows 8, per gestire le push notification? E magari talmente generica da poter essere addirittura “venduta/affittata” a terzi? La risposta è ovviamente sì.

Sorriso

Cosa vi metto quindi a disposizione?
E’ semplice: un servizio WCF che espone i seguenti metodi:

I metodi sono autoesplicativi:

  1. va chiamato il metodo Subscribe quando da una qualsiasi delle vostre app wp7/win8 volete aggiungere un nuovo subscriber
  2. va chiamato il metodo Unsubscribe quando da una qualsiasi delle vostre app wp7/win8 volete rimuovere un nuovo subscriber

Il metodo Push invece deve essere invocato dal vostro servizio web/cloud: questo è il vero motore che invia le notifiche a tutti i subscriber relativi alla vostra app.

Chiaramente le chiamate ai metodi WCF descritti qui sopra utilizzano una serie di classi (SubscribeRequest, UnsubscribeRequest e PushRequest) che incapsulano un po’ di informazioni, grazie alle quali vi autenticate, mi dite che siete (inteso come “cliente”), mi dite quale app siete, etc. etc. Nel momento in cui volete inviare le notifiche, stessa cosa: mi dite chi siete, quale app siete, il tipo di notifica (toast, tile, badge, etc.), l’xml della push notification che volete inviare, etc. etc.

Io mi occupo di memorizzare sui miei server i vostri utenti e di inviare a tutti la notifica.

Limitazioni
Chiaramente, per ora metto a disposizione questa cosa solo ad amici e colleghi developer.

Ci sono alcune limitazioni note di cui vi voglio parlare.

  1. Poca sicurezza, nel senso che ad oggi mi dovete comunicare (solo per le app Windows 8) la SecretKey ed il Sid relativo a ciascuna app che volete gestire
  2. Non c’è la possibilità di fare push notification “selettive”: cioè, se la vostra app ha 1000 subscribers attivi, in questo momento la chiamata al metodo Push invia a tutti la notifica, mentre in realtà potrebbe non essere così (immaginate un’app di calcio, ed immaginate che l’utente voglia ricevere una notifica solo quando segna la squadra per cui tifa – questo scenario non è ancora coperto – ma ci sto lavorando su)

Se volete aiutarmi, se volete provarlo, se avete qualche suggerimento/segnalazione da darmi, sono tutt’orecchi!

Sorriso

Send to Kindle
.NET World

App Windows 8 Metro-Style, Bing Map e snapped view

Lavorando sulla mia prima app per Windows 8 mi sono scontrato con un problema davvero fastidio e difficilmente debuggabile.

In pratica, ho implementato una normalissima Page che – in condizioni normali di full-screen – mostra una BingMap che visualizza un volo aereo. Sulla mappa potete fare normali operazioni come zoom, pan, etc. etc. Nella versione snapped view della stessa pagina avevo deciso di rimuovere la BingMap, e di mostrare solo un’altra serie di informazioni. Quello che accadeva è nel momento in cui facevo lo snap della pagina, l’app si schiantava e Visual Studio mi segnalava una unhandled exception. Ho cercato di capire per sicuramente più di un paio d’ore, alla fine sono riuscito ad isolare il problema, che riguardava proprio la BingMap. Se la rimuovevo dallo XAML, infatti, tutto funzionava senza problemi. La cosa si verificava sia se metteva in snapped la pagina – come ho appena descritto – sia se partivo dalla pagina precedente in snapped view.

Come risolvere?

Questa cosa è spiegata sommariamente nella sezione Q&A della pagina Bing Maps SDK for Metro style apps (RP).

Per risolvere, quindi, basta impostare una MinWidth al controllo BingMap, impostandolo ad un valore qualsiasi maggiore di zero. A quanto pare, infatti, durante l’operazione di snapping la width e la height finiscono uguali a zero, causando non pochi problemi, tra cui il crash dell’app e del debugger. Io l’ho impostata a “160” ed il problema è sparito!

Send to Kindle
.NET World

Fare lo short di un url usando le Google API

Sviluppando applicazioni Metro per Windows 8, una delle funzionalità più interessanti – non solo dal punto di vista developer ma anche utente – è la possibilità di fare lo share di un qualsiasi contenuto usando una delle app già installate nel sistema. In pratica per un utente il tutto si riassume in pochi passi, ovvero:

  • vedo un contenuto interessante all’interno di un’app (una foto, un link, un articolo, un punteggio in un videogioco, il prezzo di un articolo, un film da vedere al cinema, qualsiasi cosa) e decido di condividerla con qualcuno
  • l’espressione “condividerla con qualcuno” è volutamente generica, perchè vuol dire un sacco di cose (molte delle quali ancora da intuire, probabilmente): vuol dire poter mandare una mail, twittare, postarla sulla propria pagina Facebook, postare una foto su PInteret, marcare un link tra quelli preferiti in Diio, aggiungere una foto in un photoset di Flickr, etc. etc.
  • per farlo, l’utente non deve far altro che richiamare lo charm di Share di Windows 8 premendo Win + H (oppure Win + C e poi cliccare su Share). Se l’app che state usando prevede questa funzionalità, Windows 8 mostrerà l’elenco di app installate nel sistema che sono predisposte a condividere l’informazione

Nell’app Windows 8 che sto sviluppando, pviCommunity, è possibile per esempio fare lo share di fotografie scattate durante i voli virtuali di Piloti Virtuali Italiani. Ogni fotografia è identificata da un url ben preciso, quindi…mi sono detto…perchè non permette di twittare dalla mia app quanto sia bella una certa foto. Sappiamo tutti che i tweet hanno una lunghezza massima di 140 caratteri. L’url di una fotografia può essere una cosa tipo questa:

http://service.vivendobyte.net/FlightLogs/7600/2012-7-6_11-47-26-546.jpg

E’ una fotografia reale, quindi se cliccate sul link potete tranquillamente guardarla.
Sorriso

La domanda è la seguente: come è possibile fare lo short di questo url, per esempio usando le API di Google. Il primo passo è quello di registrarsi qui per ottenere una apikey da utilizzare direttamente nel vostro codice C#. Fatto questo, utilizzate questa classe per fare tutto il resto:

public static class GoogleUrlShortnerApi
    {
        private const string key = "api_key";
 
        public static string Shorten(string url)
        {
            string post = "{"longUrl": "" + url + ""}";
            string shortUrl = url;
 
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url?key=" + key);
            try
            {
                request.Method = "POST";
                request.ContentType = "application/json";
 
                using (Stream requestStream = request.GetRequestStreamAsync().Result)
                {
                    byte[] postBuffer = System.Text.Encoding.UTF8.GetBytes(post);
                    requestStream.Write(postBuffer, 0, postBuffer.Length);
                }
 
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result)
                {
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        using (StreamReader responseReader = new StreamReader(responseStream))
                        {
                            string json = responseReader.ReadToEnd();
                            shortUrl = Regex.Match(json, @"""id"": ?""(?<id>.+)""").Groups["id"].Value;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // if Google's URL Shortner is down...
                System.Diagnostics.Debug.WriteLine(ex.Message);
                System.Diagnostics.Debug.WriteLine(ex.StackTrace);
            }
 
            return shortUrl;
        }
    }

 

Il codice è pensato per girare all’interno di un’app Windows 8 Metro-style, chiaramente.

Send to Kindle
.NET World

Push Notification con Windows 8, aspetti tecnici e ragionamenti vari

Nelle ultime settimane ho studiato pesantemente tutta la nuova architettura che Microsoft ha messo in piedi per permettere a noi dev di inviare push notification alle nostre app Metro. Partivo con un po’ di vantaggio per il semplice fatto che avevo già fatto la stessa cosa con Windows Phone 7, ma ci ho comunque dovuto sbattere un po’ la testa. Alcune cose sono cambiate, come è logico che sia.

Facciamola breve. Gli ingredienti di cui avete bisogno per mettere in piedi le push notification per la vostra app Metro sono i seguenti:

  • ovviamente, un’app Metro-style Windows 8. La vostra app deve permettere ai vostri utenti di sottoscriversi alle notifiche push: questo vuol dire banalmente mettere un controllo tipo ToggleSwitch nei settings della vostra app grazie al quale l’utente può scegliere se ricevere oppure no le notifiche (poi sta a voi magari fargli scegliere se vuole ricevere solo le tile notification, oppure solo le toast, le badge, etc. etc.). E’ buona norma farvi restituire l’esito di questa operazione, per informare l’utente se tutto è andato bene oppure no: questo può essere un semplice bool oppure qualcosa di più complesso. Quando una vostra app si sottoscrive alle push notification riceve un url, che identifica univocamente quel device e quell’applicazione
  • un vostro “cloud-service”, ovvero un servizio Web che al momento opportuno spara a tutti i vostri utenti la notifica. In quasi tutte le mie app Windows Phone 7 ho praticamente un servizio WCF che fra le altre cose serve anche a questo scopo. In pratica, quindi, vi serve un qualsiasi servizio di hosting che vi metta a disposizione database SQL Server, l’hosting di servizi WCF, etc. etc.
  • tornando al punto (1), quando l’utente attiva il ToggleSwitch invoca un metodo esposto dal servizio WCF, che si occupa di memorizzare server-side gli url che vengono associati al proprio dispositivo (dico dispositivo perchè potrebbe essere un pc, un notebook, un ultrabook, un tablet, un Surface, un qualsiasi dispositivo su cui gira Windows 8)

I punti qui sopra sono ovviamente un po’ più complessi, andrebbero sviscerati fino a riempire libri su libri. Io la faccio molto semplice, basta googlare per raccogliere informazioni in quantità. E devo anche aggiungere che MSDN è decisamente migliorata sotto questo punto di vista, rispetto ai primi tempo con Windows Phone. Adesso potete davvero trovare quickstart, tutorial, esempi di codice, xml, etc. etc.

Per cui una volta messa in piedi tutta l’infrastruttura software, la cosa è piuttosto semplice. Quando si scatena un determinato evento, il servizio WCF passa in rassegna la tabella dei vostri utenti che vogliono ricevere le notifiche: per ciascuno dei vostri utenti avete un url che lo identifica in modo inequivocabile ed univoco. A questo url inviate un certo blocco XML ed il gioco è fatto. L’XML può identificare qualsiasi tipo di notifica, anche se di un solo tipo per volta: non potete specificare con un unico XML una notifica toast e di tipo tile. All’interno di una notifica tile, però, potete specificare sia quella square che quella wide (ovvero: sia quella quadrata, che quella rettangolare): questo è indispensabile, perchè dal punto di vista del servizio WCF non sapete quale tile sta usando l’utente, e quindi è necessario mandargliele entrambe. Se sta usando quella square, vedrà quella, altrimenti quella wide.

Parliamo un secondo di settings della nostra app Windows 8 Metro-style.
Generalmente, con un’app Windows 8 verrebbe le tentazione di salvare tutti i settings all’interno di quelle roaming. Questo significa che i vostri settings viaggiano su tutti i device Windows 8 su cui state usando quell’app, e rimangono sincronizzate. Se cambiate un’impostazione su un PC, vi ritroverete la stessa impostazione su tutti gli altri device, insomma. Attenzione, però: parlando di push notification non è una buona idea. Nei settings delle mie app Windows 8 che fanno uso di push notification mantengo sempre due informazioni: un bool che mi dice se le notifiche sono attive, e l’url univoco di quel device. Questi due settings li salvo all’interno dei settings locali e non su quelle roaming, perchè sono impostazioni specifiche del device e non dell’app. Magari su un PC desktop (che non ha problemi di salvaguardia della batteria) vorrei sempre lasciare abilitate le notifiche, mentre potrebbe non essere la stessa cosa su un tablet. Su un device voglio le notifiche attive, sull’altro no. Quindi è opportuno decidere cosa salvare nei settings di tipo roaming, e cosa salvare nei settings di tipo local.

Forse la cosa più difficile è stato capire quali tipi di tile sono supportati dal sistema di notifiche (e quale XML inviare per ciascuna di esse, soprattutto).
Per questo vi lascio questa pagina:

http://msdn.microsoft.com/library/windows/apps/Hh761491

che riporta tutte le tile, siano essere quadrate o rettangolari. Ce ne sono un bel po’, che supportano solo testo, solo immagine, oppure testo ed immagine insieme, con diverse formattazioni.

Lo so, rispetto a tanti altri, questo post è un po’ sconclusionato: ho solo voluto riassumere in modo sparso un po’ di concetti con cui mi sono scontrato nei giorni scorsi, lavorando sulle push notification.

Send to Kindle
.NET World

Lightswitch e la mancata autenticazione in produzione

Lasciate che vi racconti questo scenario, piuttosto realistico, dato che è quello che è successo a me.

Qualche settimana fa ho deployato su un server di produzione un’applicazione Lightswitch. L’applicazione utilizza la Forms Authentication, in modo tale che l’utente possa loggarsi, farsi riconoscere, lavorare e portare a termine i compiti che deve fare. Venerdì scorso ho aggiornato l’applicazione, solo che non ho voluto utilizzare la procedura di deploy prevista da Lightswitch, ma con un banalissimo ftp ho aggiornato e sovrascritto le varie componenti manualmente.

Mi riferisco a:

  • Varie dll proprietarie di Lightswitch
  • Dll esterne che utilizzo nella solution
  • XAP principale dell’applicazione

Fatto questo, bello soddisfatto, apro il browser, vado all’indirizzo dell’applicazione, e tutto pimpante mi aspetto di fare login.

Panico. Panico. L’applicazione Lightswitch NON mi chiede l’autenticazione, entro direttamente come ‘test user’, e posso fare tutto di tutto. Gestire anagrafiche, fare fatture, modificare e cancellare questo & quello.

Ora, un piccolo preambolo. Chi sviluppa con Lightswitch sa che quando si decide di attivare la Forms Authentication e si esegue l’applicazione da Visual Studio 2010, in realtà l’applicazione non chiede mai login. L’applicazione viene eseguita con un ‘test user’, le cui autorizzazioni vengono impostate in un pannello di proprietà del progetto stesso.

Nello screenshot qui sopra vedete il pannello. Lo si raggiunge aprendo le proprietà del progetto. Nel rettangolo violetto si attiva la Forms Authentication. Nel rettangolo arancione si attivano i ruoli che vogliamo attivare al ‘test user’: nel nostro codice, risulterà che ‘test user’ abbia quei permessi, e quindi l’interfaccia della nostra applicazione Lightswitch reagirà di conseguenza.

Arriviamo al dunque. Quello che è successo alla mia applicazione in produzione è che ha cominciato a comportarsi come se fosse eseguita da Visual Studio 2010, utilizzando l’utente ‘test user’. Niente login, login automatico con questo utente, tutti i permessi attivi.

A cosa è dovuto tutto ciò? E’ semplice. Andate nella cartella WebManifests e cancellate il file Microsoft.LightSwitch.Design.Server.Manifest.dll. Questo file si trova ovviamente nella binRelease dell’applicazione, sul vostro PC, ma non va copiata sul server di produzione. La prima volta che ho deployato in produzione ho utilizzato la procedura standard di Lightswitch; l’aggiornamento invece l’ho fatto a mano, copiando le dll, ma non sapendolo, ho copiato anche quella dll incriminata, e questo ha causato quel problema.

Tutto è bene quel che finisce bene!

Send to Kindle
.NET World

Pubblicato un mio articolo sul Lightswitch Publish Wizard

Questo è un post veloce!

Da circa tre giorni è on-line sul sito www.lightswitch.it un mio articolo dedicato alla procedura di deploy & publishing di Lightswitch.

Per poterlo vedere è necessario essere utenti registrati; intanto vi lascio questo indirizzo, da dove potete raggiungere il sito della community.

Ringrazio lo staff che mi ha dato questa piccola opportunità: è un periodo in cui ho voglia di partecipare con più coinvolgimento alle varie di attività di community, e questa cosa mi ha fatto sfogare un pochino. Probabilmente scriverò altri contenuti fra poco tempo, per cui rimanete sintonizzati e vi farò sapere.

Buona lettura!

Send to Kindle
.NET World

Lightswitch: come rendere invisibile un controllo, agendo sulla UI

Questo post inizia con la fatidica frase “A due controlli è stato fatto del male durante la stesura di questo post”.
Prima vi spiego come risolvere il vostro problema, poi vi dico perchè questa cosa in fondo non mi piace poi molto.

Dunque, lo scopo è quello di rendere invisibile un controllo (TextBox, CheckBox, ComboBox, insomma…qualsiasi cosa che erediti da System.Windows.Controls.Control), in base al valore contenuto in un altro controllo. La cosa è nata in questo thread sui forum di lightswitch.it. In pratica, abbiamo due controlli: una TextBox ed una CheckBox. Entrambe sono bindate a due entity property diverse: quando la TextBox (usata per inserire il valore di uno stipendio) contiene “0”, la CheckBox (usata per inserire Contributi si/no) deve essere resa invisibile, altrimenti no. Come fare?

Io ho risolto in questo modo.

Analogamente a quanto fatto in un mio post precedente, vado a gestire l’evento Created dello screen che mi interessa:

partial void TeamsListDetail_Created() {  }

 

In questo modo, grazie ad un bel giochino di C# e lambda, scrivo poche righe di codice:

this.FindControl("CheckBox").ControlAvailable += (s, e) =>
{
checkbox = e.Control as CheckBox;
};

this.FindControl("TextBox").ControlAvailable += (s, e) =>
{
textbox = e.Control as TextBox;
textbox.TextChanged += (s2, e2) =>
{
checkbox.Visibility = textbox.Text.Equals("0") ? System.Windows.Visibility.Collapsed :
System.Windows.Visibility.Visible;
};
};

 

In breve, cerco di riassumere:

  • ottengo i riferimenti ai due controlli, rispettivamente chiamati “CheckBox” e “TextBox” – ovviamente i vari nomi vengono assegnati da Lightswitch, ma possono essere modificati
  • quando si scatena l’evento ControlAvailable della CheckBox, non faccio nulla di particolare: semplicemente mi vado a salvare il riferimento per usarlo dopo
  • quando si scatena l’evento ControlAvailable della TextBox, ne sottoscrivo l’evento TextChanged
  • ogni volta che l’utente cambia il testo contenuto nella TextBox, si scatena l’evento TextChanged – questo lo sappiamo bene, è il runtime di Silverlight. A questo punto è molto semplice, perchè faccio un banale controllo: quando la TextBox contiene “0” la CheckBox sparisce, altrimenti compare
  • notare che Lightswitch sulla UI produce anche la label della nostra proprietà (oltre al controllo per editare la proprietà stessa): la Label non è sotto il nostro controllo, per cui non potremo mai renderla invisibile/visibile (attendo correzioni se sbaglio Con la lingua fuori)

La soluzione c’è, e devo dire anche con poche righe di codice.
Sorriso

Perchè è stato fatto del male a questi due controlli? Per due motivi principali.

  • Innanzitutto è stata inserita una logica di business a livello di UI. Il fatto che la proprietà booleana Contributi debba essere false quando lo stipendio è zero mi sembra una regola del dominio (non è un’applicazione che sto sviluppando, perciò prendo per buona questa regola). Però questo non dovrebbe essere inserito nella UI, ma sulle entity vere e proprie. E’ per questo che ho consigliato di agire sulla entity, così questa regola viene “riciclata” indipendentemente dal fatto che venga utilizzato quello screen. Importantissimo!!! Quindi, per esempio, basta andare nel set della proprietà Stipendio e – se vale zero – metto a false la proprietà Contributo. Sia chiaro: questo non rende invisibile la CheckBox, si assicura solamente che i dati nelle entità di dominio siano valorizzate coerentemente con quello che il dominio vuole e si aspetta.
  • Il secondo errore è che scriviamo codice molto, molto specifico rispetto alla tecnologia del presentation layer. Come ha già osservato Alessandro Del Sole qualche giorno fa, oggi Lightswitch produce in output un’applicazione Silverlight. Ma in futuro potrebbe produrre HTML5, applicazioni Metro-style, WPF, e chissà cos’altro. Quando quel “futuro” sarà “presente”, saremo costretti a riprendere l’applicazione e a riscrivere quella parte. Uno dei vantaggi di Lightswitch è l’autogenerazione dinamica della UI, e se noi andiamo a metterci lo zampino, ne paghiamo e pagheremo le conseguenze.

Alla prossima!

Send to Kindle
.NET World

Utilizzare OpenFileDialog e SaveFileDialog con Lightswitch

Una delle cose più comuni all’interno di un’applicazione, sia Desktop che Web, è fornire all’utente la possibilità di aprire e salvare files sul proprio PC. Potrebbe trattarsi di una fattura in formato pdf, oppure di un semplice file di testo, xml, e via dicendo. Le possibilità sono innumerevoli, e dipendono ovviamente dal tipo di applicazione che state sviluppando.

Dal punto di vista developer, questa cosa si ottiene con le classi OpenFileDialog e SaveFileDialog. Queste classi sono disponibili allo stesso modo con Windows Forms, WPF ed ovviamente Silverlight. Il che tocca ovviamente anche il nuovo mondo Lightswitch. Arriviamo al dunque.

Per permettere all’utente l’apertura di un file è necessario scrivere qualche riga di codice. Apriamo lo Screen Designer relativo allo screen su cui vogliamo gestire questa cosa, e per semplicità aggiungiamo un pulsante nuovo, chiamato “PrintInvoice”.

Per editare il codice è sufficiente cliccare con il destro sul Button appena aggiunto e successivamente fare click su Edit Execute Code. In condizioni normali scriveremmo il codice seguente:

OpenFileDialog dialog = new OpenFileDialog();

partial void Print_Execute()
{
    var result = dialog.ShowDialog().GetValueOrDefault();

    if (result)
    {

    }
}

 

Ovvero: istanziamo un oggetto OpenFileDialog come membro privato della classe, e sul click del Button invochiamo la ShowDialog() per dare la scelta all’utente. Sfortunatamente con Lightswitch le cose sono un po’ diverse:

  • Innanzitutto l’istanziazione della classe OpenFileDialog deve avvenire nel thread UI (comunque facilmente accessibile attraverso Microsoft.LightSwitch.Threading.Dispatchers.Main)
  • Se anche risolvessimo il punto sopra, ci scontreremmo con un altro problema, tipico dello sviluppo Silverlight. Ovvero la chiamata a ShowDialog() deve avvenire sempre e comunque come diretta conseguenza di un’interazione fatta dall’utente. Nel nostro caso sarebbe il semplice click del mouse, ma evidentemente Lightswitch aggiunge qualche strato software che impedisce questa cosa. L’architettura che c’è dietro i Button creati e gestiti con Lightswitch – infatti – vengono gestiti attraverso il motore di binding di WPF/Silverlight, applicando il pattern MVVM. Vediamo infatti che dobbiamo gestire gli eventi Execute e CanExecute, che derivano direttamente dall’interfaccia ICommand.

Quindi, difatto siamo bloccati. Cosa dobbiamo fare per risolvere il problema? Bisogna complicarsi la vita, come sempre! Sorriso

Innanzitutto, andiamo a gestire l’evento Created dello Screen che ci interessa e scriviamo questo codice:

   1:  partial void InvoicesListDetail_Created()
   2:  {
   3:      Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() =>
   4:      {
   5:          dialog = new SaveFileDialog();
   6:          dialog.DefaultExt = "pdf";
   7:          dialog.Filter = "Documenti Pdf (*.pdf)|*.pdf|Tutti i files (*.*)|*.*";
   8:      });
   9:   
  10:      var printInvoiceButton = this.FindControl("PrintInvoice");
  11:      printInvoiceButton.ControlAvailable += printInvoiceButton_ControlAvailable;
  12:  }

 

In fase di creazione dello Screen, utilizzo il thread UI per inizializzare l’oggetto dialog, definito – come prima – come membro della classe. Oltre a questo, utilizzo l’extension method FindControl per ottenere un riferimento al Button che ci interessa.

Una cosa importante: il metodo FindControl, come già detto, è un extension method. Assicuratevi di avere la riga using Microsoft.LightSwitch.Presentation.Extensions, altrimenti non potrete mai utilizzarlo.

Una volta ottenuto il riferimento al Button, utilizzando il suo nome che avete impostato nello Screen Designer, ne sottoscrivo l’evento ControlAvailable. Questo, finalmente, mi porta a poter gestire l’evento Click.

   1:  void printInvoiceButton_ControlAvailable(object sender, ControlAvailableEventArgs e)
   2:  {
   3:      this.FindControl("PrintInvoice").ControlAvailable -=
   4:          printInvoiceButton_ControlAvailable;
   5:      var button = (Button)e.Control;
   6:      button.Click += button_Click;
   7:  }
   8:   
   9:  void button_Click(object sender, RoutedEventArgs e)
  10:  {
  11:      dialogResult = dialog.ShowDialog().GetValueOrDefault();
  12:  }

 

Nulla di particolarmente complicato. All’interno dell’evento Click possiamo visualizzare all’utente la finestra di dialogo, chiamando semplicemente il metodo ShowDialog(). Qui si sfrutta un comportamento particolare di Lightswitch: quando cliccate su un Button gestito secondo questa tecnica, prima viene richiamato l’evento Click, e solo successivamente viene eseguito il codice contenuto nell’Execute, che a questo punto conterrà una cosa simile a questa:

partial void PrintInvoice_Execute()
{
    if (dialogResult)
    {

    }
}

 

Il fatto di aver cliccato sul Button, quindi, prima visualizza la dialog (evento Click). Quando l’utente la chiude, sia scegliendo un file, sia cliccando su Annulla, viene eseguito l’Execute del Button associato. A questo punto si testa il valore restituito dalla dialog e si agisce di conseguenza.

Conclusione

Ok, il problema è risolvibile senza grossi problemi, ma il tutto mi sembra una forzatura, e ci richiede di scrivere codice “a basso livello”, che va un po’ in direzione opposta rispetto alla filosofia di Lightswitch. Che dire, magari la cosa verrà migliorata in futuro, con qualche patch o fix. Staremo a vedere!

Send to Kindle
.NET World

Microsoft Lightswitch, deploy di un’applicazione con autenticazione

Una delle features più interessanti di Lightswitch è la sua possibilità di effettuare il deploy direttamente sul server Web da cui poi sarà fruibile. Una comodità che fa piacere ai developer meno skillati, e che accelera il lavoro ai developer più esperti.

Il server Web può essere locale, all’interno della vostra LAN oppure esposto su Internet. In quest’ultimo caso, è necessario che il provider abbia installato tutti i pre-requisiti di Lightswitch. Come avevo citato nel mio primo post dedicato a Lightswitch, le possibilità di deploy messe a disposizione sono due:

  1. Deploy diretto da Visual Studio 2010
  2. Generazione in locale sul proprio PC un file di package (che non è nient’altro che un file zip), da importare sul server Web tramite la console IIS installata localmente sul proprio PC

Nel mio caso specifico, con www.winhost.com, sono obbligato a seguire la procedura (2). Non sto qui a scendere nel dettaglio: vi basti sapere che da VS2010 producete un file di package (.zip), che contiene tutti i files necessari per deployare l’applicazione: files, script SQL, parametri per la creazione dell’applicazione sotto IIS, etc. etc.

L’applicazione su cui sto lavorando per Brain-Sys fa utilizzo anche dell’autenticazione offerta dal Membership Provider. In questo caso, nel momento in cui effettuate l’installazione dell’applicazione su IIS, il wizard vi chiede, tramite una dialog dedicata, anche username & password dell’utente Administrator, per fare il primo login e procedere alla creazione degli altri utenti & ruoli, etc. etc. Per motivi che onestamente non siamo riusciti a capire, a me questa dialog non compare. Risultato? L’applicazione veniva deployata senza alcun problema, e raggiungendo il suo url (esempio: http://www.dominio.it/Nomeapp) appariva la form di login, ma non essendoci utenti configurati (ripeto: nemmeno l’Administrator) … difatto l’applicazione rimaneva inutilizzabile.

Ma abbiamo trovato una soluzione, spiegata in questo thread.

In pratica, tutta la struttura del database è ok: quello che manca è un bel record all’interno della tabella aspnet_Users (e qui ovviamente stiamo parlando di Membership Provider). Escludiamo a priori di aggiungere manualmente un record: non si fa, non si fa, non si fa. E quindi, cosa si fa? Semplice.

Se avete installato Lightswitch sul vostro PC, andate nella directory:
C:Program Files (x86)Microsoft Visual Studio 10.0LightSwitch1.0Tools

All’interno di questa directory trovate il file Microsoft.LightSwitch.SecurityAdmin.exe. E’ sufficiente eseguire da command-line questo comando…
Microsoft.LightSwitch.SecurityAdmin.exe/createadmin /user:Admin /password:pwd /fullname:Administrator /config:C:Documentiweb.config

…per ottenere il vostro utente Administrator. Qualche precisazione:

  • /user:nome_utente (va specificato lo username dell’utente che volete creare)
  • /password:password_utente (va specificata la password dell’utente che volete creare)
  • /fullname:nome_completo (va specificato il nome completo dell’utente)
  • /config:filepath (va specificato il percorso completo del web.config sul vostro PC, che contiene la stringa di connessione che punta al database che vi interessa)

Se il comando non vià segnala alcun errore, significa che l’utente Administrator è stato creato con successo. Potete loggarvi all’interno della vostra applicazione Lightswitch. Se fatta a dovere, la vostra applicazione vi mette a disposizione tutti gli strumenti per creare altri utenti, altri ruoli, e per effettuare l’assegnamento di ruoli ai singoli utenti.

Et voilà, problema risolto!

Send to Kindle
.NET World

Rientro dalle ferie? Microsoft Lightswitch a tutta forza!

www.microsoft.com/visualstudio/en-us/lightswitch/overview/comparePochi giorni prima delle mie ferie, esattamente il 27 Luglio scorso, ho seguito un evento in streaming dedicato interamente a Microsoft Lightswitch 2011, organizzato dalla community italiana dedicata proprio a questo nuovo prodotto. Per chi se lo fosse perso, le registrazioni alle varie sessioni sono disponibili a questo indirizzo (attenzione, dovete essere utenti registrati per visionarli).

Fino a quel giorno avevo sentito parlare poco di Lightswitch 2011. Qualche tweet, qualche news, qualche post da parte del nostro amico Alessandro Del Sole. L’evento, molto interessante, ha messo in mostra le caratteristiche principali del software, partendo dai concetti più semplici fino alle features più avanzate. Non so perchè, deve essere stato una sorta di sesto senso, ma sentivo che Lightswitch potesse essere un cavallo su cui puntare, e sono riuscito a trasmettere questo interesse internamente a Brain-Sys. Ho seguito l’evento, sessione dopo sessione, ho twittato i contenuti che trovavo più stuzzichevoli e ne sono uscito con una determinazione che mi ha fatto dire: “Cascasse il mondo, devo provarlo e studiarlo almeno un po’!”.

Ma torniamo un po’ all’inizio. Cos’è esattamente Microsoft Lightswitch? Definirlo è forse un po’ complicato. Le caratteristiche che lo contraddistinguono sono:

  • Strumento di sviluppo RAD (Rapid Application Development)
  • Viene di fatto installato all’interno di VS2010, comparendo come nuovo tipo di progetto (nota: Lightswitch è utilizzabile anche come prodotto stand-alone, vedere in fondo al post)
  • Ideale per applicazioni data-centriche
  • Generazione automatica di tabelle ed interfaccia utente Silverlight 4 (applicazione desktop OOB oppure fruibile via browser)
  • Infrastruttura n-tier con WCF RIA Services
  • Deploying automatico su un server Web (esempio: un server Web locale, oppure remoto in hosting come winhost.com, etc.)
  • Supporto per le autenticazioni e autorizzazioni tramite Membership Provider
  • Estendibilità tramite controlli custom
  • Al 100% mi sto dimenticando di qualcosa: vi consiglio di googlare o di visitare il sito Web ufficiale per tutte le info
    Sorriso

Il fatto è che se dovete creare un’applicazione Web in breve tempo per costruire anagrafiche, un piccolo gestionale, una rubrica, un archivio di qualche tipo, qualsiasi cosa che lavori sui dati, probabilmente Lightswitch 2011 fa al caso vostro. Il database è completamente auto-generato in base alle entity che disegnate, la UI è auto-generata in base a ciò che stabilite all’interno dello Screen Designer, potete inserire regole di validazione, potete avere la UI localizzata, potete scrivere codice custom (ad esempio per aggiungere calculated property, per aggiungere alla UI Button custom, per validare entity), potete creare controlli Silverlight da incorporare in Lightswitch. Insomma, il vostro lavoro può partire considerando Lightswitch come un ambiente di sviluppo “sempliciotto” e molto RAD, ma vi posso assicurare che, spremendolo a dovere, potete ottenere degli ottimi lavori.

Parliamo di deploy. Quando la vostra applicazione è terminata, dovete ovviamente deployarla da qualche parte. La procedura di publishing di Lightswitch fa in modo di semplificare il più possibile il compito al developer (assumendo che non abbia skill a sufficienza) e può avvenire secondo due metodi:

  1. Deployare direttamente da Visual Studio 2010 sul server Web (locale o remoto)
  2. Generare in locale sul proprio PC un file di package (che non è nient’altro che un file zip), da importare sul server Web tramite la console IIS installata localmente sul proprio PC

In ambedue i casi, ovviamente, dovete avere i permessi e le credenziali adeguate. Non solo: se stiamo parlando di deployare su un vostro hosting (come nel mio caso http://winhost.com o http://discountasp.net), dovete assicurarvi che questi supporti Lightswitch, con tutta una serie di pre-requisiti. Il provider può adeguarsi in modo piuttosto semplice usando il Web Platform Installer, che fa tutto in automatico. E se invece cercate un hosting già pronto per Lightswitch, il sito Microsoft riporta qualche informazione in merito a questo indirizzo. Ultima menzione: Lightswitch supporta anche il deploy su Azure. Mica male, no?

Per concludere, in circa una settimana di lavoro ho messo in piedi un prodotto che – se fatto da zero ed a parità di complessità tecnologica – avrebbe richiesto sicuramente molto, molto, molto più tempo. Trattandosi di un progetto reale non posso in questo momento scendere nel dettaglio, ma vi posso assicurare che la produttività è stato altissima, al punto che abbiamo già deployato una versione beta da far vedere al cliente.

Ultimissime note: grazie ad Alessandro Del Sole per il suo costante impegno ad aiutare il prossimo, e grazie a tutta la community italiana www.lightswitch.it, che si dimostra attiva e di buon livello, considerando che si tratta di un prodotto appena uscito sul mercato.

Giovedì 1 Settembre 2011, 22:24 – Aggiornamento dell’ultim’ora. Giustamente, mi è stata fatta notare una cosa importante su Microsoft Lightswitch. Se già possedete Visual Studio 2010, Lightswitch si installa all’interno di questo ambiente di sviluppo – come già ho detto prima, lo avete come un nuovo tipo di progetto. Se non possedete Visual Studio 2010, niente paura: Lightswitch è anche un IDE separato, per cui potete tranquillamente utilizzarlo anche in questo modo. Qualche info in merito la trovate qui (comparazione tra Lightswitch stand-alond e Lightswitch con VS2010).

Send to Kindle