JSON for Dummies (parte 4)

Dopo aver visto come connetterci ad un servizio REST con HttpClient (vedi la parte 3) concludiamo l’argomento illustrando come connetterci ad un servizio REST autenticato e come eseguire altre operazioni che non siano solo il semplice GET.

Tutto quello che dobbiamo fare è semplicemente usare il costruttore dell’HttpClient che prende un oggetto HttpClientHandler come parametro e impostare la proprietà Credential di quest’ultimo uguale ad un oggetto NetworkCredential che possiamo passare alla nostra funzione

 NetworkCredential credential = new NetworkCredential(username, password); 

L’ultima cosa da modificare è DefaultRequestHeaders dell’HttpClient, e a questo punto la funzione che permette di fare una chiamata Get autenticata può essere scritta in questo modo:

  
public static async Task<T> GetAsyncAuthenticated<T>Uri uri, NetworkCredential credential) 
{
     using (var http = new HttpClient(new HttpClientHandler { Credentials = credential }))     
     {         
          http.DefaultRequestHeaders.Add"Accept", "application/json");
          http.DefaultRequestHeaders.Add("user-Agent", "authentication.cs");
          var response = await http.GetAsync(uri);
          string json = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();
          var output = JsonConvert.DeserializeObject<T>(json);
          return output;
     } 
} 

In modo assolutamente analogo possiamo scrivere una funzione che esegua un POST autenticato (o non autenticato, basta rimuovere le parti relative all’autenticazione), dove ovviamente dobbiamo passare anche un content da passare al POST

 
public static async Task<T> PostAsyncAuthenticated<T>(Uri uri, NetworkCredential credential, HttpContent content)
{ 	
     using (var http = new HttpClient(new HttpClientHandler { Credentials = credential }))
     {                 
          http.DefaultRequestHeaders.Add("Accept", "application/json");
          http.DefaultRequestHeaders.Add"user-Agent", "authentication.cs");
          var response = await http.PostAsync(uri, content);                 
          string json = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();                 
          return JsonConvert.DeserializeObject<T>(json); 	
     } 
} 

Come vedete usando HttpClient è tutto molto semplice. Buon lavoro!

Mobile Camp Roma 12 Febbraio

Giovedì 12 Febbraio 2015 a Roma, presso la sede Microsoft in viale Avignone 10 (Zona EUR, dietro al Centro Commerciale EURoma), si terrà un Mobile Camp, evento gratuito in cui si parlerà di sviluppo per Windows 8.1 e Windows Phone 8.1 con il supporto esclusivo di esperti Microsoft, delle Community e degli altri sviluppatori presenti. 

Durante la giornata saranno presentate sessioni teoriche di natura tecnica, riguardanti le ultime novità nel campo mobile. Non potete perdere questa occasione, anche perché ci sarò anche io a presentare una sessione Occhiolino

image

Per iscrivervi andate sulla pagina dell’evento

OT: Boot nativo di Windows 10 da un disco virtuale VHD

Avete installato Windows 10 TP, vero? Se non l’avete installato correte subito sulla pagina del Windows Insider Program, iscrivetevi e scaricate la vostra ISO preferita (32 o 64 bit, anche in lingua italiana). Installatelo perché sia che abbiate Windows 7 o Windows 8.x l’upgrade a Windows 10 sarà gratuito per il primo anno. E quindi meglio abituarsi da subito al futuro Windows.

Dopo avere scaricato la ISO, avete diverse strade per provare il nuovo sistema:

  • potreste installare il nuovo sistema in dual boot su una nuova partizione
  • potreste installare la Technical Preview in una macchina virtuale (magari su Hyper-V, che è già incluso in Windows, senza dover installare programmi di terze parti)
  • potreste aggiornare il vostro sistema attuale

La prima soluzione è consigliata se volete avere le massime performance dal vostro nuovo sistema, ma richiederà di cambiare configurazione del vostro disco per ripartizionare. La seconda soluzione è quella che impatta meno sulla vostra configurazione attuale, quando ne avrete abbastanza potete semplicemente eliminare la macchina virtuale e il disco virtuale ad essa connesso e sarà come non fosse mai successo nulla. Il prezzo da pagare è che un sistema virtualizzato sarà meno prestante di un sistema che gira sul ferro. La terza soluzione è quella che sconsiglio a meno che non abbiate una macchina da usare come cavia, perché stiamo pur sempre parlando di una release preliminare.

In realtà c’è una quarta via, che unisce i vantaggi delle prime due. Potete installare su una macchina virtuale e poi fare il boot del vostro sistema direttamente dal disco virtuale (vhd), in modo da evitare la virtualizzazione. Questa modalità è chiamata boot-to-vhd.

