Con SQL Server Integration Services è possibile utilizzare un
particolare task, chiamato Web service Task, utilizzato proprio per
invocare Web services. E' il seguente:

Prendiamo un semplicissimo scenario, il web service di default che
Visual Studio 2005 ci propone quando creiamo un progetto Web Service.
Il classico Hello World.
L'utilizzo del task è molto semplice. Gli step da seguire per poter usufruire delle sue funzionalità sono i seguenti:
- Creare un connection Manager di tipo HTTP

Nell'esempio ho impostato semplicemente il link http al mio WSDL di prova, ma come potete notare ci sono altre impostazioni molto importanti da poter utilizzare.
Ad
esempio è possibile fornire username, password e dominio di accesso,
impostare un certificato, definire il timeout, la dimensione del blocco
per la scrittura dei dati e testare la connessione.
In alto vi è anche la clip dedicata alle impostazioni di un eventuale proxy.
Siccome
questa connessione HTTP è stata appositamente creata per un web service
task e siccome avrò bisogno di conoscere la struttura del servizio, e
quindi un WSDL, l'url di riferimento comprende il parametro ?WSDL. Chiamiamolo Servizio
- Creare una variabile che conterrà la risposta (o un connection manager File per scrivere la risposta su filesystem)
E' possibile ad esempio creare una variabile di tipo stringa che conterrà la risposta del nostro servizio.

- Creare nella cartella del nostro progetto o su di una posizione nel disco ben definita un file vuoto con estensione .wsdl

- Impostare il Web Service Task come segue:
Fare doppio click sul Web service Task.
Come prima cosa selezionare la http connection che abbiamo creato pocanzi e poi definire nella proprietà WSDLFile il percorso ove il file .wsdl è stato creato.
La terza proprietà, OverwriteWSDLFile, indica se si vuole sovrascrivere il file alla pressione del tasto sottostante, il Download WSDL.
La
prima volta, ed ogni volta che la struttura del servizio cambia (e
quindi ogni volta che si vuole scaricare il nuovo WSDL) lasciare questa
proprietà impostata a True.
A questo punto, premere il tasto Download WSDL e attendere il messaggio di conferma:

Se la proprietà OverwriteWSDLFile è a False, viene restituito un messaggio di errore.
Facoltativamente,
potete andare a controllare sul disco e noterete che il file scaricato
è effettivamente il WSDL del servizio che dobbiamo invocare.
- Definire la sezione Input
Spostarsi sulla sezione input. Scegliere il servizio (proprietà Service) ed il metodo da eseguire (proprietà Method).
Nel caso in cui il metodo abbia parametri, comparirà un'apposita
sezione al di sotto della selezione della chiamata. Qui di seguito un
esempio di chiamata con un parametro stringa (metodo Message), mentre
quello al precedente punto non ne ha alcuno:

Attenzione,
perchè per i tipi che non sono considerati primitivi, come possono
esserlo interi e stringhe, SSIS non è in grado di fornire il passaggio
di parametri. Ad esempio, un metodo definito come il seguente, non
restituirà a SSIS nessuna richiesta di parametri input:
<WebMethod()> _
Public Function
NumeroRighe(ByVal ds As
DataSet) As Integer
Return
ds.Tables(0).Rows.Count
End Function
- Definire la sezione OutputDopo
aver configurato l'input, definiamo l'output selezionando il tipo di
container della risposta, File o Variabile. Qui di seguito l'esempio su
variabile, dichiarata all'inizio del post:

Eseguendo
un ipotetico SSIS che lancia il web service suddetto e che in seguito
visualizza il valore della risposta avremo questo comportamento:

Dopo
aver introdotto il task, vorrei soffermarmi su alcuni ostacoli che
potremmo incontrare nell'usarlo. E vorrei anche giustificare il titolo
del post

.
Oltre a non poter passare parametri di un certo tipo (da MSDN: "
The Web Service task supports parameters of the following data types
only: primitive types such as integers and strings; arrays and
sequences of primitive types; and enumerations."),
vi è da ricordare che tutte le risposte del web service task sono
stringhe. Ognuna di esse è la serializzazione del valore/oggetto di
ritorno. Quindi ogni stringa contiene l'XML della risposta
serializzata. Questo perchè il task non si pone di creare una classe
proxy come ad esempio Visual Studio fa quando aggiungiamo una Web
Reference.
Abbiamo la possibilità di salvare la stringa su un file
xml, è vero, ma se volessimo utilizzare la risposta tipizzandola e
castandola in un nostro oggetto all'interno di un package, dovremmo per
forza ricorrere alla deserializzazione. E quindi scrivere codice.
Di conseguenza, molto spesso non utilizzo il web service task ma direttamente lo script task, in un modo un po' particolare.
Tramite il tool WSDL.exe usato anche da Visual studio per scrivere la classe proxy dal wsdl, genero la classe proxy.

Aggiungo
uno script task e includo al suo interno la classe generata con
wsdl.exe (con SSIS 2005 solo VB). Inoltre aggiungo il riferimento a
System.Web.Services e
System.Xml.

Nello
ScriptMain possiamo istanziare il manager del servizio (la nostra
classe proxy) per eseguire i metodi da codice. Ricordiamo il metodo
d'esempio:
<WebMethod()> _
Public Function
NumeroRighe(ByVal ds As
DataSet) As Integer
Return
ds.Tables(0).Rows.Count
End Function
Ecco come nello Script eseguo la chiamata:
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Public Class ScriptMain
Public Sub Main()
' istanzio il web service
Dim objWS As New Service1()
' creo una tabella con una riga
Dim objdt As New DataTable()
objdt.Columns.Add("col1", GetType(System.String))
Dim objdr As DataRow
= objdt.NewRow()
objdr("col1") = "PROVA"
objdt.Rows.Add(objdr)
' popolo il dataset
Dim objDs As New DataSet
objDs.Tables.Add(objdt)
' chiamo il metodo che mi torna il numero di righe della tabella del
dataset
Dim i As Integer =
objWS.NumeroRighe(objDs)
' ...
Dts.TaskResult = Dts.Results.Success
End Sub
End Class
Con questo metodo possiamo muoverci con maggiore libertà sui tipi del
framework ed anche su quelli definiti da noi. Esiste comunque un
rovescio della medaglia, ed è quello relativo alla manutenzione del
codice. Cambiando la struttura del web service, è necessario replicare
la nuova classe proxy anche negli script che la utilizzano.
ATTENZIONEVi è una soluzione più
corretta, ovvero
creare una dll strongly signed e metterla in GAC,
in modo tale da poter aggiungere il riferimento così come per le altre
classi .NET. Quest'ultima è sicuramente la soluzione più pulita, se non
vogliamo utilizzare il task di SSIS. Ad ogni modo, il riferimento deve
essere aggiunto a livello di Script poichè non è possiible referenziare
una DLL a livello globale.
Comunque lascio la firma e la creazione dell'assembly in GAC a Voi.. ecco un link utile per capire meglio come firmare la dll
http://msdn2.microsoft.com/en-us/library/ms247123.aspx
Stay tuned!