Creare un Web Service in .Net e richiamarlo da applicazioni esterne

I Web Services sono delle applicazioni, o meglio delle classi con relativi metodi che possono essere richiamate da altre applicazioni.

Un grande vantaggio è la possibilità di definire un Web Service in un sistema e linguaggio, e poterlo poi richiamare da un programma definito in un sistema e linguaggio completamente differente.
Ad esempio un Web Service che risiede su sistema Microsoft IIS, creato usando C# o VB.Net, può essere consumato da una applicazione desktop installata su un pc o da una applicazione web che risiede su un altro server (ad es. una pagina PHP su server Apache).

Chi consuma il Web Service effettua una richiesta Http, che può essere di tipo GET o POST, e lo scambio dati avviene in formato testo, che può essere Soap/Xml oppure JSon.
E' possibile impostare un WS in modo che sia fruibile da chiunque, oppure limitarne l'accesso e proteggerlo da password.

Le possibili combinazioni sono numerose, in questo ed altri articoli mostrerò solo alcuni esempi per avere un'idea di come funziona.

Creare un Web Service con Visual Studio

Nel mondo Microsoft esistono due tipi principali di Web Services: quelli "tradizionali" e i WCF (Windows Communication Foundation). Entrambi i tipi possono trasmettere dati in forma Soap/Xml e JSon. In questo articolo mi occuperò dei WS del primo tipo, che sono immediati da comprendere e utilizzare.

Visual Studio rende davvero semplice la creazione di un Web Service. Per prima cosa si aggiunge un file di tipo .asmx al Sito Web. Il template include i namespaces necessari e presenta già una classe con un metodo HelloWorld di esempio.

File >> New File >> Add New Item >> Web Service

Poi si definiscono i vari metodi, proprietà ecc che servono svolgere le attività. Questi membri sono tutti "interni", non visibili dall'esterno del progetto. Per rendere un metodo (o una proprietà) utilizzabile da applicazioni esterne è sufficiente farlo precedere da <WebMethod()> _.

E' bene definire anche il namespace, facendolo solitamente coincidere con il dominio del sito che ospita il WS.
In questo esempio ho creato una semplice funzione che esegue la somma di due numeri interi.

Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols

<System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://www.dev-oclock.com")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class srb_service
    Inherits System.Web.Services.WebService

    <WebMethod()> _
    Public Function Somma(ByVal num1 As Short, ByVal num2 As Short) As Short
        Return num1 + num2
    End Function

End Class

In C# la sintassi è leggermente diversa:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

Consumare un Web Service da una pagina AspNet

Per poter usare un Web Service in una applicazione AspNet esterna, è necessario aggiungere il riferimento al WS tramite Visual Studio.

Web Site >> Add Service Reference >> Inserire l'URL del file .asmx >> Advanced >> Add Web Reference >> Inserire il percorso del file .asmx seguito da ?wsdl >> Freccia destra >> Impostare un namespace

Dal pannello Esplora Soluzione di Visual Studio si può notare che viene aggiunta una cartella per il riferimento; vengono anche aggiunte informazioni nel file web.config

Ora è possibile istanziare l'oggetto come se la classe del Web Service fosse stata definita nello stesso progetto. Si ha quindi il supporto di IntelliSense durante la digitazione. In questo esempio ho creato due textbox dove inserire gli addendi, poi ho richiamato il metodo Somma del Web Service, e infine ho stampato il risultato in una label. L'addizione quindi viene calcolata dal server su cui risiede il Web Service.

Protected Sub btnSomma_Click(sender As Object, e As System.EventArgs) Handles btnSomma.Click
    Dim objSRB As devoclock.srb_service = New devoclock.srb_service
    lblRisultato.Text = (objSRB.Somma(CType(txtAddendo1.Text, Short), CType(txtAddendo2.Text, Short))).ToString
End Sub

Questa è l'interfaccia dell'applicazione che si vede sul browser:

Richiamare un Web Service da una applicazione desktop Windows Form

I passaggi per usare un WS in una applicazione desktop sono quasi identici a quelli appena visti per una applicazione AspNet.
Tramite Visual Studio si aggiunge il riferimento al WS.

Project >> Add Service Reference >> Inserire il percorso del file .asmx >> Advanced >> Add Web Reference >> Inserire il percorso del file .asmx seguito da ?wsdl >> Freccia destra >> Impostare un namespace

Questo esempio è la versione Windows Form dell'esempio precedente. Si crea un'istanza della classe, e si ha a disposizione il metodo Somma poiché è stato volutamente reso fruibile dall'esterno.
Per precisione ho voluto convertire i tipi di dato con CType in quanto vengono letti da textbox, mentre il metodo accetta in pasto due variabili di tipo numerico Short.

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Dim s As com.devoclock.www.srb_service = New com.devoclock.www.srb_service
    lblSomma.Text = CType(s.Somma(CType(txtNum1.Text, Short), CType(txtNum2.Text, Short)), String)
End Sub

Nota: le versioni Express di Visual studio 2010 non supportano pienamente l'aggiunta di riferimenti Service, è quindi consigliabile usare la versione completa di VS.

Usare un Web Service asmx da una applicazione PHP

In php esistono diversi modi per agganciarsi a un Web Service, anche usando estensioni di terze parti come nuSoap. Per questo esempio ho voluto usare la classe SoapClient in quanto mi sembra quella più semplice ed è nativa di php.

I Web Service di tipo .asmx per default usano il protocollo Soap per comunicare. Di conseguenza per usarli in PHP è necessario  che sia attivo il modulo soap-wsdl. Per assicurarsi che sia attivo si può lanciare il comando phpinfo(), come nell'immagine:

Se non dovesse essere presente la sezione Soap occorre abilitarla agendo sul file di configurazione php.ini sul server.
Individuare la riga contente questo codice:

; extension=php_soap.dll

Rimuovere il punto e virgola (;) di commento presente a inizio riga.
Infine riavviare Apache e controllare nuovamente da phpinfo.

Questo è il codice necessario per consumare il WS:

<?php 
	$wsdl = "http://www.dev-oclock.com/srb_service.asmx?wsdl";
	$client = new SoapClient($wsdl);
	$params->num1 = '32';
	$params->num2 = '81';
	$result = $client->Somma($params);
	echo " Risultato: " . $result->SommaResult;
?>

In php si può usare la classe SoapClient, alla quale si passa l'indirizzo del Web Service. Si ha quindi a disposizione il metodo Somma definito nel Web Service, a cui bisogna dare in pasto un array contenente i vari parametri richiesti.
Il risultato viene reso disponibile nella proprietà chiamata SommaResult. Notare che questo nome viene generato automaticamente aggiungendo "Result" al nome del metodo.

Considerazioni

L'esempio mostrato in questo articolo ovviamente non ha alcuna utilità nel mondo reale, ma penso che dimostri il potenziale offerto dai Web Services. Anziché una semplice funzione di somma, si potrebbe creare un metodo che legge i dati da un data base e fornisce informazioni su libri, meteo, quotazioni di mercato, ecc. Il sito che effettua l'interrogazione potrà presentare i dati secondo lo stile e la formattazione delle proprie pagine.

Autore: Sergio Roberto Boarina