1. Se non avete installato Hyper-V andate su Pannello di Controllo –> Programmi –> “Attiva o disattiva funzionalità di Windows” (o se avete Windows 8 direttamente Cerca –> “Attiva o disattiva funzionalità di Windows”) ed abilitate Hyper-V

image

2. Create una nuova macchina virtuale e installate Windows 10 Technical Preview. Se volete utilizzare la funzione di boot-to-vhd dovete installare la versione analoga a quella che avete come sistema primario (x86 o x64).


AGGIORNAMENTO:

Potete installare direttamente Windows 10 in un disco virtuale VHD tramite la procedura indicata qui: Convert-WindowsImageps1
Potete sempre caricare il disco virtuale in una nuova macchina virtuale successivamente.


3. Montate il disco virtuale sul vostro sistema. Da Gestione Disco –> Azione –> Collega file VHD

image

4. Aggiungete una voce al boot menu di Windows. Aprite il prompt dei comandi in modalità amministratore e digitate bcdboot e:\Windows (posizione della cartella di installazione di windows nel disco virtuale appena montato)

E’ tutto. Ora potete riavviare il sistema e scegliere Windows 10 Techical Preview come sistema di avvio.

PS: Per riportare il sistema allo stato originale, eliminate la macchina virtuale ed il disco virtuale. Per eliminare la voce aggiuntiva dal menu di boot, aprite il prompt dei comandi in modalità amministratore e digitate:
bcdedit /enum per ottenere l’elenco di tutte le voci
bcdedit /delete {identifier} per eliminare una voce

JSON for Dummies (parte 3)

In questo terzo post della serie JSON for Dummies (qui la parte 1 e la parte 2) vedremo una implementazione più elegante del processo di deserializzazione di dati JSON provenienti da un servizio REST.

Creeremo una funzione asincrona generica che si occupi di connettersi al servizio remoto, scaricare i dati e deserializzarli nel tipo corretto. La prima modifica è che useremo il metodo GetAsync() di HttpClient invece del metodo GetStringAsync(). In questo modo avremo una risposta del tipo HttpResponseMessage  che espone proprietà utili a stabilire l’esito della connessione. In questa prima implementazione Controlleremo che lo StatusCode della risposta sia positivo prima di continuare. In caso contrario lanceremo una eccezione. Dopo aver verificato l’esito positivo dell’operazione possiamo deserializzare il contenuto della risposta con ReadAsStringAsync().

public async Task<T> GetAsync<T> (Uri uri)
{
    using (var http = new HttpClient())
    {
         http.DefaultRequestHeaders.Add("Accept", "application/json");
         var response = await http.GetAsync(uri);
         if (response.StatusCode != System.Net.HttpStatusCode.OK)
         throw new Exception(response.StatusCode.ToString());
         string json = await response.Content.ReadAsStringAsync();
         return JsonConvert.DeserializeObject<T>(json);
    }
}

Grazie all’uso di HttpResponseMessage  possiamo rendere ulteriormente compatto il codice sostituendo il controllo dell’esito della richiesta  (tutta la struttura dell’if) con

response.EnsureSuccessStatusCode();

dato che il metodo EnsureSuccessStatusCode() restituisce l’HttpResponseMessage in caso di esito positivo, la nostra funzione finale può essere scritta in questo modo:

public static async Task<T> GetAsync<T> (Uri uri)
{
using (var http = new HttpClient())
{
http.DefaultRequestHeaders.Add(“Accept”, “application/json”);
var response = await http.GetAsync(uri);
string json = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(json);
}
}

In questo modo basterà richiamare la funzione appena definita sostituendo T con il tipo di oggetto da deserializzare e uri con la url del servizio

MyStruct struct = await GetAsyncAuthenticated<MyStruct>(uri);

Nel prossimo episodio vedremo come connettersi a servizi REST autenticati.

ASP.NET Web API for Dummies

Dopo avere visto come utilizzare il formato JSON per scambiare dati tra la nostra applicazione e un servizio remoto, in questa nuova serie for dummies vedremo come creare un servizio remoto che possa servire dati alla nostra, o ad altre applicazioni.

Notiamo subito che basandosi i servizi REST, di questo stiamo parlando, sullo scambio di file di testo tramite semplici chiamate HTTP, la tecnologia che usiamo nella creazione del servizio remoto non è in nessun modo vincolata alla tecnologia usata nella creazione dell’app.

Utilizzeremo un progetto Web Api di ASP.NET MVC che potrà essere ospitato su un qualsiasi servizio web con IIS. Noi utilizzeremo Azure, il servizio cloud di Microsoft, che permette di creare gratuitamente fino a 10 siti web.

Da Visual Studio creiamo dunque un nuovo progetto web di tipo applicazione Web ASP.NET (Se avete VS 2013 questo è l’unico tipo di progetto web che potete creare, se invece avete Visual Studio 2012 dovrete scegliere un’applicazione MVC4).

