Вы находитесь на странице: 1из 68

��������������������������������������������������������������������������������������������������������������������������������������

����������������������
�������������������������������������������������
�������������������������������������������������������������������
������������������������������������������������������������������
����������������������������������������������������������������������������
����������������������������������������������������������������������
���������������������������������������������������
�������������������������������
������������������������������������������������������������������
���������������������������������������������������������������������
���� ��������
��������
�������������������������
�� �����������������������������������������������������������������������������������
������������������������������������������������������������������������������������
�����������������������������
�����������������

���
���������������������������������������������
�� �������������������������������������������������������������������������������������
���������������������������������������������������������������������������������������
����������������
������������������

����������
���������������������������
�� ����������������������������������������������������������������������������������
������������������������������������������������������������������������������������
��������������������������������������������������������������������������������������
������������
����������������������

���
������������������������������������������������������������
�� ����������������������������������������������������������������������������������������
������������������������
�����������������������������������������

������
����������������������������������������
�� ��������������������������������������������������������������������������������������
����������������
������������������

��������������� ��������
������������������������������������������������������������������������������������ � ����������
��������������������������������������������������������������������������������������
������������������������������������������������������������������������������������������� �� ����������
������������������������������������������������������������������� �� �������������

����������������������������������� �
�������������������
������������������������������
����������������������������

��������������������������
��������������������������������������

��������������������
���� ������� ������
�����������������������������������������
����������������
�������������������������������
�������������������������
�������������
���������������
������������������
�������������������������
�������������������


��������������� ������������������������������������������������������������
�������������
�������������� ����������������������������������������������������������
��������������� �����������������������������������������������������������
�����������������������������������������������������������������������
�������������������������������������������������������������
������������������������������������������������������������
���������������������������������������������������������������
�������������������������������������������������������������������
����������������������������������������������������������������
��������������������������������������������������������������������
���������������������������������������������������������������
��������������������������������������������������������������������������������������
���������� �����������������������������������������������������������������������
�������������������������������� �������������������������������������������������������������������������������������������������
������������������������� ���������������������������������������������������������������������������������������������
����������������������� �����������������������������������������������������������������������������������
����������������������� ���������������������������������������������������������������������
��������������� �����������������������������������������������������������������������������������
����������� ������������������������������������������������������������������������������������
������������������������������ ��������������������������������������������������������������������������������������
������� ����������������������������������������������������������������������������������������
���������������������������������� �����������������������������������������������������������������
�������������� �����������������������������������������������������������������������������������
������������������������������ ������������������������������������������������������������������������������������
����������������������������������������������������������������������������������������
����������� �����������������������������������������������������������������������������������������
�������������
������������������� �������������������������������������������������������������������������������������
�����������������������������������������������������������������������������������
��������������������������������������������������������������������������������������
������ �������������������������������������������������������������������������������������������
������������������������ ���������������������������������������������������������������������������������������
���������������������� ������������������������������������������������������������������������������������������
��������������������������������������������������������������������������������������
������������������� ���������������������������������������������������������������������������������������
���������������������������������� �������������������������������������������������������������������������������������
���������������������������������
���������������� �����������������������
������������������������������������������������������������������������������������
������������������������������� ����������������������������������������������������������������������������������
������������������������������������������������
����������������������������������
������������������������������������������������������������������������������������
�������������������� ������������������������������������������������������������������������������������������������
������������������������� �����������������������������������������������������������������������������������

��������������������������������������������������������� ����������������
����������������������������������������������������
������������������������������������ ��������������������������
����������������������������������������������������������������
���������������������������������������������������������
�������������������������������������
�������������������������������������������������������������������������
�����������������������������������������������������
����������������������������������� �
I N O F F E R TA V B J 7 1
Scrivi a
ASP.NET 2.0 Cookbook, ASP.NET 2.0
Second Edition book@infomedia.it Illustrated
di M.A. Kittel, specificando di A. Homer,
G.T. LeBlond D. Sussman
nell’oggetto della
O’ Reilly
e-mail: Addison Wesley
ISBN 0596100647
1014 pp, euro 54,95
IN OFFERTA ISBN 0321418344
800 pp, euro 48,95
VBJ n. 71
OPPURE
inviaci il coupon
ASP.NET 2.0 How to Break
Unleashed sottostante Web Software
di S.Walther al numero di fax di M.Andrews,
J.Whittaker
0587/732232
Addison Wesley
Sams Potrai acquistare ISBN 0321369440
ISBN 0672328232 240 pp, euro 30,95
1992 pp, euro 52,95
i libri qui riportati con
uno
SCONTO
Web Services Platform
ECCEZIONALE Core Security Patterns
del 10% anche se
Architecture di C. Steel, R. Nagappan
AA.VV
acquisti solo un
libro
Prentice Hall Prentice Hall
ISBN 0131488740 OPPURE ISBN 0131463071
456 pp, euro 46,95 1088 pp, euro 52,95
del 20% se acquisti
3 libri

VBJ 68
SPECIALE

La paginazione
dei record
La paginazione dei dati è un problema che da sempre si pre-
senta nelle applicazioni moderne, in particolare con interfac-
cia web. Esaminiamo le tecniche più diffuse per rispondere a
questa esigenza Paginazione

di Paolo Pialorsi (www.devleap.com)

D
a anni esiste un problema che assilla gli gono personalizzati possono
sviluppatori di applicazioni web e non restituire tanto 10 quanto
solo: la paginazione dei record. 10.000 record."
Tutte le volte che si parla di questo argomento Pensiamo a un caso sicura-
c’è chi storce il naso e sostiene che è un falso mente noto a tutti: un moto-
problema. Probabilmente il più delle volte ha re di ricerca su Internet. Se
ragione! Spesso infatti abbiamo l’esigenza di cerchiamo <<“XML Schema
paginare i record perché non abbiamo fornito Definition” XAML>> otterre-
ai nostri utenti gli strumenti adatti o non siamo mo un certo risultato (ad oggi
stati abbastanza convincenti, per far capire loro 1.880 righe su Google), se in-
che ottenere una lista di 850.000 record da pagi- vece cerchiamo “XML” ne ot-
nare 20 alla volta non serve poi un granché... o terremo un altro (929.000.000
no? In questo senso spesso si dice che paginare righe, sempre su Google).
migliaia di record non è un problema da risolve- Il risultato sarà diverso sia
re ma è un problema da evitare. in termini di qualità che di
D’altra parte sappiamo però che non sempre si quantità. Eppure i motori di
può realizzare tutto come si vorrebbe. A volte ricerca ci forniscono una lista
gli utenti dobbiamo accontentarli, soprattutto se paginata e maledettamente
sono clienti o responsabili d’ufficio che ci pagano veloce da sfogliare!
in proporzione a quanto li rendiamo contenti... Il problema principale, per
Inoltre, molto spesso forniamo agli utenti degli una tipica applicazione di
strumenti di consultazione dei dati che sono consultazione dati, è fornire
personalizzabili e che in funzione di come ven- una lista che sia anche ordi-
nabile e ricercabile secondo
dei filtri che sono definibili
liberamente dall’utente fina-
Paolo Pialorsi è un consulente e autore specializzato nello
sviluppo di servizi SOA e soluzioni in architettura distribuita le dell’applicazione. È infatti
basate sul Framework .NET di Microsoft. Lavora nell’omonima relativamente facile restituire
società Pialorsi Sistemi S.r.l. e fa parte del gruppo DevLeap. Può una lista di record, ordinati
essere contattato via email: paolo@devleap.it. Mantiene il blog
secondo un preciso criterio,
personale all’indirizzo http://blogs.devleap.com/paolo/
che non cambierà mai, con-

N. 71 - Settembre/Ottobre 2006 VBJ 11


SPECIALE

sentendo all’utente di spostarsi solo avanti e confrontandomi con il resto del gruppo
o indietro di una pagina per volta, rispetto DevLeap ho deciso di provare a ricondurre
alla pagina correntemente visualizzata. Un il problema a una serie di casi.
altro discorso è fornire una lista filtrata e Ho preso come esempio un’applicazione
ordinata a piacere, paginandola in modo web, utilizzando quasi sempre una griglia
casuale con una finestra di N (di solito 10 o ASP.NET, perché è comoda e perché è
20) pagine per volta, ciascuna con 20/30/50 quella che 9 sviluppatori su 10 utilizzano
record. – magari abusandone – se devono fornire
una lista paginata, ordinabile e filtrabile in
Le possibili soluzioni un’applicazione Intranet/Internet, utiliz-
Esistono diverse possibili soluzioni a que- zando un database demo con una tabella di
sto problema, tutte che possono andare 1 milione di record così strutturata:
bene, ma a seconda dell’obiettivo da rag-
giungere. Questo significa che non esiste T-SQL
la soluzione, ma esistono delle soluzioni
possibili. Sta a noi e alla nostra competen- CREATE TABLE [dbo].[tabCustomers] (
za di analisti e non solo di programmatori [idCustomer] [int] INDENTITY(1,1) ,
capire quando applicare quale soluzione. [CustomerName] [varchar] (30) NOT NULL ,
L’obiettivo sarà sempre e comunque quello [CustomerEMail] [varchar] (50) NOT NULL ,
di fornire ai nostri utenti la possibilità di [CustomerBirthday] [datetime] NOT NULL,
elencare dei record, eventualmente filtrati [CustomerSex] [bit] NOT NULL ,
e/o ordinati a piacere (entro certi limiti di fil- [SysTimestamp] [timestamp] NOT NULL
tro e ordinamento dettati dal buon senso). ) ON [PRIMARY]
Partendo quindi da queste considerazioni, GO

Tecnica Pro Contro


Paginazione con Richiede poco sforzo Al crescere del numero di
DataAdapter pagina, cresce il costo. Non è
una soluzione ottimale perché
“spreca” tutti i record prima di
quelli della pagina corrente
Cursore Server-Side Consuma solo i record Richiede un cursore lato server
necessari
Tabella temporanea Non richiede cursori La tabella temporanea
determina la ricompilazione
del piano di esecuzione della
stored procedure
Paginazione custom Ottimi risultati, anche con Richiede impegno per la
con colonna dinamica alto numero di record codifica della stored procedure
Paginazione SQL Ottimi risultati, anche con Richiede SQL Server 2005
Server 2005 con CTE alto numero di record
e ROW_NUMBER()

Tabella 1 Riepilogo delle tecniche esaminate

12 VBJ N. 71 - Settembre/Ottobre 2006


SPECIALE

tato e non tutti gli statement SQL delle


ALTER TABLE [dbo].[tabCustomers] WITH NOCHECK ADD stored procedure. Questi ultimi saranno
CONSTRAINT [PK_tabCustomers] PRIMARY KEY CLUSTERED disponibili nel codice allegato all’articolo,
( che contiene gli script SQL completi di
[idCustomer] tutti gli esempi.
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tabCustomers] ADD La paginazione dei record è
CONSTRAINT [DF_tabCustomers_CustomerSex] DEFAULT (0) spesso un falso problema
FOR [CustomerSex]
GO

Come si vede ho creato una PrimaryKey


con un indice clustered (cioè che defini-
sce l’ordinamento dei record nella tabella) Non dimentichiamoci la sicurezza!
sulla colonna idCustomer, definita come Tutte le soluzioni proposte prevedono che
INDENTITY (ho cercato di riprodurre un le applicazioni che ne fanno uso siano pro-
caso abbastanza tipico). gettate e sviluppate senza trascurare gli
Con uno script banale ho popolato la tabel- aspetti e i problemi legati alla sicurezza.
la con 1 milione di record e ho predisposto Alcune delle stored procedure proposte,
le varie soluzioni e le ho eseguite, visualiz- se alimentate con parametri “grezzi” non
zando diverse pagine, con diversi filtri e controllati e filtrati con regular expression
ordinamenti. o soluzioni analoghe, potrebbero dare adito
In tutti i casi focalizziamoci sul codice a problemi di SQL Injection.
SQL e non sul codice ASP.NET, che è solo Questo è un articolo che concentra la sua
un dettaglio applicativo. Paginare una gri- attenzione sugli statement SQL e sulle
glia ASP.NET non c’entra con i criteri di tecniche di paginazione, non sull’archi-
paginazione sul DB e si possono trovare tettura di un’intera applicazione, quindi
centinaia di articoli e libri che spiegano non avremmo tutti gli elementi necessari
come farlo in modo più o meno automa- a svolgere delle valutazioni serie sul conte-
tico. In tutti i casi costruiamo dinami- sto di sicurezza del codice proposto. Prima
camente, all’interno di apposite stored quindi di utilizzare le soluzioni proposte
procedure, lo statement SQL di selezione occorre un’attenta valutazione dei rischi e
delle righe, in funzione dei criteri di filtro delle problematiche di security, contestua-
e ordinamento scelti dall’utente, quindi lizzandone l’uso.
invochiamo la stored procedure di siste-
ma sp_executesql per ottenere il risultato. Paginazione con DataAdapter
Alla prima richiesta avremo prestazioni Il DataAdapter di ADO.NET ci fornisce la
modeste, ma dalla seconda potremo sfrut- possibilità di popolare un DataSet indi-
tare il caching del piano di esecuzione del- cando da quale record vogliamo iniziare e
la query costruita dinamicamente, quindi, per quanti record ci vogliamo spostare in
per ricerche uguali in termini di filtro, avanti.
avremo probabilmente già in cache i loro
piani di esecuzione. C#
In Tabella 1 c’è un breve riepilogo delle
tecniche valutate, alcune delle quali an- da.Fill(ds, gridCustomers.PageSize * gridCustomers.
dremo a sviluppare di seguito. Curren tPageIndex,
Nell’articolo analizzeremo le query risul- gridCustomers.PageSize, “tabCustomers”);

N. 71 - Settembre/Ottobre 2006 VBJ 13


SPECIALE

Sappiamo che il DataAdapter internamen- Paginazione con cursore lato server


te utilizza un DataReader per riempire il Un’altra possibile soluzione da valutare è
DataSet. Ecco che allora risulta immediato quella di utilizzare un cursore lato server,
capire come si comporti in questo caso: che ci consenta di posizionare il server e
scorre in modalità forward-only e read- non più il client sulla pagina corretta, per
only il DataReader e quando arriva al pri- poi caricare la rete dei soli record di no-
mo record utile del resultset inizia a riem- stro interesse. Se non dovessimo fornire
pire la DataTable di destinazione; quando al nostro utente la possibilità di filtrare e
sono stati raggiunti gli N record di pagina, ordinare liberamente i record, basterebbe
annulla la parte restante della richiesta. definire un cursore “classico” con DECLA-
Questa soluzione non risparmia per nulla RE ... CURSOR FOR e farne la FETCH per
la rete e il Server SQL, in particolare se spostarci sui record di nostro interesse.
richiediamo numeri di pagina alti. Quin- Qualcosa come:
di è applicabile su resultset di modeste
dimensioni o comunque su pagine basse. T-SQL
Sicuramente è preferibile al caso della pa-
ginazione automatica operata dai controlli -- Cursore per scorrere i record di tabCustomers
ASP.NET. Dal punto di vista del codice DECLARE curCustomers SCROLL CURSOR FOR
SQL non dobbiamo fare nulla, perché tutto SELECT idCustomer, CustomerName, CustomerEMail, Customer-
il lavoro sarà a carico del DataAdapter. La Birthday, CustomerSex
nostra stored procedure di selezione dei FROM tabCustomers FOR READ ONLY
record fornirà comunque tutti i record:
-- Apro il cursore
T-SQL OPEN curCustomers

CREATE PROCEDURE spListCustomersForDataAdapterPaging -- Mi sposto sul primo record della pagina


( DECLARE @FirstRecordPosition int
@CustomerName varchar(30) = ‘’, SET @FirstRecordPosition = (@PageSize * (@CurrentPage
@CustomerEMail varchar(50) = ‘’, - 1)) + 1
@CustomerBirthDayStart datetime = NULL, FETCH ABSOLUTE @FirstRecordPosition FROM curCustomers
@CustomerBirthDayEnd datetime = NULL,
@CustomerSex bit = NULL, -- Ottengo i record della pagina richiesta
@SortExpression nvarchar(100) = NULL, DECLARE @CurrentPosition int
@RecordCount int OUTPUT SET @CurrentPosition = 1
) WHILE ((@@FETCH_STATUS = 0) AND (@CurrentPosition < @Pa-
AS geSize))
BEGIN
-- Non devo fare altro che richiamare la spListCusto- SET @CurrentPosition = @CurrentPosition + 1
mersForAutoPaging aggiungendo il numero di record che ho FETCH NEXT FROM curCustomers
ottenuto END
EXEC spListCustomersForAutoPaging @CustomerName, @Custo-
merEMail, @CustomerBirthDayStart, @CustomerBirthDayEnd, -- Rilascio le risorse allocate
@CustomerSex, @SortExpression CLOSE curCustomers
DEALLOCATE curCustomers
SET @RecordCount = @@ROWCOUNT
GO SELECT @RecordCount = Count(*) FROM tabCustomers
GO

14 VBJ N. 71 - Settembre/Ottobre 2006


SPECIALE

re sulla base di uno statement SQL da noi


