Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1904, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Xamarin.Forms e i servizi WCF

Windows Communication Foundation è una delle tecnologie su cui molti sviluppatori hanno investito, nel tempo, per offrire informazioni, dati e operazioni all'interno di reti e di architetture SOA.

Sebbene oggi si preferiscano maggiormente servizi che supportano lo standard REST, tipo Web API, WCF riveste ancora una grande importanza per due motivi: fare tutto ciò per cui Web API è meno indicato e perché, appunto, ci sono investimenti esistenti.

Chiaramente, da quest'ultimo punto di vista, può emergere la necessità di far dialogare anche un'app per dispositivo Android, iOS e Windows con un servizio WCF e, per quello che interessa noi, Xamarin e la sua parte Xamarin.Forms. Pertanto in questo post vedremo come consumare servizi WCF da Xamarin.Forms superando alcune limitazioni di progetti che difficilmente ci riguarderanno ancora.

Il problema è infatti il seguente: in Xamarin.Forms, nel progetto PCL (quello in cui condivido il codice tra le piattaforme) non esiste più la voce Add Service Reference. Devo quindi crearmi la classe proxy a manina? No, una soluzione c'è.

Creare un servizio WCF

Per questo post creeremo un semplicissimo servizio WCF che esporrà un'operazione di servizio il cui compito è quello di calcolare l'area di un cerchio. Non ci serve affatto un servizio complicato, ci serve capire i passaggi soprattutto lato client. Utilizzerò C# (...) solamente per consistency con Xamarin, ma il servizio si può scrivere senza dubbio anche in VB. Visual Studio 2015 dev'essere avviato con privilegi di amministratore, perché poi pubblicheremo il servizio su IIS locale. Non utilizzeremo IIS Express che richiede configurazioni particolari per l'emulatore Android. Creato un progetto di tipo WCF Service Application, la prima cosa è definire il contract, ossia l'interfaccia-contratto che definiremo in questo modo (rinominando quella di default):

[ServiceContract] 
public
 interface ICircleService
{    
[OperationContract]    
double CalculateCircleArea(double radius);
}

Quindi, la classe di servizio che implementa il contract, anch'essa definita rinominando la parte .svc di default:

public class CircleService : ICircleService 
{    
public
 double CalculateCircleArea(double radius)    
{        
return
 radius*radius*Math.PI;    
}
}

Posto che il progetto compila, lo pubblichiamo facendo clic destro sul progetto, Publish. Nella finestra di pubblicazione dapprima selezioniamo il profilo Custom, a cui daremo un nome, quindi inseriamo le informazioni per la pubblicazione su IIS locale:



Al termine della pubblicazione, ci accerteremo che il servizio funzioni digitando l'URL http://localhost/WcfCircleService/CircleService.svc nel browser. Nel frattempo, munitevi dell'IP della vostra macchina di sviluppo (o comunque quella su cui pubblicate il servizio). Mentre usare Localhost va bene per la pubblicazione, per la connessione al servizio ci vuole l'IP per i motivi che poi vi spiego.

Consumare servizi WCF da un'app Xamarin.Forms
Un'app per Android, iOS e Windows scritta con Xamarin.Forms può facilmente consumare un servizio WCF. C'è un però: se vogliamo sfruttare il famoso comando Add Service Reference, dobbiamo rimuovere i progetti Windows 8.1 e Windows Phone 8.1. In teoria questo non sarà un grosso danno, se stiamo creando un nuovo progetto è molto probabile che ci interessi più che altro la parte di Universal Windows Platform. Creato quindi un nuovo progetto Xamarin.Forms basato su Portable Class Library, prima di connetterci al servizio dobbiamo eseguire questa sequenza di passaggi:

  1. Rimuovere i progetti Windows 8.1 e Phone 8.1. Già solo questo farà magicamente riapparire il comando Add Service Reference (c'è una nota limitazione legata ai progetti Windows Phone)
  2. Dal progetto PCL, rimuovere il pacchetto NuGet Xamarin.Forms. Questo è necessario perché dobbiamo cambiare il target della PCL
  3. Nelle proprietà del progetto PCL, clicchiamo su Change vicino ai target supportati e cambiamoli con quelli visibili nella prossima figura (di fatto togliamo Windows Phone 8.1)
  4. Reinstalliamo il pacchetto Xamarin.Forms da NuGet.



Fatto questo, possiamo finalmente connetterci al servizio WCF mediante Add Service Reference nel progetto PCL:




Importante: nell'indirizzo del servizio, mettete l'indirizzo IP. Non localhost, né il nome della macchina perché l'emulatore Android considera se stesso come il localhost. A questo punto il più è fatto. Nella pagina principale di questa app, possiamo scrivere dello XAML molto semplice che richieda l'inserimento del raggio e attenda il risultato del calcolo a seguito della pressione di un pulsante:

  <StackLayout Orientation="Vertical">     
<
Label Text="Insert radius:"             
VerticalOptions="Center"             
HorizontalOptions
="Center" />    
<
Entry x:Name="RadiusEntry" />    
<
Button x:Name="CircleButton" Text="Go!" Clicked="CircleButton_Clicked"/>    
<
Label x:Name="ResultLabel"/>  
</
StackLayout>
Il code-behind è altrettanto semplice, si crea l'istanza della classe client e si invoca il metodo di servizio:

public partial class MainPage : ContentPage 
{    
CircleServiceClient
 client;    
public MainPage()    
{        
InitializeComponent();        
this.client = new CircleServiceClient();        
this
.client.CalculateCircleAreaCompleted += Client_CalculateCircleAreaCompleted;    
}    

private
 void Client_CalculateCircleAreaCompleted(object sender, CalculateCircleAreaCompletedEventArgs e)    
{            
this
.ResultLabel.Text = e.Result.ToString();    
}    
private
 void CircleButton_Clicked(object sender, EventArgs e)    
{            
double
 radius = double.Parse(this.RadiusEntry.Text);            
this
.client.CalculateCircleAreaAsync(radius);    
}
}

Una considerazione fondamentale: non c'è modo di cambiare la generazione del codice basato su APM (Asynchronous Programming Model), quindi anche se la nostra operazione di servizio restituisce double, la classe proxy la costringe a ritornare void per poi scatenare un evento al completamento dell'operazione, all'interno del cui gestore troveremo il risultato dell'operazione stessa. Altre operazioni di generazione del codice sono disabilitate e pertanto, almeno da quel che ho visto, ce lo dobbiamo tenere così.

I permessi

Ricordiamoci che le nostre app devono poter accedere alla rete e pertanto devono avere i relativi permessi. Un'app Android vuole la permission Internet, una UWP vuole la Internet (client) e la Private Networks se siete all'interno di una rete locale. I permessi vanno impostati nei relativi manifest.

Risultato finale
Al termine di questo lavoro, la nostra app riesce a consumare il servizio WCF in modo molto semplice:



Come detto, il servizio utilizzato è molto molto semplice. La logica di connessione e generazione della classe proxy, però, è quella anche in servizi più complessi.

Alessandro

Print | posted on mercoledì 13 luglio 2016 00:00 | Filed Under [ Xamarin ]

Powered by:
Powered By Subtext Powered By ASP.NET