Cattura di schermata (3)

Come modello scegliamo Web Api tra quelli disponibili.
Modifichiamo l’autenticazione impostando nessuna autenticazione.
Se avete un acount Azure possiamo gestire direttamente anche la connessione con il servizio cloud impostando la sottoscrizione su cui volete pubblicare il vostro sito web, ma questo lo vedremo in un’altra occasione. Per il momento deselezionate Host nel cloud

Cattura di schermata (2)

A questo punto il vostro servizio web è pronto. Se avviate il progetto con F5 il sito web verrà lanciato nel server IIS locale, pronto a rispondere alle chiamate remote. Il template MVC costruisce per voi tutto il sito web, compresa pagina di documentazione delle API.

image

Cliccando sulla barra in alto su API arriverete a questa pagina, in cui avete la documentazione della Web API creata di default dal template, che in seguito andremo a modificare. Come si vede, il template predispone due metodi GET, un metodo POST, uno PUT e un DELETE.

image

Per invocare il servizio potete scrivere l’indirizzo del server completato con l’indirizzo dell’API. Nel mio caso l’indirizzo della prima funzione GET è http://localhost:49039/api/Values che vi restituirà, indovinate? Un file JSON.

Il file restituito Values.json ha il seguente contenuto

[“value1″,”value2”]

Il codice che definisce le funzioni restituite dai metodi HTTP è racchiuso in una classe che eredita dalla classe ApiController. Nello specifico la classe è ValuesController, nel file ValuesController.cs nella cartella Controllers del progetto, e la funzione è

public IEnumerable<string> Get()
        {
            return new string[] { “value1”, “value2” };
        }

Come vedete la funzione restituisce un oggetto di tipo array di stringhe, che viene serializzato automaticamente in JSON e scritto nel file di uscita.

A questo punto vogliamo aggiungere un nuovo controller che chiameremo TestController. Clicchiamo con il tasto destro sulla cartella controller e scegliamo la voce
Aggiungi –> Controller

Scegliete Controller Web API con azioni di lettura/scrittura e date un nome al vostro controller. Il prefisso davanti alla parola Controller sarà il nome della vostra Web API (nel nostro caso Test. Aggiungiamo anche nella cartella Models  le classi che abbiamo già utilizzato nell’esempio di JSON for Dummies

public class MyStruct
    {
        public string Title { get; set; }
        public string Name { get; set; }
        public List<MyItem> List { get; set; }
    }

    public class MyItem
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }

A questo punto possiamo creare un nuovo oggetto di tipo MyStruct nel costruttore del Controller

public TestController()
        {
            Struct = new MyStruct()
            {
                Title = “test”,
                Name = “name”,
                List = new List<MyItem>()
                {
                    new MyItem(){Id = 0, Name=”name0″, Description= “description0”},
                    new MyItem(){Id = 1, Name=”name1″, Description= “description1”},
                    new MyItem(){Id = 2, Name=”name2″, Description= “description2”},
                }
            };
        }

e modificare il metodo Get() in modo che restituisca proprio il nostro oggetto Struct

public MyStruct Get()
        {
            return Struct;
        }

Lanciando il servizio web nella pagina di documentazione delle API è apparsa la nuova API Test con i suoi metodi

image

Cliccando sulla funzione GET api/Test da noi modificata vedrete la documentazione degli oggetti restituiti ed anche un esempio del file JSON ed XML generati dal servizio.

image

A questo punto possiamo commentare o cancellare le funzioni che non abbiamo implementato ed anche cancellare il controller di default ValuesController.cs.

L’ultimo tocco riguarda come migliorare la documentazione. Nella pagina che espone tutti i metodi delle Web API nel campo Descrizione è sempre riportato No Description Available. Per personalizzare la descrizione dobbiamo eseguire le seguenti operazioni:

1. Togliere il commento dalla riga

config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath(“~/App_Data/XmlDocument.xml”)));

nel file Areas\HelpPage\App_Start\HelpPageConfig.cs 

2. Aggiungere il percorso del file XML App_Data/XmlDocument.xml  indicato in questa riga nelle proprietà del progetto web al tab Compila nell’opzione File di Documentazione XML.

image

3. Aggiungere commenti dentro il codice, sia nel controller che nelle classi, ad es.

        /// <summary>
        /// Descrizione funzione
        /// </summary>
        /// <returns>
        ///  output description
        /// </returns>
        public MyStruct Get()
       {
              …
       }

Basta scrivere /// e Visual Studio creerà la struttura per noi. Compilando e avviando il progetto anche la pagina di documentazione sarà completa.

In questo modo possiamo spostare parte della logica della nostra app in un servizio remoto e possiamo quindi aggiornare i contenuti della nostra app senza dover pubblicare una nuova versione.

E anche per oggi abbiamo terminato.