Il problema è che a noi serve poter definire definibile dinamicamente (proprio quello
dinamicamente l’oggetto della SELECT su che ci serve!). Il risultato della sp_curso-
cui aprire il cursore. Osservando come si ropen è l’ID del cursore, con il quale pos-
comporta il buon vecchio Recordset ADO- siamo chiedere a sp_cursorfetch di darci N
DB possiamo però vedere che esistono record (per noi @PageSize) partendo da un
delle extended stored procedure di siste- certo record (@FirstRecordPosition). Dob-
ma come sp_cursoropen, sp_cursorfetch biamo poi ricordarci di chiudere il cursore
e sp_cursorclose. Usate opportunamente con sp_cursorclose.
(al di là, per un attimo, delle valutazioni Bene! Dobbiamo essere consapevoli del
filosofiche sull’opportunità di farne uso) fatto che non stiamo facendo una bella
possiamo definire una stored procedure cosa! Però funziona, potrebbe dire qual-
come la seguente: cuno. Sì, funziona, ma non è particolar-
mente performante. Sicuramente non
T-SQL carica l’applicazione web ASP.NET o lo
strato business che ne fa uso. Carica de-
CREATE PROCEDURE spListCustomersServerSideCursor cisamente di più il server SQL. Non cari-
( ca per nulla la rete, visto che passeranno
solo N record, dove N sarà pari a @Page-
[ ... omissis: filtri e ordinamenti ...] Size, e il numero complessivo dei record
che corrispondono al criterio di ricerca
-- Stabilisco qual è il primo record della pagina impostato, per gestire la generazione dei
DECLARE @FirstRecordPosition int numeri di pagina.
SET @FirstRecordPosition = (@PageSize * (@CurrentPage
- 1)) + 1

-- Dichiaro e uso il cursore dinamico


Non esiste una soluzione,
DECLARE @CursorID int ma esistono delle soluzioni
DECLARE @ScrollOpt int
tra cui scegliere
DECLARE @CCOpt int
DECLARE @RowCount int
SET @ScrollOpt = 4
SET @CCOpt = 1
SET @RowCount = -1 Paginazione con tabella temporanea
EXEC sp_cursoropen @CursorID OUT, @SqlStatement, @Scrol- Proviamo allora a evitare di utilizzare cur-
lOpt output, sori lato server, senza rinunciare a lasciare
@CCOpt output, @RowCount output scarico il client e la rete. Possiamo intanto
EXEC sp_cursorfetch @CursorID ,32, @FirstRecordPosition, pensare che se lavoriamo con gli indici
@PageSize giusti e non dobbiamo cambiare l’ordina-
EXEC sp_cursorclose @CursorID mento predefinito dei record nella tabella,
una buona soluzione è quella che prevede
SET @SqlStatement = ‘SELECT @RC = Count(*) FROM tabCusto- proprio di ragionare in base alla colonna
mers’ + @SqlCondition chiave primaria e indice clustered della
EXEC sp_executesql @SqlStatement, N’@RC int OUTPUT’, @RC- tabella.
= @RecordCount OUTPUT Come posso identificare gli N record della
GO pagina X ragionando sulla base della Pri-
maryKey? Ecco un esempio pratico, men-
Come si vede sp_cursoropen apre un curso- tre negli allegati all’articolo è disponibile la

N. 71 - Settembre/Ottobre 2006 VBJ 15


SPECIALE

stored procedure che genera questa query record per pagina della tabella reale (par-
dinamicamente: liamo di operazioni di I/O, i risultati sono
visibili già a occhio nudo su tabelle con
T-SQL decine di migliaia di record, in assenza di
cache).
SELECT TOP 20 idCustomer, CustomerName, CustomerEMail,
CustomerBirthday,
CustomerSex FROM tabCustomers WHERE idCustomer >
(SELECT Max(idCustomer) FROM tabCustomers WHERE
idCustomer IN (SELECT TOP 862900 idCustomer FROM tabCu-
I problemi derivano dall’esi-
stomers)) genza di filtrare e ordinare i
Con SQL Server 2005 potremmo anche
dati in modo personalizzato
eseguire una SELECT TOP @Parametro. per l’utente
Si tratta di una soluzione normalmente
adeguata, in quanto sfruttiamo l’ordina-
mento fornito dall’indice clustered senza
ulteriori overhead. Se non dobbiamo Spostiamo il problema al caso in cui vo-
permettere ai nostri utenti di cambiare gliamo scegliere anche il criterio di ordi-
ordinamento direi che è la soluzione da namento. Lo statement SQL dovrà essere
preferire, perché carica poco sia SQL, sia modificato in modo tale da confrontare i
la rete, sia il client. record ordinati secondo il criterio scelto
Se però la dimensione in byte di una riga dall’utente e non dall’indice clustered.
è voluminosa, non è detto che la soluzio- Ecco che una possibile soluzione è quella
ne basata sull’indice clustered sia la più di utilizzare una tabella temporanea in cui
efficiente: in presenza di record con una o andremo a inserire solo la chiave primaria
più colonne di tipo testuale molto lunghe, di ciascun record, nell’ordine scelto dal-
potrebbe risultare più performante creare l’utente, e nella quale definiremo una no-
l’indice sulla chiave primaria in modalità stra chiave di servizio, con tanto di indice
NONCLUSTERED, senza alcun indice clustered, che ci permetterà di riapplicare
CLUSTERED; tale configurazione può il concetto visto nel caso precedente. Ecco
risultare molto più performante della pre- il codice SQL:
cedente in caso di query completamente
coperte dall’indice (situazione in cui SQL T-SQL
Server legge solo l’indice senza accedere
alle pagine che contengono i dati della ta- CREATE PROCEDURE spListCustomersTempTable
bella vera e propria). Purtroppo è difficile (
stabilire a priori quale sia la soluzione più [ ... omissis ...]
performante, fondamentalmente ci sono
molte variabili in gioco e la cosa migliore -- Definisco una tabella temporanea di appoggio
è provare le due varianti e fare dei bench- CREATE TABLE #tmpCustomers
mark specifici. Certamente in casi estre- (
mi, per esempio una riga con dimensione idRecord int IDENTITY(1,1) PRIMARY KEY CLUSTERED,
effettiva di circa 1.000 byte, può essere idCustomer int
estremamente conveniente avere un indi- )
ce NONCLUSTERED che risolve la query,
perché questo significa leggere circa 2.000 [ ... omissis ...]
record per pagina sull’indice, contro gli 8

16 VBJ N. 71 - Settembre/Ottobre 2006


SPECIALE

-- Costruisco lo statement che popola la tabella tempo-


ranea -- Elimino la tabella temporanea
SET @SqlStatement = ‘INSERT INTO #tmpCustomers (idCu- DROP TABLE #tmpCustomers
stomer) SELECT TOP ‘ + CONVERT(nvarchar, (@PageSize *
@CurrentPage)) + ‘ idCustomer FROM tabCustomers’ -- Conto quanti sono i record che corrispondo al criterio
di filtro impostato dall’utente (per il VirtualI-
[ ... omissis: filtri e ordinamenti ...] temCount)
SET @SqlStatement = ‘SELECT @RC = Count(*) FROM tabCust-
-- Riempio la tabella temporanea di appoggio omers’ + @SqlCondition
EXEC sp_executesql @sqlStatement EXEC sp_executesql @SqlStatement, N’@RC int OUTPUT’, @RC
= @RecordCount OUTPUT
-- Preparo lo statement di SELECT dei dati per fornire il
vero risultato all’utente GO
SET @SqlStatement = ‘SELECT idCustomer, CustomerName,
CustomerEMail, Come si vede non cambia molto rispetto a
CustomerBirthday, CustomerSex FROM tabCustomers WHERE prima. Solo che stiamo chiedendo di ese-
idCustomer IN (SELECT TOP ‘ + CONVERT(nvarchar, @PageSi- guire:
ze) + ‘ idCustomer FROM #tmpCustomers ‘
T-SQL
IF (@CurrentPage > 1)
SET @SqlStatement = @SqlStatement + SELECT idCustomer, CustomerPosition, CustomerName, Custo-
‘ WHERE idRecord > (SELECT Max(idRecord) FROM #tmpCu- merEMail,
stomers WHERE idRecord CustomerBirthday, CustomerSex FROM tabCustomers WHERE
IN (SELECT TOP ‘ + CONVERT(nvarchar, (@PageSize * idCustomer IN
(@CurrentPage - 1))) + (SELECT TOP 20 idCustomer FROM #tmpCustomers WHERE
‘ idRecord FROM #tmpCustomers))’ idRecord >
(SELECT Max(idRecord) FROM #tmpCustomers WHERE idRecord
SET @SqlStatement = @SqlStatement + ‘)’ IN
(SELECT TOP 862900 idRecord FROM #tmpCustomers)))
-- Eseguo lo statement di SELECT
EXEC sp_executesql @sqlStatement Questa soluzione paga solo se definiamo

ComInterfaceType
Indica che l’interfaccia esposta a COM è un’interfaccia duale, che
InterfaceIsDual consente sia l’associazione anticipata sia l’associazione tardiva.
InterfaceIsDual è il valore di default.

Indica che l’interfaccia esposta a COM è un’ interfaccia dispatch che


InterfaceIsDispatch consente solo l’associazione tardiva.

Indica che l’interfaccia esposta a COM è un’ interfaccia derivata dal-


InterfaceIsIUnknown la IUnknown che consente solo l’associazione anticipata.

Tabella 2

N. 71 - Settembre/Ottobre 2006 VBJ 17


SPECIALE

degli opportuni indici sulla tabella, al- CustomerEMail, 20) + CONVERT(nvarchar(10), idCustomer))
trimenti rischiamo di dover attendere il IN (SELECT TOP 220 (CONVERT(nvarchar(100), CustomerEMail,
risultato per diversi secondi. Inoltre ha 20) + CONVERT(nvarchar(10), idCustomer)) AS CustomKey
senso applicarla solo quando le pagine FROM vwListCustomersByEmail ORDER BY CustomKey) ORDER BY
sulle quali ci si sta muovendo sono di CustomKey) ORDER BY CustomKey
numero basso. Infatti più si sale, più cre-
sce la quantità di record da copiare nella In questa soluzione conviene fare atten-
tabella temporanea (ricordatevi di non zione alle colonne di tipo datetime, che
fare una INSERT INTO sempre di tutti i per default nel cast su nvarchar forniscono
record, ma solo di quelli minori o uguali un valore testuale che rende difficile ordi-
a quelli della pagina richiesta dall’utente), nare correttamente i dati. In questo caso
penalizzando quindi in modo lineare le il valore del parametro @SortExpression
prestazioni della query e il carico di lavo- dovrà essere opportunamente modificato
ro per il server SQL. Il client e la rete non per contenere la lista di colonne di ordina-
sono assolutamente penalizzati da queste mento concatenate e non separate da una
soluzioni. virgola.
Per il resto eseguiamo una query abba-
Paginazione con colonna dinamica stanza simile a quella del caso precedente,
L’uso delle tabelle temporanee è mal sop- solo che la chiave con la quale eseguiamo
portato da molti, seppur a volte utile. E il confronto non è più la Primary Key della
se provassimo a fondere l’idea del filtro tabella temporanea, ma la colonna dinami-
basato sulla chiave primaria e dell’or- ca generata nella query.
dinamento personalizzabile? Possiamo È assolutamente opportuno definire degli
inserire nella SELECT una colonna ge- indici sulla tabella che comprendano le
nerata dinamicamente in funzione del possibili combinazioni di ordinamento
criterio di ordinamento scelto dall’utente (@SortExpression) sempre seguite da
e costruita concatenando la condizione idCustomer, altrimenti rischiamo di avere
di sorting con la colonna PrimaryKey. In comunque delle soluzioni poco efficienti.
questo modo otteniamo l’univocità della Questa soluzione si contraddistingue in
colonna dinamica generata e l’ordina- particolare per il fatto che le sue prestazio-
mento secondo le richieste dell’utente. ni sono abbastanza costanti, a prescindere
Se indicizziamo correttamente la tabella dal numero di pagina richiesta. Su pagine
possiamo avere dei buoni risultati in ter- di numero basso è più costosa della solu-
mini di prestazioni. Vediamo la query ri- zione basata su tabella temporanea, ma
sultante nel caso di ordinamento in base salendo il numero di pagina le prestazioni
al CustomerEMail: rimangono abbastanza uniformi. Come nel
caso della tabella temporanea, sia la rete
T-SQL che il client non sono per nulla sovraccari-
cati di lavoro.
SELECT TOP 20 idCustomer, CustomerName, CustomerEMail,
CustomerBirthday, CustomerSex, (CONVERT(nvarchar(100), Paginazione con le CTE di SQL
CustomerEMail, 20) + CONVERT(nvarchar(10), idCusto- Server 2005
mer)) AS CustomKey FROM vwListCustomersByEmail WHE- In SQL Server 2005 troviamo alcuni nuovi
RE (CONVERT(nvarchar(100), CustomerEMail, 20) + strumenti come le Common Table Expres-
CONVERT(nvarchar(10), idCustomer)) > (SELECT TOP sion (CTE) e la funzione ROW_NUMBER().
1 Max((CONVERT(nvarchar(100), CustomerEMail, 20) + Ecco che allora sfruttando entrambi questi
CONVERT(nvarchar(10), idCustomer))) AS CustomKey FROM strumenti possiamo definire delle query
vwListCustomersByEmail WHERE (CONVERT(nvarchar(100), come la seguente:

18 VBJ N. 71 - Settembre/Ottobre 2006


SPECIALE

La CTE viene poi utilizzata per selezionare


T-SQL le sole righe di interesse della nostra pagi-
na.
WITH CustomersNumbered AS ( Si tratta di una tecnica con una buona ef-
SELECT ficienza; come sempre è importante ricor-
ROW_NUMBER() OVER (ORDER BY CustomerEMail) AS RowNumber, darsi di indicizzare correttamente le tabel-
idCustomer, CustomerName, CustomerEMail, CustomerBir- le per non pagare il prezzo di numerosi I/O
thday, CustomerSex in fase di esecuzione delle nostre query.
FROM tabCustomers)
SELECT * FROM CustomersNumbered Conclusioni
WHERE RowNumber BETWEEN 221 AND 240 Penso che l’approccio migliore al problema
sia tenere presenti tutte le possibili solu-
Dove la parte WITH … AS (...) è appunto zioni e, a seconda dei casi, applicare quelle
la CTE che definisce l’elenco dei clienti più adatte, in funzione del numero di re-
ordinati per il campo CustomerEMail, cord, del tipo di filtro, della locazione del
con l’aggiunta del numero di riga, pro- client del database, della pagina richiesta e
prio in funzione di quella chiave di ordi- della sua dimensione, ecc. Come abbiamo
namento, come si vede dall’applicazione visto in principio, per questo problema non
della funzione ROW_NUMBER() con esiste la soluzione, piuttosto esistono delle
ordinamento OVER (ORDER BY Custo- soluzioni, da applicare di volta in volta, a
merEMail). seconda dei casi.

N. 71 - Settembre/Ottobre 2006 VBJ 19


WEB

Master Page,
Temi e interfacce in
ASP.NET 2.0
Le nuove funzionalità di ASP.NET 2.0 sulla gestione dell’aspetto delle pagi-
ne permettono di ottenere risultati graficamente gradevoli e consentono di
uniformare l’aspetto del nostro sito

di Massimo Bonanni

L’articolo prende in esame le nuove funziona- Le pagine Master


lità introdotte nella versione 2.0 di ASP.NET In questo paragrafo esaminia-
riguardanti la coerenza dell’aspetto di una web mo come ASP.NET 2.0 aiuta
application, cioè gli strumenti che permettono nel realizzare pagine in cui
di rendere le pagine del sito simili tra loro per la disposizione spaziale degli
disposizione degli elementi HTML e per i conte- elementi (siano essi immagi-
nuti visivi e grafici. ni, testo, plug-in o quant’altro)
è sempre la stessa.
La realizzazione di un sito web, soprattutto quei Nella versione 1.0 e 1.1 di
siti che devono avere un grande impatto per ASP.NET, un modo per rea-
l’utente finale, non prescinde dall’aspetto grafi- lizzare pagine tutte “uguali”,
co che deve proporre. consisteva nell’affidarsi agli
Lo sviluppatore lavora, generalmente, di pari user control, realizzati una
passo con il grafico per dare al sito un aspetto volta per tutte in modo da
coerente ovvero per far in modo che tutte le pa- avere l’interfaccia utente de-
gine abbiano una “impronta grafica” simile se siderata e distribuiti su tutte
non addirittura uguale. le pagine, oppure nel costrui-
ASP.NET non stravolge questo metodo di lavo- re una pagina “template” vuo-
ro, ma fornisce strumenti e classi che permet- ta ma con la struttura grafica
tono di razionalizzare lo sforzo e, soprattutto, di ben delineata e ricavare tutte
fare in modo che eventuali cambiamenti non ab- le pagine del sito dal “templa-
biano grande impatto nella manutenzione della te” ricopiandolo, rinominan-
web application. dolo e riempiendolo di oggetti
grafici.
Quali problematiche, Micro-
Massimo Bonanni è laureato in Matematica alla Sapienza di soft, ha cercato di risolvere o
Roma, si occupa di analisi e sviluppo software in ambiente di semplificare introducendo
Windows. Per diversi anni si è occupato di applicazioni in le Master Page?
ambito telecomunicazioni ed attualmente disegna e sviluppa
applicazioni web presso una software house di Roma
Innanzitutto minimizzare l’im-
patto di eventuali cambiamenti

N. 71 - Settembre/Ottobre 2006 VBJ 21


WEB

che si possono avere


nel tempo: utilizzare
gli user control, come
accadeva nelle prece-
denti versioni, signi-
fica che se qualche
oggetto costituente
uno dei controlli
deve cambiare (an-
che solo di posizione
o attributi grafici), è
necessario compilare
di nuovo il codice sor-
gente e ridistribuire
l’assembly. Inoltre,
bisogna stare atten-
ti a non cambiare
l’interfaccia (cioè i Figura 1 Esempio di ereditarietà tra pagina modello e pagine contenuto
metodi e le proprietà
pubbliche) che tali
controlli espongono, pena il probabile mal- Le pagine Master, quindi, possono essere
funzionamento degli oggetti che li utilizza- considerate come una sorta di “metapagi-
no. Infine, dovendo creare degli user control ne” con struttura del tutto simile alle nor-
si deve scrivere codice e perdere tempo nel mali pagine aspx ma estensione .master.
debug prima di rilasciarli. A livello pratico, le pagine Master fornisco-
Queste problematiche sono risolte quasi no un modello per il rendering delle pagine
del tutto o notevolmente alleviate con l’in- aspx a loro collegate: nel momento in cui si
troduzione delle Master Page. richiede una pagina, ASP.NET “fonde” la
L’idea che sta alla base della soluzione pro- pagina richiesta (detta pagina dei contenu-
posta in ASP.NET 2.0 è quella di creare la ti) con la pagina Master in un’unica pagina
pagina che fa da modello una volta per tut- e ne effettua il rendering.
te e ricavare tutte le altre da questa. Le pagine Master possono ospitare tutti i
ASP.NET è basato su un modello ad oggetti e, controlli web che possono essere inseriti in
quindi, per realizzare la soluzione è sufficien- una pagina aspx normale, ma hanno anche
te aggiungere un livello alla “catena” di eredi- la possibilità di ospitare una o più istanze
tarietà delle pagine aspx (vedi Figura 1). del controllo ContentPlaceHolder.
Purtroppo, nella versione 1.1 del fra- Il controllo ContentPlaceHolder permette
mework, interferire con la “catena” di di definire, all’interno di una pagina Ma-
ereditarietà significava, a volte, compro- ster, un’area riservata ai contenuti che sarà
mettere il progetto. riempita dai controlli della pagina aspx.
In realtà, come vedremo tra poco, la pa- A livello della pagina dei contenuti, deve es-
gina aspx che utilizza una pagina Master sere definito un controllo Content per ogni
non deriva, nel senso classico del termine, ContentPlaceHolder della pagina Master e
dalla pagina Master, ma continua ad essere i due sono associati in base alla proprietà
figlia della Page pur mantenendo traccia ContentPlaceHolderID del Content stesso.
nella sua parte HTML del fatto che non Durante l’esecuzione, il ContentPlaceHol-
vive di vita propria ma in simbiosi con la der diventa un controllo della collection
pagina Master. Controls della pagina aspx, mentre i con-

22 VBJ N. 71 - Settembre/Ottobre 2006


WEB

Figura 2 Aggiunta di una nuova pagina aspx

trolli effettivi della pagina stessa, presenti </asp:contentplaceholder>


all’interno del Content, sono inseriti nella </div>
Controls del ContentPlaceHolder. </form>
Per creare una pagina Master all’interno del </body>
nostro progetto è sufficiente utilizzare il menu </html>
Siti Web, l’opzione Aggiungi Nuovo Elemento
e selezionare l’oggetto Pagina master. Da notare la direttiva @Master che sosti-
A seguito di ciò è creato un file con esten- tuisce la direttiva @Page e la presenza
sione .master che non differisce molto da dei ContentPlaceHolder (uno solamente
una classica pagina aspx: nell’esempio).
La pagina Master non può essere richia-
<%@ Master Language=”VB” CodeFile=”MasterPage.master.vb” mata da sola (se si prova a richiedere una
Inherits=”MasterPage” %> pagina con estensione .master si ottiene un
errore dal server), ma lavora in congiun-
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 zione con una pagina aspx che la utilizza
Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/ come modello.
xhtml1-transitional.dtd”> Per creare una pagina aspx che utilizza la
pagina Master è sufficiente creare un nuovo
<html xmlns=”http://www.w3.org/1999/xhtml” > elemento per il sito web (con lo stesso menu
<head runat=”server”> utilizzato per la master) scegliendo web
<title>Pagina senza titolo</title> form e selezionando il segno di spunta in
</head> basso (Figura 2).
<body> Nella successiva form proposta si può
<form id=”form1” runat=”server”> scegliere quale pagina Master utilizzare
<div> (Figura 3).
<asp:contentplaceholder id=”ContentPlaceHolder1” È necessario prestare attenzione perché se
runat=”server”> non si sceglie la pagina Master in questo

N. 71 - Settembre/Ottobre 2006 VBJ 23


WEB

momento, sarà necessario intervenire sul ne della stessa con la Master page (che,
codice HTML della pagina aspx per asso- invece, li ha).
ciare in un secondo momento la pagina Si capisce che per “sganciare” una pagina
Master. da una pagina Master è necessario rimuo-
vere l’attributo MasterPageFile ed inserire
<%@ Page Language=”VB” MasterPageFile=”~/ i tag <HTML>, <HEAD> e <BODY>
MasterPage.master” AutoEventWireup=”false” CodeFile=”Defa- (nonché il tag <form>).
ult.aspx.vb” Inherits=”_Default” title=”Untitled Page” %> È possibile specificare l’attributo Ma-
<asp:Content ID=”Content1” ContentPlaceHolderID=”Content sterPageFile nella sezione pages del file
PlaceHolder1” Runat=”Server”> di conzione web.config. In questo caso
</asp:Content> le impostazioni indicate nel web.config
verranno automaticamente associate a
Osserviamo che la pagina associata alla tutte le pagine che non hanno la direttiva
Master page è diversa, nella struttura, ri- @Page.
spetto ad una pagina che non ha Master
page associata. <configuration>
.
<%@ Page Language=”VB” AutoEventWireup=”false” CodeFile=” .
Default2.aspx.vb” Inherits=”Default2” %> <system.web>
.
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 .
Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/ <pages masterPageFile=”~/MasterPage.master” />
xhtml1-transitional.dtd”> .
.
<html xmlns=”http://www.w3.org/1999/xhtml” > </system.web>
<head runat=”server”> .
<title>Pagina senza titolo</title> .
</head> </configuration>
<body>
<form id=”form1” runat=”server”> Altra caratteristica dell’attributo Master-
<div>

</div>
</form>
</body>
</html>

Si può notare la pre-


senza dell’attributo
MasterPageFile del-
la direttiva @Page
e l’assenza dei tag
<HTML>, <HEAD>
e <BODY> tipici di
una pagina HTML.
Questi, infatti, ven-
Figura 3 Selezione della pagina master
gono forniti alla
pagina, dalla fusio-

24 VBJ N. 71 - Settembre/Ottobre 2006


WEB

PageFile della direttiva @Page è che può ster page di una pagina aspx sia cambiata
essere personalizzato in base al browser dinamicamente in base a particolari con-
che si sta utilizzando. dizioni (ad esempio, se si vuole che ogni
Nell’esempio seguente, vengono utilizzate, utente abbia la possibilità di avere il suo
per una stessa pagina, differenti Master page layout grafico). Per fare ciò è sufficiente
a seconda del browser che le visualizza: non inserire l’attributo MasterPageFile
nella direttiva @Page ed impostare la
<%@ Page Language=”VB” ie:masterPageFile=”~/ proprietà MasterPageFile della pagina nel
IEMasterPage.master” netscape:masterPageFile=”~/ gestore dell’evento PreInit:
NSMasterPage.master” masterPageFile=”~/
BaseMasterPage.master” AutoEventWireup=”false” CodeFile Protected Sub Page_PreInit(ByVal sender As Object,
=”Default.aspx.vb” Inherits=”_Default” title=”Untitled ByVal e As System.EventArgs) Handles Me.PreInit
Page” %> Me.MasterPageFile = Profile(“MasterPage”)
<asp:Content ID=”Content1” ContentPlaceHolderID=”Content End Sub
PlaceHolder1” Runat=”Server”>
<asp:Button ID=”Bottone” runat=”server” Text=”Button” />
<asp:TextBox ID=”TextBox” runat=”server”></asp: I Temi
TextBox> Abbiamo visto che le pagine Master con-
</asp:Content> sentono di dare costanza alla struttura del-
le pagine del sito, ma ci sono elementi che
I prefissi che si possono anteporre all’attri- devono rimanere inalterati tra le pagine,
buto MasterPageFile sono impostati all’in- pur cambiando la loro disposizione spazia-
terno della sezione BrowserCaps del file di le all’interno delle stesse. Stiamo parlando
configurazione. di font, colori, immagini, loghi e quant’al-
tro caratterizza graficamente un sito web.
Infine, è possibile fare in modo che la Ma- I temi sono stati creati proprio per ri-

Figura 4 Aggiunta di un nuovo elemento di un tema

N. 71 - Settembre/Ottobre 2006 VBJ 25


WEB

solvere questa problematica e possiamo Impostare il tema per l’intero sito signifi-
considerarli come un’estensione dei già ca che tutti gli stili definiti nel tema sono
utilizzati CSS. applicati a tutti i controlli di ogni pagina, a
I temi altro non sono che definizioni di stili meno che non si esegua l’override del tema
e possono, al loro interno, contenere anche per una singola pagina.
dei CSS. Impostare il tema per una singola pagina
Il loro ambito di applicazione può essere a comporta, invece, l’applicazione di tutti
livello di applicazione (tutto il sito), di pagi- gli stili del tema a tutti i controlli della
na o di controllo server. pagina.
I temi differiscono dai fogli di stile CSS per Per impostazione predefinita, le proprie-
le seguenti caratteristiche: tà e le impostazioni definite in un tema,
vanno a sovrascrivere le proprietà, even-
1. possono definire, al loro interno, proprie- tualmente, impostate sui controlli a design
tà di un controllo o di una pagina che van- time. È possibile impostare un tema come
no al di là delle classiche proprietà di stile. tema del foglio di stile, il che comporta che
Ad esempio in un tema è possibile defini- le impostazioni del tema verranno applica-
re gli elementi grafici di un TreeView; te alle proprietà dei controlli che non sono
2. possono contenere anche elementi grafi- state definite a design-time.
ci (immagini, icone, etc., etc.); Per impostare un tema in un sito è suffi-
3. si può decidere se le proprietà e gli stili ciente intervenire nel file web.config ed
definiti in un tema sono sovrapposti o inserire l’attributo theme del tag pages:
meno alle proprietà eventualmente im-
postate a design-time; <configuration>
4. è possibile applicare un solo tema per .
pagina. .
<system.web>
Ogni tema è caratterizzato da un nome .
(che deve essere univoco) e può essere .
composto da fogli di stile CSS, da interfac- <pages Theme=”MioTema” />
ce (skin) e da immagini. .
Le interfacce (o skin) sono dei file di testo .
di cui vedremo in dettaglio le peculiarità </system.web>
nel prossimo paragrafo. .
In pratica il CSS fornisce le proprietà .
client-side della pagina, mentre lo skin, </configuration>
come vedremo, le proprietà server-side.
Per definire un tema, è necessario creare la In questo modo tutte le pagine del sito
cartella App_Themes (menu Sito Web, Ag- avranno il tema MioTema.
giungi Cartella ASP.NET, Tema) ed un tema Per applicare il tema come tema del foglio
al suo interno (che in realtà è anch’esso una di stile si utilizza l’attributo StyleSheetThe-
cartella). me anziché l’attributo Theme:
A questo punto è possibile inserire un
elemento costituente del tema (CSS, skin <configuration>
o altro) tramite il menu SitoWeb, Aggiungi .
nuovo elemento (Figura 4). .
Vediamo ora, una volta realizzato un tema, <system.web>
come è possibile applicarlo al sito o ad una .
singola pagina. .

26 VBJ N. 71 - Settembre/Ottobre 2006


WEB

<pages StyleSheetTheme=”MioTema” /> di una pagina Master) o la proprietà Ena-


. bleTheming del controllo.
. Per applicare un tema a livello di codice si
</system.web> procede in maniera simile a quanto visto
. per le Master page: nel caso di una pagina
. aspx, si deve impostare la proprietà Theme
</configuration> dell’oggetto Page nel gestore dell’evento
PreInit. Ad esempio, supponiamo che il
Se si desidera che il tema sia applicato nome del tema da impostare sia contenuto
solo ad un sottoinsieme delle pagine del nella variabile di sessione Tema, avremo:
sito si può procedere raggruppando le pa-
gine al di sotto di una cartella e mettendo Public Sub Page_PreInit(ByVal Sender As Object, ByVal e
all’interno di essa un web.config con le As EventArgs)
impostazioni sul tema oppure creare un Dim nomeTema As String
elemento <location> nel web.config e spe- nomeTema = Session(“Tema”)
cificare la cartella: If not nomeTema is Nothing Then
Page.Theme = nomeTema
<configuration> End If
. End Sub
<location path=”~/Sezione1”>
<system.web>
<pages Theme=”MioTema1” /> Per quanto riguarda un tema del foglio
</system.web> di stile, invece, è necessario riscrivere la
</location> proprietà StyleSheetTheme della pagi-
<location path=”~/Sezione2”> na. Nell’esempio precedente avremo:
<system.web>
<pages Theme=”MioTema2” /> Public Overrides Property StyleSheetThema() As String
</system.web> Get
</location> Return Session(“Tema”)
. End Get
</configuration> Set(ByVal value As String)
End Set
Per applicare un tema ad una singola pagi- End Property
na, invece, si utilizzano gli attributi Theme
o StyleSheetTheme della direttiva @Page. I temi possono includere anche elementi
Nel caso in cui il tema contenga delle inter- grafici o altre risorse (script, audio, applet
facce, queste vengono applicate a tutte le e quant’altro) che generalmente si trovano
istanze dei controlli delle pagine del sito (o nella stessa cartella dei file di interfaccia o
della pagina se si tratta di un tema su una in una sottocartella del tema.
pagina singola). In un tema possono essere impostate
Per disattivare l’utilizzo di un tema per tutte quelle proprietà delle pagine e dei
una pagina o per un controllo si può pro- controlli che sono relative all’aspetto o al
cedere in due modi: o si definisce il tema contenuto statico ma non è possibile im-
come tema del foglio di stile e si impostano postare quelle proprietà che specificano
le proprietà della pagina o del controllo il comportamento del controllo, come ad
oppure si disabilita l’utilizzo del tema esempio il CommandName per un bottone
valorizzando l’attributo EnableTheming di una DataGrid.
della direttiva @Page (@Master se si tratta Le proprietà impostabili da tema sono so-

N. 71 - Settembre/Ottobre 2006 VBJ 27


WEB

lamente quelle che hanno l’attributo The- In questo modo si può applicare l’in-
meableAttribute impostato su True. terfaccia in maniera selettiva (e non
indistintamente a tutti i controlli) impo-
Le interfacce stando la proprietà SkinID delle istanze
Il concetto di interfaccia, brevemente ac- del controllo a cui si vuole associare l’in-
cennato nel precedente paragrafo, unito a terfaccia.
quello delle Master page e dei temi, per- Per impostare da codice l’interfaccia di
mette di completare la gestione dell’aspet- un controllo è necessario valorizzare la
to grafico di un sito. proprietà SkinID dello stesso nel gestore
Un’interfaccia è un modo per impostare le dell’evento PreInit della pagina che lo
proprietà dei controlli lato server senza do- ospita.
ver mettere mano al codice delle pagine o
delle classi che sono nel code behind. Conclusioni
I file di interfaccia sono file di testo con Probabilmente strumenti come Master
estensione .skin al cui interno, in maniera page, temi ed interfacce non sono in-
molto simile al codice presente nelle pagi- dispensabili per la realizzazione di siti
ne aspx, vengono riportate le proprietà ed i coerenti (visto che fino ad ora se ne è
valori da impostare dei controlli del sito. fatto a meno), ma permettono di gesti-
Possiamo definire le interfacce come dei re, in maniera quasi indolore, eventuali
CSS lato server. cambiamenti grafici che, inevitabilmente,
Per esempio supponiamo di avere il se- hanno i siti di un certo livello. Grazie al-
guente file di interfaccia: l’utilizzo sensato ed oculato di queste tre
nuove caratteristiche del framework si
<asp:label runat=”server” può anche riuscire a dare una sorta di per-
backcolor=”blue” sonalizzazione all’utente (impostando di-
forecolor=”white” namicamente una o tutte e tre) che rende
font-name=”Arial”/> l’interazione sicuramente più coinvolgen-
te. Ben venga, quindi, l’utilizzo di queste
Questo fa si che tutti i controlli label delle nuove funzionalità, anche se inizialmente
pagine che hanno associato il tema che possono sembrare inutilmente complicate
contiene l’interfaccia, avranno il backcolor, e prolisse.
il forecolor e il font impostato con i valori
definiti nel file.
In pratica è come se, da codice, si avesse:
Bibliografia e Riferimenti
Label1.BackColor = Drawing.Color.Blue [1] Dino Esposito – “ASP.NET 2.0 Program-
Label1.ForeColor = Drawing.Color.White mazione avanzata”, Mondadori Informati-
Label1.Font.Name = “Arial” ca, 2006
[2] Dino Esposito – “Introducing Microsoft
È possibile associare un identificativo alla ASP.NET 2.0”, Microsoft Press, 2005
definizione di interfaccia valorizzando l’at- [3] George Shepherd – “ASP.NET 2.0 passo
tributo SkinID: per passo”, Mondadori Informatica, 2006
[4] http://www.aspitalia.com
<asp:label runat=”server” SkinID=”labelSpeciale” [5] http://www.weekit.it
backcolor=”blue” [6] http://www.dotnethell.it
forecolor=”white” [7] http://www.microsoft.it
font-name=”Arial”/>

28 VBJ N. 71 - Settembre/Ottobre 2006


ENTERPRISE

Interoperabilità
COM e .NET Seconda puntata

Comprendere e confrontare i modelli di eventi in .NET ed in COM


non solo può aiutarci a specializzare la nostra conoscenza del fra-
mework .NET stesso ma può essere utile per un miglior riutilizzo
event-driven, in applicazioni.NET, di software binario COM già

COMNET2

di Maurizio Mammuccini

I
n questa conclusiva seconda puntata Comunque queste aziende
viene esposto lo strato d’interoperabilità sono attratte dalla potenza
COM/.NET che permette l’utilizzo di com- straordinaria del .NET Fra-
ponenti assembly .NET da parte di client COM, mework e gradirebbero poter
così da concludere quanto esposto nella prima aggiungere già alle loro appli-
puntata ([11]). cazioni un qualche manufatto
A mio avviso questa è una parte abbastanza poco funzionale scritto in .NET,
trattata nella letteratura del settore in quanto si prima di una completa ripro-
pensa di non dover mai manutenere applicativi gettazione e riscrittura delle
COM impiegando componenti binari realizzati medesime.
aderendo a standard industriali di generazione Ebbene in questo articolo
successiva; o perlomeno molti non lo ritengono esporrò anche come sia pos-
conveniente. Invece credo che l’aggiunta di sibile realizzare ciò, ossia
componentistica .NET in applicativi COM sia un come si possano manutenere
ottimo mezzo per procedere incrementalmente in .NET vecchi applicativi
e gradualmente ad una reingegnerizzazione di COM, orientando l’esposizio-
procedure COM ormai assestate che necessitano ne soprattutto al confronto
di essere portate sulla piattaforma .NET. del modello di eventi .NET in
Nella mia attività di formatore mi sono accorto COM (che rimane l’argomen-
che diverse aziende, a causa di motivi di vario to centrale dell’articolo). Al
tipo, tendono a non riscrivere le loro vecchie ap- termine dell’articolo inoltre
plicazioni COM in .NET o comunque tendono a elencherò delle linee guida,
ritardare i tempi di una tale riscrittura. ossia delle considerazioni
finali sulla interoperabilità
COM e .NET che spero possa-
Maurizio Mammuccini ha esperienza decennale nella pro-
no esser d’aiuto a chi si trova
gettazione e sviluppo di software. Dedica particolare atten-
zione alle tecnologie di calcolo distribuito. Utilizza sin dalle a manutenere vecchi appli-
primissime versioni Visual Studio di Microsoft. Attualmente cativi COM e sta pensando
è formatore per PCSNet Umbria SRL a Perugia e consulente ad una loro migrazione verso
per aziende del settore informatico. È MCSD for VS6 - MCDBA
for Sql Server 2000 - MCAD for .NET - MCSD for .NET ed .NET.
MCT. Risiede in Umbria.

30 VBJ N. 71 - Settembre/Ottobre 2006


ENTERPRISE

CCW – COM Callable Wrapper


In [11] abbiamo visto come l’ar-
chitettura d’interoperabilità COM/
.NET renda possibile l’esposizione
di componenti COM a potenziali
utilizzatori .NET ricorrendo ai po-
tentissimi RCW (Runtime Callable
Wrapper).L’RCW di fatto incapsula
il componente COM esponendone i Figura 1 Il CCW rende visibile l’assembly .NET come un
comune componente COM, con tutte le funzio-
servizi via .NET. nalità tipiche di tali componenti
In modo simmetrico e con altret-
tanta potenza ma con evidenti dif-
ferenze è possibile incapsulare un
componente assembly .NET ed esporlo a Approfondimenti sul CCW
client COM ricorrendo ai CCW (COM Cal- Vediamo un po’ più in profondità l’organiz-
lable Wrapper). zazione interna del CCW ed a tal proposito
Ribadiamo per i CCW quanto esposto in invito il lettore a rivedere l’esposizione di
[11] per gli RCW, ma in modo simmetrico. COM in [9] o l’introduzione a COM in [11].
Questi oggetti CCW svolgono un servizio Innanzitutto bisogna osservare che il CCW
basilare in tutta l’architettura d’interope- è allocato (costruito) runtime nell’heap non
rabilità effettuando il marshaling (smi- gestito e quindi non è soggetto a garbage
stamento) degli argomenti trasferiti nelle collection, ecco dunque spiegato perché il
chiamate a metodo tra il codice non gestito CCW gestisca un contatore di riferimenti
e quello gestito, verso l’oggetto .NET di cui alla maniera di COM.
effettuano il wrapping. Il CCW dovendo agire proprio come un ge-
Dunque i CCW sono oggetti che hanno la nuino componente COM espone un’inter-
capacità di varcare i confini tra il codice faccia IUnknown ed un’interfaccia IDispa-
non gestito e quello gestito, preoccupan- tch. A tal proposito si tenga presente che
dosi di tutti i meccanismi di basso livello il CCW implementa sempre le interfacce
come appunto la trasformazione dei tipi COM elencate nella Tabella 1.
dato (Figura 1); ciò è dovuto al fatto che Il CCW, per i client COM di un assembly
COM è stato realizzato prima di .NET ed il .NET, è in grado di operare come un com-
codice COM non viene supportato nativa- ponente COM classico, proprio perché im-
mente dall’infrastruttura .NET. plementa tali interfacce.
Il CCW inoltre implementa tutta una serie Inoltre, operando come un componente
di operazioni di basso livello tipiche di COM, mette a disposizione dei client il clas-
un componente COM, come ad esempio sico meccanismo di puntamento alle inter-
il conteggio dei riferimenti per gestirsi il facce COM, necessario al funzionamento dei
life-time in memoria. Allorquando, infatti, client che vogliono invocare le funzionalità
il conteggio dei riferimenti al CCW ha rag- dell’assembly .NET passando per il CCW.
giunto lo zero, allora il CCW rilascia una Prima di andare avanti, vorrei qui ricor-
referenza interna all’istanza dell’assembly dare un fatto notevole circa gli assembly
.NET e viene deallocato. .NET. Gli assembly .NET sono il risultato
Insomma dal lato del codice non gestito, della compilazione in MSIL (Microsoft
il CCW rende visibile l’assembly .NET Intermediate Language) di tipi .NET (es.
come un comune componente COM con classi, interfacce, … )
tutte le funzionalità tipiche dei compo- Dentro l’assembly compilato viene scritta
nenti COM. una sezione chiamata metadati, alle volte

N. 71 - Settembre/Ottobre 2006 VBJ 31


ENTERPRISE

Interfacce COM sempre implementate da un CCW


Fornisce l’implementazione standard dell’interfaccia IUnknown con
IUnknown cui il client COM gestisce la durata del CCW e provvede all’assegna-
zione forzata.

IDispatch Fornisce un meccanismo per l’associazione tardiva al tipo.

Consente ai client COM di ottenere l’accesso all’interfaccia ITypeInfo


IProvideClassInfo
implementata da una classe gestita.

Consente a un client COM di determinare se l’oggetto gestito


supporta l’interfaccia IErrorInfo. Se sì, consente al client di ottenere
ISupportErrorInfo
un puntatore all’ultimo oggetto di eccezione. Tutti i tipi gestiti sup-
portano l’interfaccia IErrorInfo.
Fornisce una descrizione testuale dell’errore, la relativa origine, un
IErrorInfo file della Guida, un contesto della Guida e il GUID dell’interfaccia che
ha definito l’errore (per le classi .NET è sempre GUID_NULL).
Fornisce per le classi le stesse informazioni sul tipo che fornisce
ITypeInfo
Tlbexp.exe.

Tabella 1 Interfacce COM sempre implementate da un CCW

paragonata alle librerie dei tipi COM (tlb), metadati nell’assembly .NET sono utilis-
che intende descrivere i tipi compilati nel- simi in quanto sono alla base del mecca-
l’assembly. nismo che porta alla costruzione del CCW
Di fatto questa assimilazione della sezione per l’assembly. Questo meccanismo passa
metadati ad una libreria dei tipi è un po’ primariamente per la generazione di una
fuorviante, essendo le sezioni metadati di libreria dei tipi (tlb) che si rende neces-
assembly .NET molto più ricche delle type saria in quanto i client COM non possono
library. accedere direttamente alle informazioni
Dentro una sezione metadati infatti trovia- sui tipi fornite dagli assembly.
mo: Concludiamo queste osservazioni d’ap-
profondimento sul CCW evidenziando un
• la descrizione dell’assembly (nome, versio- comportamento strutturale molto impor-
ne, cultura, dipendenza dell’assembly da tante. Il CCW è prodotto in modo unico
altri assembly…) per l’assembly .NET wrappato indipenden-
• la descrizione dei tipi (interfacce, classi… ) temente dal numero dei client COM che
• attributi personalizzati (forniti dall’utente, accedono alle funzionalità dell’assembly
forniti dal framework… ) (Figura 3).

Il grande vantaggio dei metadati è che Regole e norme


permettono all’assembly una propria au- all’interoperabilità di COM
tonomia di descrizione e di funzionamento Cercando di realizzare un assembly .NET
che lo svincola da altri tipi di supporto sia a per un suo utilizzo in COM bisogna tener
runtime che a tempo di programmazione. conto di alcune regole ed alcune norme che
Dal punto di vista del nostro argomento i riassumiamo per brevità qui di seguito. Ciò

32 VBJ N. 71 - Settembre/Ottobre 2006


ENTERPRISE

al fine di ottenere il mas-


simo vantaggio dall’inte-
roperabilità di COM.

1. Le classi scritte in un
assembly .NET debbono
avere un costruttore di
default (senza parame-
tri).
Infatti COM da parte
sua non dispone del Figura 2 Univocità del CCW rispetto ai client COM
concetto di costruttore,
quindi quando il wrap-
per CCW istanzia per
un client COM una classe .NET, l’unico C#
costruttore che può invocare è quello di // esempio di utilizzo dell’attributo ComVisible per un
default, ossia senza parametri. assembly
using System.Runtime.InteropServices;
2. Sono visibili a COM solo i tipi pubblici
scritti nell’assembly .NET. [assembly: ComVisible(false)]
Solo i tipi pubblici di un assembly ven-
gono registrati ed esportati nella libreria
dei tipi. Di conseguenza saranno visibili VB.NET
in COM solo i tipi pubblici. ‘ esempio di utilizzo dell’attributo ComVisible per un
assembly
3. Metodi, proprietà, campi ed eventi devo- Imports System.Runtime.InteropServices
no avere ambito di visibilità pubblico.
<Assembly: ComVisible(True)>
È necessario che i membri di un tipo pub-
blico .NET, se sono destinati ad essere vi- Mentre nel successivo pezzo di codice ad
sibili a COM, siano anch’essi pubblici. esempio si vieta la visibilità a COM di un
Di default tutti i tipi pubblici e tutti i metodo di una classe .NET, mentre si per-
membri pubblici di un tipo pubblico mette la visibilità dell’intera classe (sempre
sono visibili a COM. Quest’ultima situa- però con l’esclusione del metodo nascosto);
zione può essere modificata utilizzando il codice deve essere collocato nel relativo
l’attributo ComVisibleAttribute che si file di definizione della classe:
trova nel namespace System.Runtime.In
teropServices. Infatti tramite l’attributo C#
ComVisibleAttribute è possibile stabilire // esempio di utilizzo dell’attributo ComVisible per una
l’accesso o meno a COM di un tipo gestito classe
o di un membro specifico entro un tipo [ComVisible(True)]
gestito o di tutti i tipi all’interno di un class ClassForInteroperability
assembly .NET. Nel successivo pezzo
di codice (in C# e VB.NET) ad esempio Public Sub New()
si vieta la visibilità a COM di un intero ‘costruttore di default, deve essere presente
assembly .NET, il cui codice deve essere End Sub
collocato nel relativo file AssemblyInfo:
<ComVisible(False)> _

N. 71 - Settembre/Ottobre 2006 VBJ 33


ENTERPRISE

Public Function HiddenMethod() As String Questo è un punto molto delicato. Si ri-


Return “” cordi ([9] od [11]) che in COM l’accesso al
End Function codice binario di un componente passa
per la valorizzazione di un indirizzo di
Public Function MyOtherMethod() As String un’interfaccia esposta da questi. Il CCW
‘questo metodo è visibile per default a COM che a tutti gli effetti funge da componen-
Return “Ciao,Mondo!” te COM relativamente a client COM di
End Function un componente gestito, non ha quindi
di suo un meccanismo che permetta ai
End Class client di distinguere tra una classe ed
una sua istanza. Dunque non c’è suppor-
VB.NET to al concetto di membro statico da parte
‘ esempio di utilizzo dell’attributo ComVisible per una dei CCW.
classe
<ComVisible(True)> _ 5. È buona norma che le classi gestite per
Class ClassForInteroperability l’interoperabilità implementino le inter-
facce in maniera esplicita.
Public Sub New() Mi viene da dire che ciò dovrebbe co-
‘costruttore di default, deve essere presente munque essere sempre vero in una sana
End Sub ottica di progettazione e sviluppo OOP
(Object-Oriented), ma in funzione del-
<ComVisible(False)> _ l’interoperabilità con COM ciò assume
Public Function HiddenMethod() As String maggior evidenza.
Return “” Anche se l’interoperabilità COM dispone
End Function di un suo meccanismo per generare in
modo automatico un’interfaccia conte-
Public Function MyOtherMethod() As String nente tutti i membri della classe e i mem-
‘questo metodo è visibile per default a COM bri della relativa classe base, è preferibile
Return “Ciao,Mondo!” fornire interfacce esplicite. L’interfaccia
End Function generata automaticamente è definita in-
terfaccia della classe (class interface).
End Class
Esposizione di assembly .NET
In questi esempi di codice abbiamo visto all’interoperabilità di COM
l’applicazione di un fondamentale attribu- Ci preoccuperemo in questa sezione di
to per l’interoperabilità di COM ma ve ne come si possano esporre assembly .NET al-
sono altri di notevole importanza che al l’interoperabilità di COM, tenendo a mente
momento nel nostro articolo non trattia- quanto detto nelle pagine precedenti. Nel
mo. Invito comunque l’attento lettore ad paragrafo precedente abbiamo dato norme
approfondirne la conoscenza, poiché l’uti- e regole di cui tener conto quando si pro-
lizzo di attributi nella fase di realizzazione getta un assembly per l’interoperabilità, in
del manufatto assembly .NET permette di funzione di un suo impiego in applicativi
intervenire in modo determinante sul mec- COM. In questa sezione dell’articolo in-
canismo di conversione eseguito dalle API vece ci occupiamo di come fattivamente
e dagli strumenti di interoperabilità COM. scrivere il codice di tipi gestiti per COM. Ci
accorgeremo che .NET fornisce un discre-
4. Nessun membro nella classe .NET può to numero di attributi di programmazione,
essere statico. alcuni dei quali debbono essere conosciuti.

34 VBJ N. 71 - Settembre/Ottobre 2006


ENTERPRISE

I meccanismi di esposizione fisica di un as-


sembly gestito a COM sono numerosi. Per 1. TlbExp.exe
esporre un assembly a COM possiamo: 2. RegAsm.exe

• sfruttare l’IDE di Visual Studio.NET TlbExp.exe è l’utilità di esportazione della


• eseguire l’operazione manualmente libreria dei tipi relativa all’assembly gesti-
to e genera una classica libreria di tipi al
Tutti i meccanismi di esposizione a COM cui interno sono descritti i tipi definiti in
di un assembly gestito comunque passano un assembly .NET.
per la produzione di una libreria binaria La sintassi canonica utilizzata di solito
dei tipi, una TLB, ciò per ovvie necessità di per produrre la TLB dall’assembly ge-
COM ([9] od [11]). stito è:
Nell’IDE di Visual Studio.NET il menu
Progetto contiene la voce Proprietà di tlbexp [path]/nome_assembly /out: [path]/nome_tlb
Nome_Progetto, al click su questa voce
compare la finestra che riassume visual- dove nome_assembly è il nome dell’assem-
mente tutte le proprietà impostate per bly gestito comprensivo della sua estensio-
Nome_Progetto. ne dll e nome_tlb è il nome della libreria
Se vogliamo che l’IDE alla produzione dei tipi comprensiva della sua estensione
dell’assembly DLL produca la TLB con tlb.
la traduzione COM dei tipi gestiti e la RegAsm.exe è l’utility di registrazione
registri nel registro di sistema, assieme degli assembly gestiti nel Registro di
ad altre utili informazioni sull’assembly sistema. Legge la sezione metadata al-
gestito per COM, dovremo impostare a l’interno di un assembly e aggiunge al
true il flag Registra per interoperabilità Registro di sistema le voci necessarie
COM presente alla voce Generazione in per consentire ai client COM di istan-
Proprietà di Configurazione nella fine- ziare classi di .NET Framework in modo
stra delle proprietà. Comunque indipen- trasparente. Quando una classe gestita
dentemente dalla strada percorsa per è stata registrata nel Registro, qualsiasi
esporre a COM l’assembly gestito, è bene client COM può utilizzarla come se si
produrre una chiave univoca con cui fir- trattasse di una comune classe COM. La
mare l’assembly; a tal scopo si utilizzi classe deve essere registrata una sola
l’utility sn.exe fornita gentilmente dalla volta, al momento dell’installazione del-
Microsoft col framework .NET. Dopo aver l’assembly nella macchina target. Si fac-
impostato a true il flag Registra per inte- cia attenzione che non è possibile istan-
roperabilità COM possiamo utilizzare la ziare da COM classi d’assembly finché
libreria dei tipi risultante dalla produzio- tali classi non siano state effettivamente
ne del client COM del nostro assembly registrate.
gestito. La sintassi canonica utilizzata di solito per
Si faccia ben attenzione che sebbene .NET registrare un assembly gestito è:
Framework non prediliga passare per il Re-
gistro di sistema, la cosa diventa necessa- regasm [path]/nome_assembly
ria quando si lavora con l’interoperabilità
di COM, in quanto quest’ultimo sfrutta il od
Registro.
L’esportazione manuale della libreria dei regasm [path]/nome_assembly /regfile: [path]/nome_
tipi relativa all’assembly gestito passa per assembly.reg
due utilità fornite col framework .NET:

N. 71 - Settembre/Ottobre 2006 VBJ 35


ENTERPRISE

dove nome_assembly è il nome dell’assembly


gestito comprensivo della sua estensione dll ‘lista d’eventi
ed nome_assembly.reg è il file contenente Sub ChangeValueEvent(b As Boolean)
tutte le voci di registro necessarie al sistema,
comprensiva della sua estensione tlb. End Interface
Volendo che i nostri client COM possano
eseguire codice event-driven nell’accedere Le interfacce pubblicano gli eventi noti-
a classi gestite, relativamente a notifiche ficati dalla sorgente gestita e che il client
emesse da queste ultime, dobbiamo racco- dovrà, se vuole, gestire.
gliere gli eventi entro un’opportuna inter- Come vediamo vengono utilizzati due
faccia sink d’eventi (event sink interface) attributi fondamentali: GuidAttribute e
in codice gestito. InterfaceTypeAttribute.
GuidAttribute permette l’assegnazione di
C# un UUID d’interfaccia all’interfaccia IO-
// esempio di codice perazioni quando questa viene esportata
[ComVisible(true),GuidAttribute(“82e42c55-fdd7-468d-a3cf- nella libreria dei tipi, così come richiede
363d0d067588”), COM.
InterfaceTypeAttribute(ComInterfaceType. La sintassi dell’attributo di programmazio-
InterfaceIsIDispatch)] ne GuidAttribute è:
public interface IOperazioni
{ C#
//lista d’eventi // esempio di codice
void ChangeValueEvent(bool b); [GuidAttribute(“82e42c55-fdd7-468d-a3cf-363d0d067588]
}
VB.NET
VB.NET ‘ esempio di codice
‘ esempio di codice < GuidAttribute(“82e42c55-fdd7-468d-a3cf-363d0d067588”)>
<ComVisible(true),GuidAttribute(“82e42c55-fdd7-468d-a3cf-
363d0d067588”), _ Ricorrendo all’utility UUIDGEN.exe
InterfaceTypeAttribute(ComInterfaceType.InterfaceIs fornita con l’SDK di Microsoft Visual
IDispatch)> _ C++ 6.0 possiamo ricavare i GUID d’in-
Public Interface IOperazioni terfaccia da assegnare come argomento

ComInterfaceType
Indica che l’interfaccia esposta a COM è un’interfaccia duale, che
InterfaceIsDual consente sia l’associazione anticipata sia l’associazione tardiva. In-
terfaceIsDual è il valore di default.

Indica che l’’interfaccia esposta a COM è un’ interfaccia dispatch


InterfaceIsDispatch che consente solo l’associazione tardiva.

Indica che l’interfaccia esposta a COM è un’ interfaccia derivata dal-


InterfaceIsIUnknown la IUnknown che consente solo l’associazione anticipata.

Tabella 2

36 VBJ N. 71 - Settembre/Ottobre 2006


ENTERPRISE

C++ 6.0 possiamo ricavare i GUID d’in- Public Class Operazioni


terfaccia da assegnare come argomento
all’attributo GuidAttribute. ‘…
L’attributo InterfaceTypeAttribute serve a
specificare a COM se, l’interfaccia esposta End Class
a COM è:
L’attributo ComSourceInterfaces lista un
• duale elenco di interfacce esposte come origini
• dispatch di eventi COM per la classe gestita. L’uti-
• solo IUnknown lizzo più frequente di questo attributo
prevede l’elenco delle interfacce sorgenti
Si può specificare ciò a COM ricorrendo d’evento entro stringhe separate dalla
all’enumerazione ComInterfaceType (Ta- virgola.
bella 2). Il client COM a questo punto non fa altro
che referenziare la libreria dei tipi espor-
È importante che a livello d’assembly siano tata e registrata ed utilizzarne i tipi nel
dichiarate le sintassi dei delegati d’evento proprio codice. Il client non avrà perce-
uguali a quelle dei metodi d’evento listati zione di passare tramite un proxy CCW
nell’interfaccia sink. quando effettua le chiamate al metodo
Viene definita la classe gestita ed al suo della classe gestita o nel ricevere da que-
interno vengono dichiarati gli eventi da sta delle notifiche d’evento, che volendo
notificare ai client servendosi dei delegati può gestire.
dichiarati.
La classe è dichiarata con un attributo Conclusioni
che fa riferimento all’interfaccia sink Ritengo che questa seconda puntata abbia
d’eventi che il client COM dovrà imple- esposto un aspetto dell’interoperabilità
mentare in uno specifico oggetto sink COM/.NET abbastanza sentito da chi at-
d’eventi ([11]). Se lavoriamo con client tualmente sta reingegnerizzando vecchie
COM Visual Basic 6 questo oggetto è procedure COM tuttora efficienti, avendo
realizzato dal compilatore previa dichia- presente la compatibilità con il Framework
razione con WithEvents del riferimento .NET.
all’istanza della classe gestita di cui verrà Lo scopo è quello di realizzare classi ge-
creato runtime il CCW. stite in integrazione e manutenzione al
vecchio codice COM, non producendo più
C# codice COM (in Visual Basic 6, in Visual
// esempio di codice C++ 6) ma scrivendolo direttamente in
[ComVisible(true),ComSourceInterfaces(“SAMPLELib.I un linguaggio .NET compatibile. Mi spie-
Operazioni”)] go meglio. Se la manutenzione della vec-
public class Operazioni chia applicazione COM richiede l’aggiun-
{ ta di nuove funzionalità, queste devono
// … essere scritte in binario .NET anziché
nelle vecchie DLL COM. I client COM
} secondo quanto visto possono ugualmen-
te utilizzarle via CCW ed ottenendo così
VB.NET l’indubbio vantaggio che si cominciano
‘ esempio di codice ad accumulare nuovi manufatti binari
<ComVisible(true),ComSourceInterfaces(“SAMPLELib. .NET da riutilizzare direttamente tal
IOperazioni”)> _ quali quando l’applicazione verrà rein-

N. 71 - Settembre/Ottobre 2006 VBJ 37


ENTERPRISE

Anche in questa seconda conclusiva pun- ca, 1998


tata voglio dire grazie alle opere citate in [4] George Sheperd e Brad King – “Inside
bibliografia i cui autori mi hanno aiutato ATL”, Mondadori Informatica, 1999
a comprendere e poi a mettere in pratica [5]_Jeffrey Richter, Francesco Balena
i concetti della moderna programmazio- – “Programmazione avanzata con Micro-
ne distribuita a componenti, secondo soft Visual Basic .NET” Mondadori Infor-
gli standard industriali della Microsoft, matica, 2002
invitando l’attento lettore ad approfon- [6]_http://msdn.microsoft.com/library/
dire su questi libri i concetti discussi nel default.asp?url=/library/en-us/csref/html/
presente articolo, sperando che oltre al- vcrefthedelegatetype.asp
l’acquisizione di tecniche e metodologie, [7]_http://msdn.microsoft.com/library/
egli possa percepire l’intrinseca bellezza default.asp?url=/library/en-us/csref/html/
dei contenuti concettuali. vcwlkeventstutorial.asp
[8]_http://msdn2.microsoft.com/en-us/
library/75s611wc.aspx
Bibliografia e Riferimenti [9]_E. Deana – “IUnknown, CLSID,
[1] Jeffrey Richter – “Microsoft .NET Pro- IDispatch,IID”, Visual Basic Journal n. 29
grammazione avanzata”, Mondadori In- [10] M. Mammuccini – “ .NET: Delegate e mo-
formatica, 2002 dello di eventi”, Visual Basic Journal n. 66
[2] Julian Templeman e John Paul Muel- [11] M. Mammuccini – “Interoperabilità
ler – “COM programming with Microsoft COM e .NET” (1a puntata), Visual Basic
.NET”, Microsoft Press, 2003 Journal n. 69
[3] Guy Eddon ed Enry Eddon – “Inside
Distributed COM”, Mondadori Informati-

38 VBJ N. 71 - Settembre/Ottobre 2006


VB6

Invocazione di
web service da VB6
Un approccio semplificato

Come realizzare un’applicazione VB6 che scarica immagi- Web Service


ni da satellite di un determinato indirizzo di una strada.

di Scott Swigart, Swigart Consulting LLC

I
siti web espongono ogni sorta di informazio- momento se questi siti web
ni utili. Con Amazon, si possono visualizzare subiscono delle modifiche.
le classifiche dei testi e effettuare acquisi- La risposta è l’utilizzo dei
ti; su Google, si possono effettuare ricerche sul web service. I web service
World Wide Web; con MapPoint, si possono ricer- permettono tipicamente a
care indirizzi e ottenere indicazioni; e attraverso un’applicazione di effettuare
eBay, si può acquistare o vendere, praticamen- richieste via Web, e piuttosto
te… di tutto (http://www.dotcomscotland.co.uk/ che ottenere in risposta i dati
weirdsites/ebay/eBay1.htm). come documento HTML, i
Il problema con i siti web è che non espongo- dati vengono restituiti in
no informazioni in un modo facile da consu- formato XML. Ciò agevola
mare per un’applicazione. Ad esempio, si po- notevolmente l’applicazione
trebbe volere che i propri agenti del servizio nel consumare le informazio-
clienti abbiano un’applicazione che permetta ni. I web service sono emer-
loro di localizzare il punto vendita più vicino, si come il mezzo con cui le
in modo da fornire indicazioni ai clienti che applicazioni comunicano fra
chiamano. Realizzare un’applicazione che loro. In alcuni casi, i sistemi
setacci a video MapPoint o MapQuest sareb- legacy backend vengono av-
be difficile, e si potrebbe corrompere in ogni volti da web service per poter
esporre facilmente dati e fun-
zionalità al resto dell’azienda.
© 2006 Microsoft Corporation. All rights reserved In altri casi, i provider Web-
based (come quelli elencati
Scott Swigart fornisce consulenza alle aziende su come uti- prima) introducono un web
lizzare al meglio l’attuale tecnologia e prepararsi al domani.
service per permettere l’ac-
A tal riguardo, Scott è un orgoglioso collaboratore del sito VB
Fusion, dove offre informazioni e strategie di reale utilizzo per cesso da programma ai dati
gli sviluppatori VB che vogliono realizzare il maggior numero e alle funzionalità che forni-
di funzionalità con il minimo sforzo. Scott è anche un Microsoft scono correntemente ai Web
MVP, ed è coautore di numerosi libri e articoli, ed è contattabile
all’indirizzo email scott@swigartconsulting.com.
browser.

40 VBJ N. 71 - Settembre/Ottobre 2006


VB6

L’applicazione Basic .NET può ricavare la sottoimmagine


In questo articolo, intendo realizzare e convertirla in una bitmap con una sola
un’applicazione che scarica delle immagi- riga di codice. E può anche assemblare
ni riprese da satellite di un determinato facilmente le sottoimmagini per ricavare
indirizzo di una strada. So per certo che l’immagine completa. Infatti, il più delle
le foto da satellite sono disponibili per volte si vedrà che il modo migliore per in-
mezzo del web service TerraServer (http: vocare un web service da Visual Basic 6 è
//www.terraserver.com). E so anche che si scrivere un po’ di codice Visual Basic .NET
può convertire un indirizzo di una strada per effettuare l’invocazione, e restituire i
in una coppia di coordinate latitudine/ risultati in COM standard che Visual Basic
longitudine per mezzo del web service 6 può consumare.
MapPoint (http://msdn.microsoft.com/
mappoint) e di Geocoder, pertanto so che i I web service di geocodifica
componenti di base dell’applicazione sono Il primo passo è convertire un indirizzo di
già disponibili. una strada in coordinate latitudine e lon-
Per prima cosa, mostrerò l’applicazione gitudine richieste da TerraServer. Ci sono
completa (Figura 1), e poi passeremo a due possibili alternative per farlo. Il modo
esaminare come il tutto viene realizzato in “migliore” è utilizzare qualcosa di simile
Visual Basic 6. al web service MapPoint. Si tratta di un
web service altamente affidabile fornito da
Decisioni Microsoft che può convertire rapidamente
Esistono due modi per poter invocare un indirizzo in una coppia di valori latitu-
un web service da Visual Basic 6. Si può dine e longitudine (un processo noto come
utilizzare il Web Services Toolkit [1], ma “geocodifica”). MapPoint è concepito come
quando si invoca un web service che ri- servizio ad alte prestazioni, scalabile e suf-
chiede dati complessi [2] ciò comporta la ficientemente affidabile da poter dipende-
gestione di un bel po’ di XML grezzo. Inol- re da esso per applicazioni mission-critical.
tre, l’immagine satellitare verrà restituita Tuttavia, MapPoint ha due svantaggi che
da TerraServer come
serie di sottoimma-
gini che è necessario
assemblare. Ciò si-
gnifica che la propria
applicazione riceverà
documenti XML con
le sottoimmagini
codificate in Base64.
L’applicazione do-
vrà decodificarle e
ricucirle in qualche
modo per ottenere
l’immagine comple-
ta. Da Visual Basic 6,
ciò non sarebbe una
passeggiata.
Con Visual Basic Figura 1 Immagine satellitare di un indirizzo da Visual Basic 6 (disponibile come
.NET, invece, è mol- video all’indirizzo [10])
to semplice. Visual

N. 71 - Settembre/Ottobre VBJ 41
VB6

Listato 1 Classe VB .NET per contenere le informazioni latitudine/longitudine una strada in coor-
dinate latitudine/
longitudine. Se si
<ComClass(LatLongInfo.ClassId, LatLongInfo.InterfaceId, _ invia l’indirizzo
LatLongInfo.EventsId)> _ come parte della
Public Class LatLongInfo
query string, il
#Region “COM GUIDs” sito restituirà un
Public Const ClassId As String = “4362FF28-FFF7-4BCE-B844-8CF4208536AC” documento XML
Public Const InterfaceId As String = “4A8FC896-6A9D-4F85-8B55-104CE4211829”
Public Const EventsId As String = “B9108846-8A2C-4698-831B-D3BC197168C5” contenente le infor-
#End Region mazioni latitudine/
Public Sub New()
longitudine. Per
MyBase.New() iniziare, ho creato
End Sub una classe mol-
Private _lat As Double to semplice per
Public Property Lat() As Double contenere il risul-
Get
Return _lat tato latitudine/
End Get longitudine (Lista-
Set(ByVal Value As Double)
_lat = Value
to 1).
End Set Questa classe
End Property contiene semplice-
Private _long As Double mente le proprietà
Public Property [Long]() As Double per la latitudine e
Get
Return _long della longitudine.
End Get Inoltre, la classe
Set(ByVal Value As Double)
contiene gli attri-
_long = Value
End Set buti in modo da ve-
End Property nire esposta come
End Class
oggetto COM che
può essere utilizza-
lo rendono non ideale per un utilizzo spo- to direttamente da Visual Basic 6.
radico. Innanzitutto, bisogna registrarsi [3] Il sito Geocoder può quindi essere utilizza-
e ottenere uno user ID e una password di to per ricercare un indirizzo e popolare un
valutazione. Queste informazioni di auten- oggetto LatLongInfo con le informazioni
ticazione vengono utilizzate per effettuare (Listato 2).
le invocazioni al servizio MapPoint. Questo
ID gratuito di valutazione vale per 45 gior- La cosa che amo di .NET è che semplifica
ni. Inoltre, dopo aver effettuato la registra- notevolmente l’interazione con il Web. La
zione, possono essere necessari un paio di classe WebClient [4] permette di “aprire”
giorni per ricevere il proprio ID. Pertanto, un URL come se fosse un file. Poiché que-
intendo fornirvi una applicazione d’esem- sto “file” è un documento XML, posso uti-
pio che si possa semplicemente scaricare lizzare semplicemente un XmlTextReader
e eseguire, senza alcuna registrazione [5] per ricercare nel risultato gli elementi
speciale o alcun setup; perciò, oltre a Map- XML con determinati nomi. Una volta tro-
Point, ho previsto una ulteriore opzione vati, basta prendere i valori e metterli nella
per la geocodifica dell’indirizzo. classe LatLongInfo. Se il sito web non è in
Anche il sito Web Geocoder.us (http: grado di risolvere l’indirizzo, questa fun-
//www.geocoder.us/help) fornisce una fun- zione restituirà Nothing; altrimenti, resti-
zionalità per convertire un indirizzo di tuirà una classe LatLongInfo che contiene

42 VBJ N. 71 - Settembre/Ottobre
VB6

Listato 2 Utilizzo di Geocoder per ricavare latitudine/longitudine di un mappointsdk/HTML/P_Na-


indirizzo mespace_FindAddressSpeci-
fication_ataSourceName.asp)
Public Function AddressToLatLongGeocoder(ByVal address As String) _ è impostato a MapPoint.NA,
As LatLongInfo ad indicare che verrà effet-
Dim wc As New WebClient
tuata una ricerca in Nord
Dim geocodeStream As Stream = _
wc.OpenRead(“http://geocoder.us/service/rest?address=” _ America.
& address) Infine, avviene l’invocazione
Dim xr As New XmlTextReader(geocodeStream) a FindAddress [7]. Ciò resti-
tuisce un oggetto FindResult
Try
Dim ll As New LatLongInfo
(http://msdn.microsoft.com/
While xr.Read() library/en-us/mappointsdk/
If xr.Name = “geo:lat” Then HTML/T_Namespace_
ll.Lat = CDbl(xr.ReadInnerXml)
End If FindResult.asp) che contiene
If xr.Name = “geo:long” Then le informazioni sulla latitu-
ll.Long = CDbl(xr.ReadInnerXml)
End If dine e longitudine. Queste
End While informazioni vengono poi
wc.Dispose()
copiate nella classe custom
Return ll LatLongInfo e restituite.
Catch
Return Nothing
End Try Una vista… dall’aldilà
Adesso che si conosce la
End Function
latitudine e la longitudi-
ne dell’indirizzo richiesto,
la latitudine e la longitudine della strada TerraServer può restituire un’immagine
richiesta. satellitare di questa locazione geografica.
Ho anche accennato che si potrebbe utiliz- L’immagine è fornita come insieme di sot-
zare il web service MapPoint per ottenere toimmagini che è necessario “ricucire” per
latitudine/longitudine di un indirizzo. In ottenere l’immagine complessiva. Il codice
tal caso il codice è ancor più semplice del- per farlo è fornito sul sito Web TerraServer
l’utilizzo di Geocoder (Listato 3). [8]. Pertanto, ho utilizzato questo codice
Le primissime righe di questa funzione e l’ho convertito in Visual Basic .NET. Il
servono semplicemente ad impostare lo codice inizia calcolando semplicemente la
user ID e la password in modo che ven- larghezza e l’altezza in pixel dell’immagine
gano inviate al web service MapPoint. Per desiderata (Listato 4).
effettuare un’invocazione al web service
MapPoint, è necessario che sia già stato Visual Basic .NET contiene alcune funzio-
creato un account. Senza un account, vo- ni di supporto che facilitano la conversione
lendo utilizzare MapPoint invece di Geo- dei twip utilizzati da Visual Basic 6 in pixel
coder, basta registrarsi all’indirizzo https: standard. Ciò permette all’applicazione
//mappoint-css.partners.extranet.microsoft Visual Basic 6 di passare l’altezza e la
.com/MwsSignup/Eval.aspx. larghezza del controllo Image come twip,
Il codice crea poi un oggetto Address Map- e il codice Visual Basic .NET è in grado di
Point e lo popola con l’indirizzo fornito dal- calcolare le dimensioni in pixel in modo
l’utente. MapPoint dispone di diverse fonti che possa invocare il servizio TerraServer
di dati [6] per il Nord America, l’Europa, e e ottenere correttamente l’immagine.
via dicendo, e pertanto FindAddressSpeci- Successivamente, il codice invoca TerraServer
fication.DataSourceName_(/library/en-us/ con le dimensioni dell’immagine, e TerraSer-

N. 71 - Settembre/Ottobre VBJ 43
VB6

Listato 3 Geocodifica di un indirizzo utilizzando il Web service Map- la foto satellitare:


Point
Dim pf As PixelFormat = PixelFormat.

Public Function AddressToLatLongMapPoint(ByVal address As String, _ Format32bppRgb


ByVal username As String, ByVal password As String) As Dim compositeImage As Bitmap = New
LatLongInfo
Bitmap(mapWidth, mapHeight, pf)
Dim fs As New MapPoint.FindServiceSoap Dim compositeGraphics As Graphics =
fs.Credentials = New System.Net.NetworkCredential(username, Graphics.FromImage(compositeImage)
password)
fs.PreAuthenticate = True
A questo punto, ciascuna sot-
Dim addressInfo As New MapPoint.Address
addressInfo.FormattedAddress = address
toimmagine può essere scari-
Dim fas As New MapPoint.FindAddressSpecification cata e disegnata per formare
fas.InputAddress = addressInfo l’immagine composita (Li-
fas.DataSourceName = “MapPoint.NA”
stato 5). Nel listato, ciascuna
Dim results As MapPoint.FindResults = fs.FindAddress(fas) sottoimmagine viene scarica-
Dim ll As New LatLongInfo ta e disegnata nell’immagine
If results.Results.Length = 0 Then composita nella posizione
Return Nothing
Else
corretta. Al termine del ciclo,
With results.Results(0).FoundLocation.LatLong l’intera foto da satellite del-
ll.Lat = .Latitude l’area richiesta sarà scaricata,
ll.Long = .Longitude
End With e l’oggetto compositeImage
End If conterrà l’immagine comple-
Return ll
End Function ta. La sola cosa che resta da
fare è restituire questa imma-
gine in modo che possa esse-
ver restituisce un elenco di ID delle sottoim- re assegnata a un controllo Visual Basic 6
magini dell’area che si vuole visualizzare: Image o PictureBox.
Devo ammettere che la sola parte di questa
Dim ts As New TerraService applicazione che mi ha preoccupato è stata
Dim abb As AreaBoundingBox = ts.GetAreaFromPt(center, _ la restituzione dell’immagine a Visual Basic
theme, scale, mapWidth, mapHeight) 6. Ero conscio del fatto che la classe Bitmap

AreaBoundingBox contiene un
Listato 4 Calcolo delle dimensioni dell’immagine in Visual Basic
elenco di tutte le sottoimmagi- .NET
ni che sarà necessario scarica-
re per poter creare l’immagine
Public Function DownloadSatteliteImage(ByVal latLong As LatLongInfo, _
completa dell’area richiesta. ByVal scale As Integer, _
Man mano che ciascuna sot- ByVal widthTwips As Double, _
toimmagine viene scaricata, ByVal heightTwips As Double) As Object

verrà disegnata in un oggetto Dim center As New LonLatPt


Bitmap del .NET Framework, Dim theme As Integer
Dim mapWidth As Integer
che infine conterrà l’immagi- Dim mapHeight As Integer
ne completa. La classe Bitmap
center.Lon = latLong.Long
[9] rende sorprendentemente center.Lat = latLong.Lat
agevole disegnare e interagi- theme = 1
re con la grafica. Il seguente mapWidth = Compatibility.VB6.TwipsToPixelsX(widthTwips)
mapHeight = Compatibility.VB6.TwipsToPixelsY(heightTwips)
listato permette di creare un ...
oggetto Bitmap per contenere

44 VBJ N. 71 - Settembre/Ottobre
VB6

.NET e i controlli Listato 5 Download di ciascuna sottoimmagine e aggiunta all’immagine composita


Image Visual Basic
6 non fossero diret-
tamente compatibili, Dim xStart As Integer = abb.NorthWest.TileMeta.Id.X
e ritenevo che la Dim yStart As Integer = abb.NorthWest.TileMeta.Id.Y
For x As Integer = xStart To abb.NorthEast.TileMeta.Id.X
conversione della
For y As Integer = yStart To abb.SouthWest.TileMeta.Id.Y Step -1
Bitmap in qualcosa Dim tid As TileId = abb.NorthWest.TileMeta.Id
che Visual Basic 6 tid.X = x
tid.Y = y
potesse utilizzare Dim tileImage As Image = Image.FromStream( _
fosse qualcosa di New MemoryStream(ts.GetTile(tid)))
compositeGraphics.DrawImage(tileImage, _
non facile. Ho tra- (x - xStart) * tileImage.Width - _
scorso del tempo a CInt(abb.NorthWest.Offset.XOffset), _
cercare delle rispo- (yStart - y) * tileImage.Height - _
CInt(abb.NorthWest.Offset.YOffset), _
ste con Google, cer- tileImage.Width, tileImage.Height)
cando invocazioni tileImage.Dispose()
Next
alle API Win32 o Next
librerie che fossero
state già scritte. Ma
infine, giusto per essere certo che non stavo Visual Basic .NET si occupa dell’invocazione
controllando nel posto più ovvio, ho dato a TerraServer e della composizione dell’im-
un’occhiata all’oggetto Microsoft.VisualBas magine completa (Figura 2). L’immagine
ic.Compatibility.VB6 di .NET. Si tratta dello viene restituita, e può essere semplicemente
stesso oggetto che ci ha fornito la conversione assegnata alla proprietà Picture del controllo
da twip a pixel. Com’era prevedibile, è dota- Image Visual Basic 6.
to di un metodo ImageToIPictureDisp. La
proprietà Picture dei controlli Image e Pic- Conclusioni
tureBox è un IPictureDisp, pertanto questo Realizzare questa applicazione solo con Visual
metodo ha consentito la conversione con una Basic 6 sarebbe stato realmente arduo. Per
riga di codice: scaricare una pagina Web, avrei dovuto utiliz-
zare un controllo Web browser, e poi estrarre
Return Compatibility.VB6.ImageToIPictureDisp le informazioni dal documento. Si tratterebbe
(compositeImage) di un suicidio in confronto alle semplici classi
che il .NET Framework fornisce per questo
Da Visual Basic 6, si può invocare il metodo compito. Per poter invocare i web service sa-
DownloadSatelliteImage, passare la coppia rebbe stato necessario il Web Services Toolkit,
latitudine/longitudine e la dimensione del con- lasciandomi l’onere di gestire un bel po’ di
trollo immagine, e ottenere una foto satellitare XML grezzo. E non saprei come avrei dovuto
delle dimensioni corrette (Listato 6). decodificare le sottoimmagini codificate in
Si può vedere che
basta invocare
Listato 6 Invocazione di DownloadSatelliteImage da Visual Basic 6
DownloadSatel-
liteImage, pas-
sando latitudine/
longitudine, la scala Dim msw As MapServiceWrapper.SatImageService
Set msw = New MapServiceWrapper.SatImageService
(quanto si vuole sia Dim satImage As Object
ingrandita l’imma- Set satImage = msw.DownloadSatteliteImage(latLong, hscrScale.Value, _
imgSatPhoto.Width, imgSatPhoto.Height)
gine), e l’altezza e la Set imgSatPhoto.Picture = satImage
larghezza. Il codice

N. 71 - Settembre/Ottobre VBJ 45
VB6

Figura 2 Immagine scaricata e visualizzata in un’applicazione Visual Basic 6

Base64 o come ricucirle assieme. [2]_http://msdn.microsoft.com/library/en-


Tuttavia, estendendo Visual Basic 6 con us/dnxpwst2/html/odc_CmplxTypes.asp
Visual Basic .NET, il tutto è stato real- [3]_https://mappoint-css.partners.extranet.
mente agevole da realizzare. Mi auguro microsoft.com/MwsSignup/Eval.aspx
che l’articolo abbia illustrato chiaramente [4]_http://msdn.microsoft.com/library/en-
come si può prendere un’applicazione esi- us/cpref/html/frlrfSystemNetWebClientCl
stente Visual Basic 6, per poi estenderla assTopic.asp
con Visual Basic .NET per poter ottenere [5]_http://msdn.microsoft.com/library/en-
informazioni in realtime dai web service. us/cpref/html/frlrfSystemXmlXmlTextRea
I web service potrebbero essere ospitati derClassTopic.asp
nella propria azienda per esporre i sistemi [6]_http://msdn.microsoft.com/library/
backend, o possono esistere sul Web: ad default.asp?url=/library/en-us/
esempio, Google, eBay, Amazon o Map- mappointsdk/HTML/index.asp
Point. Esistono web service che espongono [7]_http://msdn.micorosft.com /library/en-
quotazioni di titoli finanziari, informazioni us/mappointsdk/HTML/M_Namespace_
metereologiche, e quasi qualsiasi altro tipo FindServiceSoap_FindAddress.asp
di dati. E, con la combinazione di Visual [8] http://terraserver.microsoft.com/about.a
Basic 6 e di Visual Basic .NET, sono tutti spx?n=AboutTerraServiceExampleMap
servizi a propria disposizione. [9]_http://msdn.microsoft.com/library/en-
us/cpref/html/frlrfSystemDrawingBitmap
Riferimenti ClassTopic.asp
[1]_http://www.microsoft.com/downloads/de [10]_http://download.microsoft.com/download/
tails.aspx?FamilyId=4922060F-002A-4F5B- 8/0/a/80a8307c-ece6-4f4d-94c9-ceeaae586ca4/
AF74-978F2CD6C798&displaylang=en VisualBasic6WebServices.wmv)

46 VBJ N. 71 - Settembre/Ottobre
OFFICE

La programmazione
di Office tramite
VSTO
In questo articolo vedremo come creare applicazioni in am-
biente Office utilizzando la tecnologia .NET

VSTO
di Emanuele Mattei

M
icrosoft Office è un pacchetto che mare per i prodotti Word ed
comprende diverse applicazioni, mol- Excel; inoltre tramite alcuni
to usate in ambito aziendale e perso- componenti aggiuntivi che
nale; quelle di più frequente utilizzo sono Word, si trovano sugli appositi cd,
Excel, Access e Outlook. Il pacchetto Office si può abilitare tale ambiente
offre altri prodotti, quali Power Point, Infopath, di sviluppo anche per la pro-
FrontPage, Visio e Project. Quando si ha l’esi- grammazione di Outlook e
genza di utilizzare un determinato applicativo Infopath. Prima di procedere
con funzionalità avanzate, è possibile persona- all’installazione dell’ambien-
lizzarlo utilizzando il linguaggio Visual Basic te di sviluppo VSTO, bisogna
for Application (VBA). L’uscita di Visual Studio installare le Primary Interop
2005, in particolare con la versione Visual Stu- Assemblies (pias), che per-
dio Tools for Office (VSTO), ha messo in grado di mettono di rendere possibile
programmare i prodotti Office con la tecnologia la programmazione .NET per
.NET, superando quei limiti che VBA (che conti- il pacchetto Office. Tali com-
nua a rimanere) poneva all’utente. ponenti si possono installare
durante l’installazione di
Installazione Microsoft Office oppure mo-
Microsoft Visual Studio 2005 comprende di- dificandone le impostazioni
verse versioni, quella dedicata allo sviluppo di installazione: in quest’ul-
di applicazioni per Office si chiama Visual timo caso bisogna scegliere
Studio Tools for Office e permette di program- la voce aggiungi/rimuovi del
programma Office, situato
nella finestra di installazio-
ne applicazioni del pannello
Emanuele Mattei è sviluppatore presso una società d’infor- di controllo. Nelle opzioni
matica di Roma. Attualmente collabora con altri webmaster di Office, bisogna eseguire
al sito www.shareoffice.it il primo usergroup italiano dedicato
alla programmazione di Office, tramite la tecnologia .NET. l’installazione completa per
alcune voci, tramite il menu

48 VBJ N. 71 - Settembre/Ottobre 2006


OFFICE

proprio interesse, si ha la
possibilità di scegliere il
tipo di progetto, ossia se in
ambiente Windows, Mobile
ed Office. Selezionato il
tipo di progetto, nella parte
destra (quella indicante i
modelli) verranno riportati
i vari progetti che si posso-
no creare: Word, Excel ed
eventualmente anche per
Outlook o Infopath, qualo-
ra si sia scelto di installare
anche questi componenti.
Selezionando il modello
“Documento Word” verrà
aperta una finestra (Fi-
Figura 1 Finestra per l’aggiunta delle programmazione (pias) di Office gura 4), che ci chiede se
vogliamo creare un nuovo
documento o utilizzare uno
di scelta rapida dell’elemento seleziona- esistente; selezioniamo nuovo documento
to. A tal proposito occorre impostare tale e digitiamo il pulsante Ok. A video po-
scelta alle voci “Supporto per la program- trebbe essere visualizzato un messaggio,
mabilità .NET per Microsoft Form 2.0” come mostrato nella Figura 5, qualora le
e “Supporto programmabilità .NET per impostazioni delle protezioni macro siano
Smart Tag” situate alla voce Strumenti ad un livello medio-alto.
di Office, come mostrato in Figura 1. Come si vede nella Figura 6, l’ambiente di
Stessa operazione anche
per Word, selezionando la
voce “Supporto per la pro-
grammabilità .NET.” come
mostrato nella Figura 2.

Prima applicazione
Dopo aver installato il
tutto, si può procedere
alla creazione della prima
applicazione .NET per Of-
fice. Si apra Visual Studio
2005; dopo aver selezio-
nato Nuovo Progetto dal
menu File, viene aperta
una finestra (Figura 3) la
quale ci permette di sce-
gliere il linguaggio che
vogliamo utilizzare; dopo Figura 2 Finestra per aggiungere la possibilità di programmare gli smart tag
aver selezionato il linguag-
gio di programmazione di

N. 71 - Settembre/Ottobre 2006 VBJ 49


OFFICE

Figura 3 Scelta del progetto in Visual Studio 2005

sviluppo è un ibrido tra quello di Visual troverà familiare la programmazione per


Studio 2005 ed un documento Word, que- Office, in quanto molti controlli che si tro-
sto per dare la possibilità al programmato- vano in ambiente Windows sono compresi
re di avere una visione reale di ciò che sta anche in quello Office, situati nella barra
programmando. degli strumenti.
Chi programma in ambiente Windows Trasciniamo un pulsante sul foglio, e nel-
l’evento click scriviamo il
frammento di codice ripor-
tato di seguito

MsgBox(“ciao a tutti”,
MsgBoxStyle.Information, “testo”)

A questo punto, per poter


eseguire il progetto baste-
rà fare click sul tasto F5 o
andare nel menu Debug e
selezionare la voce Avvia
Debug.

Modifica del riquadro


attività
Di seguito viene illustrata
la procedura per creare
Figura 4 Finestra che indica se creare un nuovo documento o utilizzare uno
un riquadro attività per-
esistente sonalizzato, il quale avrà
il compito di inserire nel

50 VBJ N. 71 - Settembre/Ottobre 2006


OFFICE

situati nella barra degli


strumenti. Inseriamo un
controllo di tipo MonthCa-
lendar ed un pulsante; in
questo modo, dopo che
l’utente avrà selezionato
una data tramite il pul-
Figura 5 Messaggio informativo sulla protezione delle macro sante inserisci, nel docu-
mento Word verrà inserita
tale data nel punto in cui
documento una data selezionata da un si trova il cursore.
apposito calendario. Il riquadro attività è
quel pannello che si trova nella parte de-
stra di ogni programma Microsoft Office
2003, nel quale si trovano informazioni L’oggetto word.selection
aggiuntive o complementari di un deter-
minato comando. permette di gestire le
Per aggiungere un nuovo riquadro atti- impostazioni del documen-
vità da codice, selezioniamo la voce di
menu Aggiungi nuovo elemento, situato
to di testo
nel menu Progetto; a questo punto verrà
aperta una finestra (Figura 7) e in essa
selezioniamo il modello con la dicitura
“Controllo riquadro azioni”. Verrà ag- L’oggetto word.selection permette di gesti-
giunto al progetto un nuovo controllo, o re le impostazioni del documento di testo,
meglio un user control, in cui si possono quali testo, tabelle, formattazioni ed altro
inserire altri controlli, per esempio quelli ancora; la proprietà text imposta o resti-

Figura 6 L’ambiente per lo sviluppo di Office

N. 71 - Settembre/Ottobre 2006 VBJ 51


OFFICE

tuisce il testo richiesto. dell’oggetto Me, il controllo inserito nel


Nell’evento click del pulsante inseriamo progetto.
il seguente frammento di codice, il qua- Il codice deve essere simile a quello ripor-
le imposta nel documento Word in cui si tato qui di seguito:
trova il cursore, la data selezionata nel
calendario Me.ActionsPane.Controls.Add(New ActionsPaneControl1)

Dim selezione As Word.Selection = Globals.ThisDocument.


Application.Selection Conclusioni
selezione.Text = MonthCalendar1.SelectionEnd In questo articolo introduttivo abbiamo
visto come in Visual Studio 2005 si pos-
sono creare applicazione in ambiente Mi-
crosoft Office; tale ambiente di sviluppo
ci permette di creare applicazioni con più
In Visual Studio 2005 si semplicità e velocità. Nel prossimo artico-
possono creare applicazio- lo vedremo come creare uno Smart Tag.
Sul sito ftp di Infomedia (ftp.infomedia.it/
ne in ambiente Microsoft pub/) trovate il codice sorgente dell’appli-
Office cazione.

Bibliografia
[1] Sito della home page della Msdn per lo
sviluppo di Visual Studio Tools for Office
Per aggiungere tale controllo nell’evento http://msdn.microsoft.com/office/tool/
startup del documento Word dobbiamo vsto/default.aspx
aggiungere alla proprietà ActionsPanel

Figura 7 Finestra per l’aggiunta di un nuovo riquadro attività

52 VBJ N. 71 - Settembre/Ottobre 2006


Prodotti News
Potete inviare i vostri comunicati stampa all’indirizzo:
comunicatistampa@infomedia.it

3CX Centralino Telefonico te interurbane e tra uffici. di portale self-service e di accesso


per Windows, edizione * Niente più costosi telefoni di siste- basato sul Web di Softricity Zero-
GRATUITA ma proprietari: utilizzo di telefoni Touch. Inoltre, i clienti Microsoft
con standard SIP che utilizzano Systems Management
3CX, una nuova società che sviluppa * Eliminazione del circuito telefoni- Server (SMS) 2003 possono scaricare
IP PBX basati su software, ha rila- co e semplificazione del trasloco gratuitamente il connettore SMS di
sciato la prima versione del proprio di uffici. Softricity. Per il supporto gli attuali
prodotto IP PBX, il Centralino Tele- clienti di Softricity potranno conti-
fonico 3CX per Windows, edizione http://www.3cx.it/centralino/ nuare a rivolgersi ai team abituali e
gratuita. product-tour.php partner dei servizi e delle vendite.
Il Centralino Telefonico 3CX libera le L’edizione gratuita è scaricabile dal Microsoft fornirà successivamente
aziende dagli elevati costi di acqui- sito http://www.3cx.it/ip-pbx/free- ulteriori dettagli sulla distribuzione
sto e gestione di centralini (o PBX) edition.html. dei prodotti Softricity che supporta-
proprietari. Centralino Telefonico no Windows Vista e Windows Server
3CX si basa sullo standard aperto “Longhorn”.
SIP (Session Initial Protocol); di Microsoft completa l’ac- In Italia Softricity SoftGrid è di-
conseguenza, funziona con qualsiasi quisizione di Softricity stribuito da Ready Informatica
gateway o telefono basato su SIP. In (www.ready.it) che ha iniziato la
questo modo, si elimina l’esigenza di L’acquisizione di Softricity consente diffusione nel 2003. Oggi si contano
telefoni di sistema proprietari ed il ai clienti Microsoft di ridurre i costo- più di 50 clienti e più di 4000 licenze
know-how d’installazione e gestione si processi di gestione delle applica- installate sul territorio italiano. Inol-
specializzate. zioni, velocizzare la distribuzione dei tre sono già presenti 10 integratori
Centralino Telefonico 3CX per Win- sistemi operativi e delle applicazioni certificati, capaci di supportare il
dows è un IP PBX che sostituisce del e creare una base per un’infrastrut- cliente dallo studio di fattibilità fino
tutto un centralino proprietario, tura di servizi software. La tecnolo- alla messa in opera del progetto.
supporta telefoni software e hard- gia di virtualizzazione di Softricity Ready Informatica è anche l’unico
ware con standard SIP, servizi VOIP può contribuire a ridurre in modo training center ufficiale Softricity
e linee telefoniche PSTN. Centralino significativo la quantità di test di SoftGrid (www.readyeducation.it).
Telefonico 3CX è molto meno co- compatibilità delle applicazioni, Maggiori informazioni su Softricity
stoso di un centralino tradizionale che vengono gestite centralmente SoftGrid sono disponibili sul sito
ed è in grado di ridurre i costi delle e inviate direttamente al desktop www.softricity.it.
chiamate in modo marcato, grazie dell’utente in un’immagine isolata e
all’utilizzo di provider di servizi VOIP. virtualizzata, riducendo al minimo le
La sua amministrazione basata su alterazioni al sistema operativo. Il 2D di Solid Edge gratis
web semplifica la gestione del siste- Grazie all’integrazione con la funzio- per tutti
ma telefonico. Centralino Telefonico nalità di streaming del software di
3CX elimina il circuito telefonico di Softricity, le applicazioni virtualizza- UGS, leader mondiale nella fornitura
rete e consente agli utenti di “con- te possono essere inviate in rete in di soluzioni e servizi per la gestione
dividere l’ufficio” semplicemente modo dinamico e su richiesta. Que- del ciclo di vita del prodotto (PLM),
rispondendo al telefono. sto approccio offre l’opportunità annuncia che
di usufruire di un servizio software Solid Edge® 2D Drafting, il software
Caratteristiche principali: gestito centralmente, nel quale le per la progettazione 2D (prece-
applicazioni siano disponibili su ri- dentemente a listino a più di 1.000
*_Sistema telefonico completo: chiesta e facilmente aggiornabili. euro) è a disposizione gratuitamente
fornisce la commutazione, lo smi- Conclusa l’acquisizione, Softricity è all¹indirizzo www.solidedge.com/
stamento e la messa in coda delle diventata una società interamente free2d. La decisione indica che il
chiamate posseduta da Microsoft ed ha già mercato considera ormai il software
* Costo di acquisto notevolmente iniziato l’integrazione delle proprie 2D una commodity e sottolinea il
inferiore a quello di un apparec- tecnologie nei processi di enginee- valore della modellazione gestita in
chio PBX tradizionale ring e di distribuzione del software 3D. Il software 2D è scaricabile gra-
* Scalabilità: numeri diretti e linee Microsoft. Microsoft, anche in tuitamente e non prevede l¹acquisto
telefoniche illimitate. Non sono Italia, ha rilasciato la piattaforma di licenze, mentre verranno forniti a
richiesti moduli di espansione di virtualizzazione delle applicazio- pagamento eventuali servizi di assi-
proprietari. ni SoftGrid ad un prezzo ridotto. stenza e aggiornamento automatico
* Configurazione e indicatore di sta- Vengono offerti due prodotti core: del software.
to basati sul web: facile gestione SoftGrid for Desktops e SoftGrid Solid Edge è il componente CAD del-
del sistema telefonico. for Terminal Services. Entrambi i la nuova suite UGS Velocity Series_.
* Riduzione dei costi delle telefona- prodotti includono la funzionalità Solid Edge 2D Drafting fornisce una

54 VBJ N. 71 - Settembre/Ottobre 2006


Prodotti News

serie di strumenti collaudati per versione 2.0 per il sistema HASP, la richiede alcuna modifica al codice sor-
disegnare. Il pacchetto integra co- soluzione dedicata alla protezione, gente, è la soluzione ideale anche per
mandi di disegno, funzionalità per la licenziamento e distribuzione sicura distributori e rivenditori che vogliono
generazione di schemi, annotazioni del software. proteggere software. Alcuni dei van-
e quotatura, che rispettano auto- Grazie all’introduzione di questa taggi offerti da Envelope:
maticamente gli standard di disegno funzionalità, HASP di Aladdin è in
meccanico selezionati, fra cui ISO, grado di proteggere automatica- • Protezione del software dall’uso
ANSI, BSI, DIN, JIS e UNI. Inoltre il mente e con un elevato livello di non autorizzato vincolandolo alla
software mette a disposizione assi- sicurezza applicazioni basate su .NET presenza della chiave HASP
stenti intuitivi (wizard) per la conver Framework 2.0, sfruttando soluzioni • Protezione da reverse engineering
tecnologiche innovative come sicu- grazie alla crittografia dei file
rezza multi-livello e misure contro
• Protezione dall’analisi del codice
La soluzione HASP di Alad- il debug ed il reverse engineering.
con l’introduzione di sofisticate
din supporta Microsoft Clienti HASP che sviluppano su
misure anti-debugging
.NET Framework 2.0 piattaforma .NET Framework 2.0 ora
possono avvalersi delle avanzate mi- • Utilizzo di diversi livelli di pro-
Techne Security, distributore ita- sure anti-hacking che caratterizzano tezione random per impedire
liano dei prodotti Aladdin Know- le soluzioni Aladdin. l’hacking dell’eseguibile.
ledge Systems (NASDAQ: ALDN), D’ora in avanti gli sviluppatori saranno
annuncia che la società Israeliana, in grado di proteggere nel giro di pochi Techne Security S.r.l.
leader nelle soluzioni DRM, strong minuti applicazioni .NET Framework Via Monte Sabotino, 69 – 41100
authentication e di content security, 2.0, che vengono letteralmente “rac- Modena Italy
ha presentato il supporto dell’archi- chiuse” in un ambiente pressocché Tel: +39 059 415608; Fax: +39 059
tettura Microsoft .NET Framework impenetrabile. Poiché Envelope non 415630

N. 71 - Settembre/Ottobre 2006 VBJ 55


Prodotti News

sono adesso anche legalmente vin- sempre più grave per gli utenti che
GFI EventsManager scopre colate a conservare ed esaminare effettuano transazioni in rete. Secon-
cosa sta effettivamente attivamente i loro log di eventi do la decima edizione dell’Internet
accadendo sulla propria nell’ambito della loro gestione or- Security Threat Report, analisi seme-
rete dinaria. La conservazione di archivi strale condotta da Symantec sulla si-
protetti di eventi nel loro formato curezza in rete, nei primi sei mesi del
GFI, sviluppatore internazionale originario si 2006, 30 dei 50 principali campioni
leader di software di protezione rivela essenziale quando si devono di codici maligni erano in grado di
della rete, sicurezza del contenuto fornire le prove di conformità a esporre i dati riservati dell’utente.
e messaggistica, ha lanciato oggi GFI leggi e normative. Norton Confidential è l’unico
EventsManager, la sua soluzione di prodotto per la sicurezza delle
prossima generazione per la ge- <http://www.gfi-italia.com/http: transazioni online che racchiude
stione e il reporting centralizzati //www.gfi-italia.com/. in un’unica soluzione tecnologie
dei log di eventi. L’ultima release antiphishing e anticrimeware. Nor-
di GFI fornisce un’idea di quanto ton Confidential non solo avvisa gli
accade nella struttura informatica Symantec presenta Nor- utenti impedendo loro di visitare i
e garantisce il massimo tempo di ton Confidential, la prima siti di phishing ma, grazie alla tec-
operatività della rete: funge da si- soluzione per la sicurezza nologia anticrimeware, è anche in
stema di avvertimento precoce per delle transazioni online grado d’impedire gli attacchi dei
tutti i potenziali errori hardware e software di eavesdropping.
software, al contempo, controllan- Symantec Corp. ha annunciato la Le principali funzionalità di Norton
do e avvisando l’utente in merito a disponibilità di Norton Confiden- Confidential comprendono:
possibili violazioni di sicurezza. GFI tial, la prima soluzione completa
EventsManager è stato inoltre svi- per la sicurezza delle transazioni • Protezione dal phishing – Avvisa o
luppato per soddisfare le crescenti online. Norton Confidential fornisce impedisce all’utente di visitare siti
richieste di conformità dei all’utente un livello di protezione di phishing noti o sospetti.
log di eventi a leggi e normative. altissimo contro gli strumenti più • Autenticazione dei siti – Confer-
GFI EventsManager è una soluzio- pericolosi utilizzati dagli hacker: siti ma l’autenticità dei più famosi siti
ne di gestione dei log di eventi di phishing fraudolenti e crimeware di shopping, banking o altro che
orientata ai risultati, che si integra eavesdropping, capaci cioè sottrar- richiedono l’inserimento di dati
in qualsiasi infrastruttura informa- re i dati digitati o presenti sulla finanziari o di altri dati personali.
tica esistente. Raccoglie in modo schermata quando si effettua una
• Protezione del crimeware – Pro-
automatico i dati degli eventi da transazione online. Per una sicurezza
tegge l’utente dal crimeware noto
tutti i componenti della rete, li ancora più efficace delle transazioni
o sconosciuto nei momenti di
standardizza in un database centrale online, Norton Confidential intensi-
maggiore rischio, ovvero prima di
e fornisce rapporti utili sulle conclu- fica la protezione nei momenti di
effettuare una transazione online.
sioni raggiunte. Grazie alla continua maggiore rischio, ovvero quando
attività di monitoraggio e avvisi, GFI l’utente inizia a inserire i propri dati • Sicurezza delle password – Pro-
EventsManager conferisce all’am- personali sensibili, come password e tegge e gestisce i dati di login e le
ministratore maggiore potere di numeri di conto, fornendo inoltre password.
prevenzione dei disastri della rete, chiari indicatori visivi che permet- • Blocco delle password – Blocca
attraverso la tono all’utente di sapere quando le credenziali di login impedendo
notifica di attività illecite o di possi- può compiere transazioni online in l’accesso ai siti non autorizzati
bili errori hardware e software rela- maniera sicura. senza l’approvazione dell’utente.
tivi alla loro rete, grazie a informa- Secondo quanto emerso da uno
zioni quali: i software che vengono studio di Harris Interactive commis- Norton Confidential sarà disponi-
installati o disinstallati, lo stato di sionato da Symantec in ottobre 2005, bile al pubblico da novembre 2006
salute di Microsoft Exchange ed altri il 71% degli utenti dichiara di sentirsi presso lo store online di Symantec
server, gli utenti che accedono a file “a disagio” nel fornire dati personali www.symantecstore.com e rivendi-
contenenti dati sensibili, le attività di online, mentre il 53% afferma di esse- tori e distributori online. Il prezzo al
login e molto altro. re “molto preoccupato” per il furto pubblico consigliato di Norton Con-
Gestori informatici con maggiore d’identità online. Vi sono quindi ot- fidential è di circa 50 euro, che com-
esperienza sanno che i dati conte- timi motivi per prendere precauzioni prendono un anno di abbonamento
nuti nei log di eventi rappresentano quando si tratta di sicurezza online. al servizio, gli update alla sicurezza
la loro risorsa più preziosa quando si Il crimeware, una serie di strumenti grazie a Symantec LiveUpdate e le
tratta di esaminare errori di sistema di malware mirati al furto di dati e nuove funzionalità del prodotto non
e violazioni di sicurezza. Le aziende d’identità, costituisce una minaccia appena disponibili.

56 VBJ N. 71 - Settembre/Ottobre 2006


Prodotti News

intuitiva che rende gli Snap Ser- di beneficiare della comunicazio-


Adaptec Snap Server 410 ver 110, 210 e 410 semplici da ne visiva basata su PC ovunque
semplifica lo storage con- installare, configurare e manu- e in qualunque momento senza
diviso tenere. Filiali e uffici remoti che prendere un appuntamento con il
non dispongono di personale dipartimento informatico.
Adaptec, fornitore globale di so- tecnico possono implementare Movi è un’applicazione video ser-
luzioni storage, ha lanciato Snap e gestire autonomamente questi ver-based per il mercato enterpri-
Server 410, il prodotto che com- server, assicurando che i dati se che ridefinisce la facilità d’uso.
pleta la famiglia di soluzioni NAS siano protetti a prescindere da Con una sola semplice operazione
(network attached storage) indiriz- dove risiedano. gli utenti possono lanciare video-
zate alle piccole e medie imprese. • Protezione e gestione dati avan- chiamate in tre modi: ciccando su
Il prodotto è disponibile in 3 di- zate e personalizzate – In base un invito a un meeting, su un link
verse configurazioni – con capacità ai budget IT e alle esigenze di permanente sull’intranet aziendale
da 640GB, 1TB e 2TB – e sfrutta storage, le aziende possono sce- oppure su un indirizzo della rubri-
il potente sistema operativo Guar- gliere lo specifico software op- ca Movi. Tutto ciò che serve è una
dianOS, lo stesso utilizzato per zionale di cui hanno bisogno per webcam, un microfono, speaker e
la linea di Snap Server di fascia trasferire, gestire e proteggere un PC con connessione Internet.
midrange. i dati aziendali. Il software di- Movi fa tutto il resto, mettendo in
Semplice da installare e manutene- sponibile comprende accesso ai comunicazione gli utenti in video
re, Snap Server 410 è stato ideato dati block-level (tramite iSCSI), nella finestra Movi.
per essere utilizzato in ambienti antivirus CA eTrust e il software La soluzione Movi permette ai di-
che non dispongono di risorse tec- di backup NetVault e di BakBone pendenti di comunicare in maniera
niche. La famiglia di Snap Server per l’archiviazione disk-to-disk visiva con i propri colleghi per au-
di Adaptec, che oltre al prodotto o disk-to-disk-to-tape (D2D & mentare la produttività - ovunque
presentato oggi comprende gli D2D2T). essi si trovino. Il personale non
Snap Server 110, 210, 520, 550 e deve più affidarsi unicamente al
i JBOD S50, rappresenta la prima Snap Server 410 da 640GB è già telefono per riunioni importanti o
linea di soluzioni NAS per le PMI disponibile a un prezzo suggerito sentirsi ‘isolato’ se lavora da casa
in grado di offrire unified block di 1749 euro, IVA esclusa. Le con- o dall’estero. La collaborazione
(tramite iSCSI) e supporto file nel- figurazione da 1TB e 2TB, disponi- face-to-face avviene direttamen-
lo stesso dispositivo. Snap Server bili a partire dalla fine dell’anno, te dal PC, facilitando il processo
410 offre funzionalità avanzate, saranno offerte a un prezzo rispet- decisionale, sfruttando l’expertise
comprese applicazioni opzionali tivamente di 2189 e 3069 euro, IVA aziendale e unendo le organizza-
di classe enterprise per la replica esclusa. zioni. Video a portata di un click
dei dati, il backup disk-to-disk e il - uno strumento indispensabile per
disaster recovery. Per maggiori informazioni: la produttività.
Snap Server 410 è offerto in con- www.snapserver.com Movi è il primo prodotto video
figurazione rack con quattro disk PC che offre l’installazione con
drive e interfacce di rete da due un solo tocco e i dipartimenti IT
gigabit. Oltre a RAID 1 e 0, Snap TANDBERG e la videocon- possono gestirlo centralmente via
Server 410 supporta anche RAID 5. ferenza su PC Web. Poiché non richiede l’installa-
zione in locale di software, aggior-
• Piattaforma storage flessibile e Immagina di essere seduto in un namenti, diagnostica e misurazione
multi-purpose – Questi sistemi caffè o in un aeroporto e, con un è molto più semplice di altri stru-
sono le prime soluzioni network semplice click, collaborare in video menti video PC.
storage di questa fascia di prez- dal tuo laptop con un collega dal- Movi è attualmente in fase di test
zo a offrire servizi unified file l’altra parte del mondo. Immagina presso numerosi clienti TANDBERG
& block (tramite iSCSI), nonché ora di essere l’IT administrator che e sarà disponibile nel secondo
supporto multi-protocollo per ha appena collegato l’intera azien- trimestre del 2007. Per ulteriori
NFS, AFP e CIFS. Le aziende pos- da con un video PC senza toccare informazioni visitate il Launch Pad,
sono pertanto ridurre la spesa IT il computer di nessun dipendente. il nuovo sito interattivo che per-
globale grazie alla possibilità di A conferma del proprio impegno mette ai visitatori di esplorare e
archiviare sia file sia dati struttu- nell’innovazione, TANDBERG® fornire pareri su Movi all’indirizzo
rati nello stesso sistema. annuncia Movi, la prima soluzione www.tandberglaunchpad.com.
• Semplicità di utilizzo - Guardia- del suo genere che rende tutto
nOS offre un’interfaccia grafica questo possibile. Permette infatti

58 VBJ N. 71 - Settembre/Ottobre 2006


.NET TOOLS
PHP Obfuscator punto oltre a domandarsi se sia davvero van-
di Raffaele Di Natale taggiosa una simile attività di offuscamento è
necessario utilizzare il tool più vantaggioso.
Un tool open source in C# per offuscare il
codice sviluppato in Php Limitazioni nell’offuscamento
Tutti i tool di offuscamento definiscono regole
La diffusione delle applicazioni web ha più o meno rigide per portare a termine cor-
senz’altro agevolato il compito di distribuzione rettamente il proprio compito. Bisogna ricono-
delle applicazioni stesse, ma, al contempo, ha scere che PHP Obfuscator non solo non eccede
favorito azioni di sciacallaggio nei confronti di in tali richieste, ma l’unica vera limitazione
interi blocchi di codice in linguaggi script. Nel- appare più che legittima. Infatti, il processo di
l’intento di aggirare il problema molte aziende offuscamento ignora tutte le variabili definite
provano ad offuscare opportunamente il codi- nel body della pagina HTML. Per garantire un
ce distribuito, soprattutto in casi particolari, corretto offuscamento, le strade da seguire
quale per esempio quello di una demo. sono principalmente due: non utilizzare tali
Dato un programma A ed un programma B svi- variabili all’interno dello blocco di codice PHP
luppati in un generico linguaggio, si dice che o, in alternativa, includerle nell’elenco delle
B è ottenuto per offuscamento di A se e solo se variabili da non sottoporre ad offuscamento.
il comportamento di A è identico a quello di B
ed inoltre il codice sorgente di B risulta
particolarmente difficile da leggere e da
analizzare.

Offuscare o non offuscare?


L’offuscamento del codice è l’obiettivo
finale, ma la strada può talvolta essere
così tortuosa che il gioco potrebbe anche
non valere la candela. Innanzitutto, biso-
gna dire che l’offuscamento del codice
effettuato in maniera inesatta non solo
potrebbe produrre un’applicazione non
funzionante, ma, cosa ben più grave,
potrebbe generare un’applicazione ap-
parentemente funzionante. Un secondo
problema è rappresentato dal modo in
cui si opera per offuscare il codice: molti
tool di offuscamento prevedono spesso
delle precondizioni tali da richiedere una Figura 1 Componenti di base del tool
modifica del codice originario al fine di
garantirne la corretta codifica. A questo

60 VBJ N. 71 - Settembre/Ottobre 2006


.NET TOOLS

<RemoveWhitespace>true</RemoveWhitespace>
L’applicazione <RenameVariables>true</RenameVariables>
PHP Obfuscator è un tool interamente svilup- <RenameFunctions>true</RenameFunctions>
pato in C#: l’applicazione ed il codice sorgente <TargetDir>C:\Obfuscated</TargetDir>
possono essere scaricati dal sito [1]. Si compo- <SourceDir>C:\Temp</SourceDir>
ne di tre elementi fondamentali: </ObfuscationConfig>

• La GUI; Tra gli elementi del progetto sono presenti


• Il tool a linea di comando; anche SourceDir e TargetDir, che rappresenta-
• La classe Obfuscator. no rispettivamente la directory a partire dalla
quale sono processati i file PHP e la cartella
Come si evince dalla Figura 1, la GUI può inte- di destinazione all’interno della quale saran-
ragire con il tool a linea di comando per mezzo no copiati tutti i file offuscati. La cartella di
di un file di progetto in XML, con estensione destinazione viene eliminata e ricreata ogni
.obxml. La classe Obfuscator è alla base sia volta che si esegue l’offuscamento. Inoltre la
della GUI, sia del tool a linea di comando. Di struttura della cartella finale è il clone di quel-
seguito è fornito un esempio del file di proget- la d’orgine garantendo, in tal modo, un codice
to in cui è facile riconoscere le variabili che offuscato, ma pronto all’uso senza la necessità
sono escluse dal processo di offuscamento. Per di ulteriori interventi sul codice stesso.
modificare tale elenco è possibile agire diret-
tamente su tale file o usufruire dell’apposita MD5 in PHP Obfuscator
funzionalità della GUI. MD5 è un algoritmo crittografico che, dato
un messaggio di arbitraria lunghezza, genera
<?xml version=”1.0”?> un’impronta di 128 bit. PHP Obfuscator uti-
<ObfuscationConfig xmlns:xsi=”http://www.w3.org/2001/XMLSchema- lizza tale algoritmo per codificare. Questo ac-
instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”> corgimento oltre a generare nomi di variabili
<FilesToObfuscate> e di funzioni praticamente illeggibili ad occhio
<string>C:\Temp\Index.php</string> nudo, rende praticamente impossibile risalire
</FilesToObfuscate> al nome iniziale delle variabili e comprender-
<ExcludeVariables> ne quindi il significato all’interno dello script.
<string>$password</string> Per maggiori dettagli visitare [2].
<string>$database</string>
<string>$username</string>
<string>$server</string>
<string>$_SERVER</string> PHP Obfuscator usa l’algo-
ritmo MD5 per offuscare
<string>$HTTP_SERVER_VARS</string>
<string>$_ENV</string>
<string>$_COOKIE</string> variabili e funzioni
<string>$_GET</string>
<string>$_POST</string>
<string>$_FILES</string>
<string>$_REQUEST</string>
<string>$_SESSION</string> Le fasi dell’offuscamento
<string>$GLOBALS</string> PHP Obfuscator effettua l’offuscamento agen-
<string>$this</string> do su variabili, funzioni e spazi vuoti, insieme
<string>$php_errormsg</string> o singolarmente, al fine di ottenere il livello
</ExcludeVariables> di offuscamento desiderato. Tramite la GUI è
<ExcludeFunctions /> possibile infatti settare quale o quali dei tre

N. 71 - Settembre/Ottobre VBJ 61
.NET TOOLS

precedenti aspetti prendere in considerazio- Come si può facilmente notare, sia il nome
ne durante l’offuscamento. In virtù del fatto della variabile, sia il nome della funzione sono
che l’obiettivo rimane sempre quello di avere stati modificati nelle corrispondenti impronte
un’applicazione offuscata equivalente a quella generate dall’algoritmo MD5.
originaria, si consiglia di effettuare l’offusca-
mento per gradi, testando di volta in volta il Conclusioni
risultato finale. Si potrebbe cominciare dalla Molteplici e complesse sono le strade che por-
rimozione degli spazi vuoti, per poi passare al- tano all’offuscamento del codice. In questo ar-
l’offuscamento delle variabili ed infine a quel- ticolo è stato proposta una possibile soluzione
lo delle funzioni. Il processo di offuscamento che, mediante semplici accorgimenti e piccole
avviene in due fasi principali: nella prima sono restrizioni, permette all’utente di codificare
rinominate le variabili, rimossi i commenti e agevolmente il proprio codice PHP. Non è det-
gli spazi bianchi; nella seconda fase sono rino- to che sia la soluzione migliore, ma sicuramen-
minate le classi e le funzioni proprie dell’appli- te non richiede uno stravolgimento del codice
cazione. e comunque consente di aggirare gli ostacoli
che potrebbero presentarsi.
Un esempio
Un semplice esempio di offuscamento può es- Bibliografia e Riferimenti
sere ottenuto applicando PHP Obfuscator ad [1]_http://www.codeproject.com/csharp/php_
un file contenente il seguente codice PHP: obfuscator.asp
[ 2 ] _ h t t p : / / w w w. a m a g r i . i t / C r i t t o l o g i a /
<?php Crittografia/Algoritmi_crittografici/MD5/analisi_
if($functions==”something”) algoritmo.htm
{
print(“<p><h3>Hello VBJ!</h3></p>”);
}
print_footer(); Prodotto
?> PHP Obfuscator
Url di riferimento
Il risultato, che un qualsiasi editor visualizze- http://www.codeproject.com/csharp/php_obfuscator.asp

rebbe in un’unica linea sarebbe: Stato Release


v. 0.1.0.0
<?php Semplicità d’uso ªªªªª
if($R83E53B3209D4446AACD5F8A9B11F3A21==”something”) Si tratta di un tool semplice e molto intuitivo. Dopo qualche test si
è in grado di generare una completa applicazione PHP offuscata.
{
print(“<p><h3>Hello VBJ!</h3></p>”); Utilità ªªªªª
In tutti i casi in cui l’offuscamento del codice si rende necessario
}
per proteggere il proprio lavoro, questa tipologia di tool risulta
F7E969322D1342FC7546AB99B9E690339(); fondamentale, soprattutto, come in questo caso, in cui non è ne-
?> cessario stravolgere il proprio lavoro.
Qualità prodotto ªªªª²
In applicazioni semplici e che rispondono esattamente alle richie-
ste del tool, l’offuscamento avviene senza grossi problemi. In ap-
Le variabili definite plicazioni più complesse gli è capitato di bloccarsi.

nel body della pagina html Qualità documentazione ªªªª²


Pur non essendo disponibile alcun help in linea, la documentazio-
sono ignorate nel ne allegata al progetto (in lingua inglese) spiega perfettamente non
solo i punti di forza del tool, ma anche le limitazioni, anticipando
processo di offuscamento in tal modo eventuali problemi.

62 VBJ N. 71 - Settembre/Ottobre 2006


.NET TOOLS

modo viene creato un file XML per ogni file del


Sandcastle progetto; questi file vengono poi dati “in pasto”
La documentazione professionale a determinate applicazioni che creano la docu-
di Fabio Perrone mentazione con l’ausilio di un compilatore di file
HTML Help. Fino a .NET 1.1 il tool più utilizzato
Il nuovo strumento Microsoft per è stato NDoc, che purtroppo ha chiuso i battenti
documentare il codice e quindi non supporta la versione 2.0 con tutte
le sue sfaccettature (prima tra tutte i Generics).
La documentazione del codice è fondamentale. Per colmare questo gap la Microsoft ha messo a
Punto. Anche se agli “smanettoni” la parola disposizione degli sviluppatori lo strumento gra-
documentare fa rizzare i capelli, in un progetto tuito oggetto della recensione di questo articolo:
software professionale è uno step necessario per al momento della scrittura è a nostra disposizio-
poter riutilizzare il proprio codice e, soprattutto, ne la CTP 2 ed è un tool completamente a riga
per capire effettivamente tutte le sfaccettature di comando; esistono tuttavia delle applicazioni
di un’applicazione complessa. La documenta- gratuite che forniscono il front-end del motore
zione può essere utente o tecnica, e in questa dell’applicazione. Come funziona Sandcastle?
recensione ci soffermeremo sulla creazione di In primo luogo è necessario compilare il nostro
quest’ultima. Con l’avvento di .NET creare do- file .cs o .vb (per comodità, da ora in poi conside-
cumentazione tecnica è divenuto molto più sem- riamo solo la parte C#) per estrarre i commenti
plice grazie alla presenza dei commenti XML XML (ciò si effettua con l’opzione /doc del com-
(presenti sin dalla versione 1.0 per il C#, dalla 2.0 pilatore C#) . A questo punto abbiamo creato due
per VB.NET) incorporati all’interno del codice e “oggetti”: un assembly compilato e un file XML
realizzabili con l’aiuto dell’Intellisense. In questo contenente i commenti estratti dai sorgenti. In

Figura 2 Sandcastle

N. 71 - Settembre/Ottobre VBJ 63
.NET TOOLS

seguito, si utilizza MRefBuilder che usa reflec- A differenza della procedura a riga di coman-
tion per ispezionare gli assembly compilati e re- do, per creare un file di documentazione è
stituisce un nuovo file di output (reflection.org), sufficiente inviare il comando “Build Project”
a cui deve essere applicata una trasformazione del menu “Documentation”: automaticamente
XML grazie all’eseguibile XslTransform che tra- verranno eseguiti tutti gli step necessari e il ri-
sforma l’output di MRefBuilder in un file di do- sultato sarà presente nella directory di output
cumentazione reflection.xml, che contiene tutti i specificata nelle opzioni.
dati ma non la presentazione dei dati stessi. Il risultato di questa elaborazione è un file di
A questo punto si esegue l’applicazione BuildAs- help del tutto somigliante a quelli cui noi pro-
sembler che presenta la documentazione presa grammatori in ambiente .NET siamo abituati,
dal reflection.xml e mette insieme i commenti cioè con lo stesso layout della documentazione
raggruppandoli secondo argomenti HTML. L’ou- MSDN.
tput di BuildAssembler può essere consumato Insieme, questi due tool forniscono un mezzo
dai compilatori Microsoft di HTML Help per crea- invalutabile per creare una documentazione
re un file di TOC (Table of Contents) e gli indici. professionale e altamente affidabile. Poiché
Come abbiamo visto, la procedura è abbastan- Sancastle è ancora in versione CTP, non è da
za macchinosa, specie per chi non ha molta escludere che verranno effettuate piccole mo-
familiarità con i tool a riga di comando. Tra le difiche al motore, che inevitabilmente dovran-
tante applicazioni open source che permettono no essere riflesse anche sul Sandcastle Help
di creare documentazione in modo visuale, File Builder. Nonostante una leggera difficoltà
vale la pena menzionare Sandcastle Help File iniziale, è assolutamente certo che questo tool
Builder, un’applicazione scaricabile gratuita- ripagherà di gran lunga le ore spese per padro-
mente dal sito di CodeProject. neggiarlo al meglio.
La semplice interfaccia grafica (volutamente
ispirata a NDoc) permette in primo luogo di sce- Prodotto
Sandcastle CTP + Sandcastle Help File Builder 1.2.0.0
gliere quali assembly includere nel progetto di
compilazione ed eventualmente quali esclude- Url di riferimento
re. Una grande property grid permette di modi- http://www.microsoft.com/downloads/details.aspx?familyid=E
ficare le impostazioni del progetto: vediamone 82EA71D-DA89-42EE-A715-696E3A4873B2&displaylang=en
(Sandcastle)
alcune. Le prime impostazioni da modificare http://www.codeproject.com/useritems/SandcastleBuilder.asp
riguardano la posizione del compilatore HTML (Sandcastle HFB)
help 1.x, del compilatore HTML help 2.x, del Stato Release
percorso dove deve essere salvato il file di help CTP
compilato e del percorso di Sandcastle.
Semplicità d’uso ªªª²²
Sotto la categoria “Build” è possibile imposta- Come tutte le applicazioni a riga di comando, la semplicità d’uso
re la versione del Framework e il formato del diminuisce; diventa buona se si utilizza Sandcastle HFBo.
file di Help. Utilità ªªªªª
Nella categoria “Help File” sono presenti alcune Finalmente a disposizione di qualsiasi programmatore uno stru-
proprietà che renderanno la nostra documenta- mento professionale per creare la documentazione.
zione in tutto e per tutto uguale a quella Micro- Qualità prodotto ªªªª²
soft: CopyrightHref e CopyrightText permettono Entrambi affidabili, nei test sul prodotto eseguiti non abbiamo ri-
scontrato particolari problemi, solo qualche piccolo bug che ver-
di impostare un link ad eventuali scritte sul rà risolto nella versione definitivai.
copyright dei contenuti, IncludeFavorites inclu-
Qualità documentazione ªªª²²
de un tab “Preferiti” nel file di help compilato, La documentazione di Sandcastle è abbastanza scarsa, si consi-
Preliminary imposta la classica scritta “[This glia una buona dose di pazienza e molte prove; la documenta-
is preliminary documentation and is subject to zione di Sandcastle HFB è decisamente buona (in lingua inglese,
come il programma)
change]”, SdkLinkType permette di scegliere
dove devono essere impostati gli eventuali link.

64 VBJ N. 71 - Settembre/Ottobre 2006

Оценить