1a lezione
A scuola con PC Open
Web Developer ASP
di Antonio Volpon
1 Da sito statico a dinamico
roseguiamo il filone aperto a inizio d'anno con il
corso Webmaster per affrontare questa volta la progettazione di pagine e siti dinamici realizzati con tecnologia Microsoft. Il corso, che si
articola in quattro puntate, vi
spiegherà tutti gli elementi essenziali per realizzare un progetto completo, inclusa l'integrazione con un database
esterno.
HTML è, come abbiamo approfondito nelle puntate del
corso Webmaster, un linguaggio utilizzato per la costruzione di pagine Web di natura statica. Con statico in questo contesto intendiamo prevedibile:
una pagina realizzata con solo
codice HTML produce lo stesso risultato per ogni visitatore
che vi accede. Se la realizzazione di siti Web si fermasse a
un sito statico, però, quasi tutto quello che siamo abituati a
vedere oggi in Internet (forum,
servizi di home banking, chat)
non sarebbe possibile.
P
Da statico a dinamico
Per dinamico si intende un
sito in grado di interagire con
l’utente, così da rispondere in
modo attivo e diverso caso per
caso, per esempio riportando
in cima alla pagina il nome dell’utente registrato o addirittura, come succede ad esempio
per MyYahoo (http://my.
yahoo.com/), personalizzando
i contenuti.
Ma quando vale la pena di
realizzare un sito dinamico? La
risposta dipende da molti fattori, come ad esempio la dimensione del sito stesso, la
frequenza di aggiornamento e
la necessità di aggiungere o
modificare diverse sezioni in
tempi brevi.
Se l’unico scopo del sito è di
ospitare il vostro curriculum
vitae, pubblicare qualche foto
delle vacanze o pubblicizzare
in poche pagine l’attività della
vostra società, probabilmente
potete accontentarvi delle
possibilità offerte da un sito
statico. In questo caso realizzerete tante pagine HTML
quante sono le pagine del sito,
ad esempio 10 pagine contenenti ognuna 5 foto delle vostre vacanze.
Ponete ora il caso che al posto di sole 10 pagine ne abbiate via via aggiunte delle altre
nel corso delle stagioni: vi troverete ben presto ad ospitare
sul vostro sito qualche centinaio di pagine. Nessun problema fino a quando non dovete
IL CALENDARIO DELLE LEZIONI
Lezione 1:
Da sito statico
a dinamico
Le prossime puntate
Lezione 2:
Portare il sito sul server
• Da sito statico a dinamico
• Come realizzare siti dinamici
• Una prima pagina ASP
• Anatomia di una pagina ASP
• Rendere il codice leggibile e
facile da modificare: gli
include ASP
1/97
Lezione 3:
ASP e i database
Lezione 4:
Uso avanzato dei database
apportare delle modifiche, ma
pensate se un domani volete
spostare la didascalia da sotto
la foto a sopra, magari aumentando le dimensioni del carattere per simulare un titolo: non
avete alcuna altra scelta se
non di ripassare una per una le
pagine. Realizzando un sito dinamico, invece, sarebbe sufficiente realizzare una sola “pagina tipo” (detta in gergo template), che assomiglia in tutto
per tutto alle pagine realizzate
precedentemente, solo che
contiene testo e immagini fittizi. A questo punto è possibile
sostituire al testo e all’immagine alcune istruzioni scritte in
un linguaggio di programmazione, in modo da interagire
con una base di dati, cioè un
“contenitore” (ne parleremo
approfonditamente nella terza
puntata) di didascalie e foto.
Quando l’utente del nostro sito richiama la pagina con le foto, gli viene servito sempre lo
stesso template, ma il contenuto prelevato dalla base di
dati cambierà di volta in volta
(le foto di Parigi, di Londra, e
così via). Il vantaggio in termini di manutenzione è evidente,
perché la pagina da aggiornare
è solo una, ma c’è di più.
Se i dati sono ospitati in un
sito dinamico, è possibile realizzare funzioni di ricerca che
permettono al visitatore di recuperare le informazioni di interesse, in questo caso di accedere alle foto volute senza
doverle scorrere tutte.
Ad esempio http://www.vol
pon.com/foto.asp contiene
elenchi generati in modo del
tutto dinamico ed è possibile
effettuare un buon numero di
ricerche. Alla fine del presente
corso saremo in grado di costruire una pagina simile a questa.
Come installare gli esercizi
Vediamo come configurare Internet
Information Services su Windows
XP Professional per poter utilizzare
gli esempi del corso
1 - Aprite il Control Panel dal menu
Start / Settings Start e da qui
selezionate Add or Remove
Programs. A questo punto cliccate
la voce Add / Remove Windows
Components dalla barra laterale
sinistra.
Assicuratevi che IIS sia installato,
oppure procedete all’installazione
spuntando la relativa voce.
Chiudete tutte le finestre, ad
eccezione del Control Panel
2 - Andate sul sito di PC Open
(sezione Guide pratiche) e
scaricate i file del corso in una
cartella del vostro disco fisso
3 - Dal Control Panel selezionate
Administrative Tools
4 - Nella lista dei programmi di
amministrazione selezionate
Internet Information Services e
apritelo
5 - A questo punto siete ai
comandi dei server. Non vi resta
che configurarlo perché prenda gli
esempi dalla cartella che avete
creato sopra. Per farlo, selezionate
la voce Default Web Site con il
tasto destro e aprite la finestra
delle proprietà
6 - A questo punto procedete alla
linguetta Home Directory e scrivete
il percorso della cartella nella
quale avete salvato i file
(alternativamente potete sfogliare
nel disco servendovi del pulsante
Browse)
7 - A questo punto potete chiudere
tutte le finestre, aprire un browser
e digitare l’indirizzo di una pagina
di esempio,
http://localhost/oggi.asp.
Localhost è il nome del vostro
server locale, che potete usare
non solo per eseguire i nostri
esempi, ma per sperimentare dal
vivo il mondo ASP
1a lezione
2 Come realizzare siti dinamici
er dotare la pagina Web di
dinamicità, in modo che il
risultato prodotto dipenda da alcuni fattori, primo fra
tutti l’interazione degli utenti
con il sito, è necessario arricchire il codice HTML con le potenzialità date dalle piattaforme lato server. Nella settima
lezione del corso Webmaster
sono stati presentati alcuni approcci per la realizzazione di
pagine dinamiche, con particolare riferimento a CGI (Common Gateway Interface). In queste 3 puntate affrontiamo invece lo studio di ASP (acronimo
di Active Server Pages), la piattaforma Microsoft che in questi ultimi anni ha riscosso parecchio successo per diverse
ragioni, prima fra tutte la relativa semplicità di apprendimento che ne ha diffuso l’utilizzo ben al di fuori dalla ristretta cerchia dei programmatori.
L’idea che sta alla base di
questo tipo di soluzioni è molto semplice: nel codice HTML
è inserita una serie di istruzioni che il Web server è in grado
di interpretare e la pagina viene salvata con una particolare
estensione, normalmente ASP.
Quando l’utente, utilizzando il
proprio browser, accede a una
pagina con questa estensione,
il Web server non la preleva
dal disco fisso per inviarla immediatamente al richiedente,
ma la analizza alla ricerca di
eventuali parti di codice ASP. Il
server Web si compone di diverse componenti software,
dette librerie, ognuna specializzata in un particolare compito, tra cui ce n’è una (asp.dll)
che riceve dal server il codice
da eseguire. Questa libreria è
responsabile di interpretare ed
eseguire il codice ASP e di restituire di nuovo al server il risultato dell’elaborazione (tipicamente dati provenienti da
un database). Il server sostituisce quindi il codice ASP all’interno della pagina con il codice HTML prodotto dalla libreria (l’elenco dei movimenti
di un conto bancario, ad esempio) e invia il risultato finale al
browser dell’utente. È quindi
importante sottolineare come
il codice ASP non arrivi mai al
browser dell’utente, ma venga
eseguito esclusivamente sul la-
P
2/97
to server. Questo ha delle importanti ripercussioni sulla sicurezza di una pagina: se l’utente fosse in grado di leggere
nel sorgente di una pagina il
codice ASP, potrebbe impossessarsi di informazioni riservate, come ad esempio le password di accesso a un database, o risalire alla configurazione delle macchine che ospitano il sito. Da quanto abbiamo
detto è anche chiara la differenza tra un linguaggio “server
side”, come per l’appunto sono quelli della piattaforma ASP,
e un linguaggio “client side”,
come è invece Javascript. Nel
caso di Javascript è direttamente il browser ad eseguire il
codice, e proprio per questo le
potenzialità e funzionalità di
questo tipo di linguaggi sono
esigue se paragonate a quelle
di un linguaggio interpretato
direttamente dal server.
Active Server Pages
e Internet Information
Services
ASP vuol dire Microsoft e il
server Web d’eccellenza di casa Microsoft è IIS (Internet
Information Services), disponibile come componente gratuito in Windows 2000, XP e naturalmente Windows Server
2003.
Ma il supporto per ASP può
anche essere installato su Windows NT, come parte del Windows NT 4.0 Option Pack e perfino su macchine Windows
95/98, in questo caso utilizzando il Personal Web Server (una
versione leggera, ma che svolge gli stessi compiti di IIS).
Possono essere scaricati entrambi da Internet [[http://
www.microsoft.com/ntserver/nts/downloads/recommended/NT4OptPk/default.AS
P]]. Anche se ASP è una tecnologia Microsoft, alcune società
si sono sforzare di portare questa piattaforma in altre realtà,
come ad esempio Sun ONE Active Server Pages [http:/wwws.
sun.com/ software/chilisoft/
index.html], che consente di
far girare applicazioni ASP sui
server Sun. Per i dettagli sull’installazione e configurazione
di ASP e IIS vi rimandiamo alla
settima puntata del corso di
Webmaster.
Se invece state cercando
qualche provider che vi dia la
possibilità di sperimentare gli
esercizi del corso senza dover
configurare il vostro PC, date
un’occhiata a quelli presenti
in http://www.aspfree.com
/ASP/freeasphost.ASP, molti
dei quali gratuiti. Tenete comunque conto che normalmente è più comodo lavorare
in locale fino a quando le pagine sembrano funzionare correttamente senza errori macroscopici, e portare successivamente l’applicazione nelle
cartelle messe a disposizione
dal provider.
ASP e i linguaggi di scripting
ASP non è un linguaggio, ma
una piattaforma, un insieme di
oggetti e funzionalità. Questo
vuol dire che per realizzare pagine ASP potete utilizzare diversi linguaggi, e l’adozione di
uno o dell’altro dipende semplicemente da quello con il
quale vi sentite più a vostro
agio. Se conoscete Visual Basic, ad esempio, la scelta ideale è rappresentata da Visual
Basic Script, mentre se realizzate pagine HTML con codice
Javascript, potreste preferire
Jscript.
Indipendentemente dal linguaggio utilizzato, comunque, i
risultati non cambiano minimamente. L’unica accortezza
che vi suggeriamo di adottare
è di non usare, anche se è tecnicamente possibile, linguaggi
diversi in una pagina ASP, per
evitare di sprecare importanti
risorse, visto che ASP deve caricare in memoria un interprete diverso per ogni tipo di linguaggio utilizzato.
Visual Basic Script (abbreviato spesso con VBScript) è I principali oggetti ASP
Application:
consente di definire dati e
informazioni comuni a tutta
l’applicazione Web. Il copyright
del sito, che sarà comune a
tutte le pagine, potrebbe
essere definito grazie a questo
oggetto
AspError:
in caso di errore, dà al
programmatore la possibilità di
accedere ai dettagli dell’ultimo
errore che si è verificato
ObjectContext:
viene impiegato per creare
pagine Web che sfruttano le
transazioni, e il suo uso va al di
fuori dello scopo di questo
corso.
Basti sapere che una
transazione è utilizzata per
raggruppare al suo interno più
operazioni atomiche ed è
impiegata, nel caso di errori o
situazioni non attese, per
riportare l’applicazione allo
stato precedente
Request:
quando l’utente interagisce con
la pagine ASP, le informazioni
inviate passano per l’oggetto
Request, che viene interrogato
per ottenere i dati inviati dal
browser verso il server
Response:
può essere considerato
l’antagonista dell’oggetto
request. Se quest’ultimo si
preoccupa di ospitare i dati
inviati dagli utenti, response
invia informazioni dal server al
browser, un po’ come la
funzione print del Basic stampa
caratteri a video
Server:
svolge alcune funzioni di utilità,
come ad esempio definire il
tempo massimo di esecuzione
di uno script (prima di andare
in timeout per preservare
risorse) e porta con sé alcune
informazioni relative al browser
dell’utente e al sito di
provenienza
Session:
consente al programmatore di
salvare e recuperare
informazioni di un particolare
utente nel corso della sua
navigazione. Diversamente
dall’oggetto Application, che
contiene informazioni comuni a
tutta l’applicazione, Session
contiene quelle di un solo
utente. Si presta quindi molto
bene per ospitare dati come gli
elementi di un carrello
elettronico, il nome e cognome
del visitatore, e così via.
1a lezione
un sottoinsieme di Visual Ba-
sic del quale eredita diverse
funzionalità, ma si differenzia
per alcuni importanti aspetti,
prima di tutto per il fatto che si
tratta di un linguaggio completamente interpretato, e quindi
dalle prestazioni di esecuzione
decisamente inferiori.
In questa sede utilizzeremo
proprio VBScript per realizzare pagine ASP. Sia Visual Basic,
sia VBScript sono linguaggi
“case insensitive”, il che vuol
dire che potete scrivere le parole chiave del linguaggio, i nomi delle variabili e le espressioni indifferentemente in
maiuscolo, minuscolo o una
combinazione dei due: non fa
alcuna differenza.
Scrivere pagine ASP
Come per le pagine HTML,
anche per scrivere pagine ASP
avete due scelte: utilizzare un
semplice editor di testo oppure affidarvi a qualche programma più evoluto, che evidenzi le parole chiave del linguaggio o vi aiuti addirittura
nella stesura del codice, come
Visual Interdev di Microsoft
[http://msdn. microsoft.com/
vinterdev/default.asp] (da
qualche tempo incluso in Visual Studio .NET). La soluzione
migliore è forse quella di utilizzare uno strumento che consenta sia di sviluppare codice
HTML, sia di integrarlo con codice ASP.
Tra i prodotti sul mercato
vale la pena di ricordare
Dreamweaver MX di Macromedia [http:// www.macrome
dia.com/software/dreamwea
ver/] e l’ultima versione di TopStyle [http:// www.bradsoft.
com/topstyle/], entrambi sca-
ricabili in versione di prova.
Per svolgere gli esempi di questo corso, comunque, un semplice editor di testo è più che
sufficiente.
Gli esempi del corso
Cercheremo di accompagnare con diversi esempi il nostro viaggio nel mondo della
tecnologia ASP, così da mettervi subito in condizione di capire quali sono i vantaggi di questa piattaforma rispetto alle
semplici pagine HTML, e per
fornirvi qualche spunto nel
realizzare i vostri prossimi progetti. Al termine delle tre puntate avremo realizzato la struttura di un semplice sito fittizio
per il signor Mario Rossi, composto da Home Page, elenco
delle foto delle vacanze (prelevate da database) e possibilità
di inviare commenti a Mario
con un form. Nel corso delle
puntate non ci preoccuperemo della resa visiva delle pagine, cioè di creare pagine belle
da vedere.
Preferiamo concentrarci sul
codice “nudo e crudo”, per
rendere gli esempi più semplici da capire e mirati, data anche la facilità con cui il numero
di righe in una pagina ASP tende ad aumentare con l’inserimento di tag HTML. Lasciamo
al lettore la possibilità di personalizzare ed estendere quanto riportato su queste pagine.
Dobbiamo però cominciare
con ordine, e introdurre per
prima cosa qualche concetto
di base, visto che realizzare
pagine ASP, per quanto si tratti di una tecnologia semplice e
al tempo stesso potente, è in
realtà costruire dei veri e propri programmi.
3 Una prima pagina ASP
rima di entrare nel dettaglio delle funzionalità di
VBScript, vediamo un primo esempio di pagina ASP che
ci servirà per gli esempi futuri
(listato 1).
P
L1
Questo semplice esempio
(che ha solo scopo didattico),
produce una pagina HTML con
un elenco di frasi del tipo “Sono arrivato a... “ da 1 a 10. Nulla di eccezionale, ma che comunque ci introduce al mondo
della programmazione. Nel codice della pagina, infatti, è presente una sola frase “Sono arrivato a”, mentre nella finestra
del browser il testo viene ripetuto 10 volte, cosa impossibile
3/97
se avessimo realizzato una
semplice pagina HTML. Il codice ASP vero e proprio si trova
racchiuso tra <% e %>. Il processore ASP, nell’incontrare
questi tag, sa che il loro contenuto non è un semplice codice
HTML, da restituire così com’è
alla pagina, ma una serie di
istruzioni da eseguire. Non c’è
limite al numero di volte in cui
inserire i tag <% %>, ma sempre
per motivi di prestazione è
buona norma isolare il più possibile il codice ASP dal resto
della pagina HTML. Non solo,
così facendo il codice risulta
notevolmente più chiaro da
leggere e modificare, soprattutto se chi realizza la pagina
HTML non è la stessa persona
che programma anche il codice
ASP. Per realizzare esempi più
complessi, e soprattutto più
utili rispetto al precedente, è
ora necessario analizzare più
da vicino le potenzialità di VBScript.
Fondamenti di VBScript
Abbiamo detto che una pagina ASP è un insieme di HTML
con righe di codice interpretate, e che in questo corso utilizzeremo VBScript quale linguaggio per costruire la nostra
applicazione.Vediamo allora le
principali strutture messe a di-
sposizione da VBScript, e come
vengono utilizzate per costruire pagine ASP. Nel costruire pagine dinamiche, per quanto
una sia diversa dall’altra, un
programmatore ha normalmente alcune esigenze ricorrenti. Se ripensiamo all’elenco
di foto delle vacanze, realizzate
con un unico template, chi sviluppa ha bisogno di:
1. memorizzare il titolo della foto prelevato dalla base di dati
(per poi compilare il template)
2. ripetere più volte il template
(cioè, “ciclare” per tutte le foto
di interesse)
3. decidere, in base all’input
dell’utente, quali foto visualizzare
VBScript, come molti linguaggi di programmazione,
rende disponibili una serie di
funzionalità che il programmatore può adottare per queste
necessità. Una variabile, come
vedremo tra poco, viene utilizzata proprio allo scopo di salvare informazioni di volta in
volta diverse, come il titolo della foto nel nostro caso. Per ripetere un template sono impiegati i cicli, cioè dei costrutti
(un costrutto è una serie di
istruzioni, che solitamente
hanno senso solo nella loro
complessità) che ripetono una
serie di istruzioni fino al verifi-
carsi di una condizione limite.
Per decidere come proseguire
in seguito all’input dell’utente,
infine, sono impiegate le
espressioni condizionali. Vediamo nel dettaglio l’uso di
queste strutture di programma.
Variabili
Una variabile, così come un
documento salvato sul computer, è un contenitore di informazioni. Se realizzate un documento Word e lo salvate su disco fisso, questo è composto
da due dati: il nome con cui
avete salvato il documento, e il
suo contenuto (ad esempio telefoni.doc è un documento che
contiene l’elenco dei numeri
telefonici dei vostri amici).
Allo stesso modo, una variabile è l’unione di due elementi:
un nome e un contenuto.
Un’istruzione di questo tipo,
ad esempio:
telefono = “1234 567890”
definisce una variabile, il cui
nome è telefono, e il cui contenuto è la stringa (ovvero, l’insieme di caratteri) 1234 567890
(prestate anche attenzione al
fatto che i doppi apici non sono
parte del contenuto, ma servono da delimitatore).
Le variabili sono un elemento fondamentale dei linguaggi 1a lezione
di programmazione, e il motivo
è evidente: sono utilizzate per
memorizzare valori che dipendono dall’input dell’utente.
Pensate a un programma che
richiede d'inserire un numero,
e lo moltiplica per due. Poiché
non è dato sapere a priori il valore inserito dall’utente, useremo una variabile, ed effettueremo le operazioni con essa (vedi
l'esempio 1).
E1
riabile è un contenitore di valori, e che è possibile eseguire
operazioni tra variabili. Tali
operazioni, il cui risultato viene anch'esso assegnato a una
variabile, sono dette espressioni, e sono composte da valori (come 2, “1234 567890”),
variabili (come telefono) e operatori (+, *). Il risultato di un’espressione dipende però dal tipo di dato con il quale opera, e
in dipendenza di esso i risultati possono essere diversi.
L'espressione
riportata
nell'esempio 3 assegna alla vaE3
Anche se vedremo più avanti come riconoscere il valore inserito dall’utente, l’esempio
precedente ci fa capire che è
anche possibile assegnare a
una variabile il risultato di
un’operazione che coinvolge
altre variabili. Tornando all’esempio di sito con foto, useremo alcune variabili che di volta
in volta contengono il titolo
della foto e la didascalia.
Ci sono due modi per creare
una variabile in VBScript. Il primo è chiamato dichiarazione
implicita, e consiste nell’usare
direttamente la variabile, ad
esempio strSaluto = “Hello
world”
È anche possibile dichiarare
esplicitamente la variabile prima dell’uso, con una forma del
tipo riportata nell'esempio 2.
E2
Questa seconda modalità è
preferibile perché, quando viene utilizzata insieme alla direttiva Option Explicit, limita i
problemi se digitate erroneamente i nomi delle variabili
(come ad esempio strSluto al
posto di strSaluto). Nel caso di
dichiarazione implicita, infatti,
le variabili vengono create automaticamente, ed è così più
difficile accorgersi di aver
commesso un errore, in quanto
l’esecuzione della pagina non
viene interrotta. Con Option
Explicit, una direttiva che è
possibile inserire in testa ad
ogni pagina ASP, ogni variabile
deve invece essere dichiarata,
pena la non esecuzione della
pagina.
Tipi di dato e operatori
Abbiamo detto che una va-
4/97
riabile c il valore 5. L'espressione invece riportata nell'esempio 4 produce come risulE4
tato 23, l’unione di 2 e 3. La differenza sta nel tipo di dato delle variabili. Nel primo caso si
tratta di numeri, nel secondo
caso, che utilizza stringhe (si
distinguono grazie alla presenza dei doppi apici), è stata eseguita una concatenazione (ne
riparleremo tra breve).
Solitamente, ogni linguaggio
di programmazione dispone di
un certo numero di tipi di dato
che è possibile e necessario
impiegare nella costruzione dei
programmi, ma in VBScript, e
questa è un’altra differenza rispetto a Visual Basic, esiste un
solo tipo Variant, ossia un tipo
di dato particolare, nel senso
che di volta in volta può rappresentare una stringa, un intero, una data, eccetera, in base al contesto nel quale viene
utilizzato. Nell'esempio 5 il tipo
E5
una variabile, come nell’esempio del sito con foto, dove è necessario ospitare più titoli e
descrizioni. In questo caso si
parla di array, e la dichiarazione è del tutto simile a quella di
una variabile, come nell'esempio 6.
E6
si è deciso di visualizzare 5 foto per pagina, un’espressione
condizionale potrebbe venire
impiegata per stabilire quando è il momento di spostarsi
su una nuova pagina, con
qualcosa del tipo elencato nel
listato 4.
L4
Espressioni condizionali
Capita spesso che l’esecuzione di una riga di codice del
programma dipenda dalla verifica di una condizione. Pensate
a un sistema Bancomat: se il
codice inserito è corretto, il sistema procede con il menu
delle operazioni, altrimenti avverte dell’errore e richiede
nuovamente l’inserimento del
codice. Lo stesso si verifica in
una pagina Web: in uno dei
prossimi esempi vedremo come far cambiare l’aspetto di
una voce di menu in dipendenza della scelta dell’utente. Anche in VBScript, come in quasi
tutti i linguaggi, è possibile accertarsi del risultato di una
condizione per proseguire in
un modo o in un altro il flusso
del programma. L'espressione
riportata nel listato 2 verifica
L2
quale tra le due variabili x e y
ha un valore maggiore, e assegna di conseguenza la variabile strRisultato a uno solo dei
due possibili valori. Se le condizioni da verificare sono più
di due, è possibile impiegare
una versione estesa rispetto a
if...then...else, che prende il nome di if...then...elseif come indicato nel listato 3.
L3
di dato è sempre Variant, ma
rappresenta una data.
Cicli
Immaginate di acquistare alcuni testi da una libreria on line, come ad esempio Amazon.
La procedura di acquisto termina normalmente con un riepilogo del vostro ordine, e molto probabilmente vi troverete
in una pagina che presenta una
tabella con l’elenco dei libri
scelti. La pagina deve essere in
grado, in dipendenza del numero di libri, di allungarsi e di
accorciarsi secondo le esigenze (c’è chi acquista un solo
prodotto, chi ne approfitta per
rimpinguare l’intera biblioteca). Il programmatore che ha
realizzato la pagina si è quindi
preoccupato di ripetere un’operazione per più di una volta,
fino al verificarsi di una condizione limite. In questo caso entrano in gioco i cicli, che in VBScript possono essere realizzati ricorrendo ai costrutti
for...next, do...while o while...wend.
Con il ciclo riportato nell'esempio 7 la variabile y vale
E7
1,3,6,10,15... Il significato del ciclo è: incrementa la variabile
“i” di una unità fino a che raggiunge il limite di 10.
Nel caso riportato nell'esempio 8 il ciclo viene eseguito fintantoché la variabile “i” è inferiore o uguale a 5.
E8
Array
Negli esempi precedenti, a
ogni variabile è stato associato
un solo valore. Capita però che
sia utile assegnare più valori a
Nel caso del sito con l’elenco di foto delle vacanze, in cui
1a lezione
Se estendiamo questo esempio, lo possiamo utilizzare per il
nostro sito di foto on line, che
prevede di suddividere le foto in
pagine che ne contengono 5.
Anche se ci manca qualche nozione sui database per poter
scrivere il codice completo, questo avrà una forma simile a
quanto riportato nell'esempio 9.
zione. Per concatenare una
stringa si utilizza l’operatore
&, come nell’esempio 10.
E9
Abbiamo per prima cosa definito due array, e abbiamo popolato il primo con l’elenco di
città.
Successivamente abbiamo
valorizzato delle stringhe concatenando a un testo fisso il nome delle due città. Poiché il codice ASP è ospitato in HTML,
nulla ci vieta di costruire stringhe che contengano tag, come
nell’esempio seguente 11.
Concatenare le stringhe
Un’operazione spesso usata
nel costruire pagine ASP con
VBScript è la concatenazione
di stringhe, ossia produrre una
variabile stringa che è il risultato dell’unione di altre stringhe (o meglio, come dicevamo,
di altre variabili di tipo Variant). Pensate al nostro esempio di foto on line. In testa alla
pagina potreste voler visualizzare un testo in questa forma:
“foto scattata a” seguito di volta in volta da un dato proveniente dalla base di dati. Per
farlo avete bisogno di costruire
una stringa composta da due
parti, una fissa e una ogni volta
diversa. Questa operazione
prende il nome di concatena-
E12
E10
E11
Per il browser non c’è nessun problema nel ricevere questa stringa, in quanto l’interprete ASP ha precedentemente
risolto l’istruzione e l’ha convertita nel corrispettivo codice
HTML, in modo del tutto trasparente per il client.
Procedure
Come gran parte dei lin-
guaggi, anche VBScript dà allo
sviluppatore la possibilità di
accorpare più istruzioni in procedure, così da rendere il codice maggiormente leggibile e soprattutto riutilizzabile.
Ne esistono di due tipi: Sub e
Function. La prima è una procedura che, al termine dell’esecuzione, non restituisce un valore frutto dell’elaborazione,
ma si limita a restituire il controllo al codice chiamante.
Nel prossimo esempio vediamo invece la procedura Function che in questo caso accetta
in input due stringhe e ne restituisce la concatenazione, come
appare nell'esempio 12.
Commenti
Come per quasi tutti i linguaggi, anche VBScript prevede la possibilità d'inserire commenti nel codice.
Per farlo esistono due sintassi equivalenti, la prima prevedere l’uso dell’apice singolo
‘, la seconda della parola chiave rem, entrambi inseriti all’inizio della riga da commentare
(vedi l'esempio 13).
E13
Questa veloce introduzione
al mondo di VBScript è sufficiente per questo corso ASP.
Vi consigliamo però di scaricare dal sito Microsoft il file di riferimento del linguaggio, totalmente gratuito, che vi aiuterà
più di una volta mentre realizzate le vostre applicazioni.
Lo potete trovare partendo
da questo indirizzo: http://
msdn.microsoft.com/scrip
ting/.
4 Anatomia di una pagina ASP
ettiamo in pratica quanto appreso fino a qui e
costruiamo un secondo,
semplice esempio di pagina
ASP (vedi il listato 5).
Lo scopo di questa pagina è
visualizzare la data e ora attuali. La direttiva language, che
compare in testa alla pagina,
istruisce il server Web relativamente al linguaggio utilizzato
in questa pagina, in questo caso VBScript. Abbiamo già introdotto il ruolo della direttiva
Option Explicit, un comodo
controllo che possiamo inserire per cautelarci da eventuali
errori di ortografia, così da utilizzare correttamente i nomi
delle variabili in tutto il codice
che scriviamo.
Dim è la parola chiave utilizzata per definire le variabili che
vengono utilizzare poco sotto,
M
5/97
e che ospitano il mese, l’anno,
il giorno, le ore e i minuti correnti. Poco sotto sono infatti
utilizzate alcune funzioni che
operano sulle date: la prima,
now(), restituisce la data e ora
corrente, mentre tutte le altre
ne estraggono una parte (l’anno, il mese, il giorno e l’ora). La
riga che ha il compito di visualizzare (write) una stringa composta dalla data e l’ora è quella
composta dall’istruzione response.write, che vedremo meglio più avanti. Il risultato della
pagina inviata al browser è
quello presentato nella figura 1.
Come dicevamo precedentemente, il server si occupa di eseguire il codice della pagina ASP e
di restituire al browser il risultato
dell’operazione. In effetti, se guardiamo il codice HTML giunto al
browser (cosa che è possibile fa-
L5
re in Internet Explorer 6 dal menu
Visualizza - Sorgente), otteniamo
il listato 6.
Come vedete, il codice ASP è
sparito. In realtà, è il server ad
aver interpretato e sostituito le
parti comprese tra <% e %>.
Esiste un altro modo per aprire e chiudere una parentesi F1
1a lezione
di codice all’interno della pagi-
na, e si ottiene utilizzando i tag
<script></script> insieme all’attributo runat=”server”. Vediamo
come cambia l’esempio utilizzando i costrutti elencati nel listato 7.
Attenzione però: benché il risultato sulla pagina sia simile a
quello che si otterrebbe utilizzando i tag <% e %>, in realtà il
codice racchiuso tra <script> e
</script> viene interpretato alla
fine della pagina, il che vuol dire
dopo che è stato chiuso il tag
<html>. Per questo motivo il tag
<script> viene di norma utilizzato per racchiudere la definizione
di procedure (sia sub, sia function) a loro volta richiamate da
codice racchiuso da <% e %>.
È possibile includere diverse
sezioni di codice all’interno di
una pagina, per esempio la presenza di tag HTML con codice
di programma. Supponiamo di
dover decidere, in base all’ora
di visita dell’utente, se salutarlo
con un “buongiorno”, oppure
con un “buonasera”. In questo
caso sfruttiamo il contenuto
del listato 8.
Una piattaforma orientata
agli oggetti
ASP è una piattaforma che
funziona secondo un modello a
oggetti a cui il programmatore
fa riferimento nella costruzione
delle pagine. Un oggetto, nel
caso di ASP, è una struttura
software definita all’interno di
una pagina, che permette di
svolgere particolari compiti,
come estrarre i dati inviati dall’utente, inviare stringhe di testo al browser o mantenere
informazioni in memoria; “re-
L8
sponse”, che abbiamo incontrato nell’esempio poco fa, è un
oggetto ASP.
Interagire con l’utente
Affrontiamo ora una problematica comune a tutti i siti dinamici: come scambiare informazioni con i visitatori del sito.
Possiamo impiegare un form
HTML, che consente di realizzare una pagina con campi che
l’utente può compilare e inviare. In particolare, nell’esempio
del nostro corso, si vuol dare la
possibilità ai visitatori di inviare commenti e che forniscano
una descrizione di loro stessi.
Per il momento ci limiteremo a
stampare i dati a video, ma nella terza puntata vedremo come
è possibile memorizzare queste informazioni in un database. Costruiamo un semplice
form per inserire il nome e cognome dell’utente, senza
preoccuparci della resa visiva,
e quindi senza adottare tabelle
di layout o fogli di stile, ma
cercando invece di rendere il
codice leggibile. Per prima cosa proviamo a farlo in HTML,
così da ottenere qualcosa di simile alla figura 2
Il codice HTML del form
è riportato nel listato 9.
Nell’esempio sono state inserite due caselle di testo (tag
input di tipo text) per contenere il nome e cognome della persona. Prestate particolare atL6
tenzione al valore dell’attributo name (txt_nome e txt_cognome), utilizzato dal codice
ASP allo scopo di estrarre i valori inseriti dall’utente. È inoltre presente un tag input di tipo submit, che viene rappresentato sulla pagina come un
pulsante da premere per inviare i dati inseriti.
In questa pagina non è necessario inserire nessuna riga
dere come è stata realizzata
consultando il listato 10.
Dopo aver dichiarato due
variabili per contenere il nome
e cognome del visitatore, queste sono valorizzate utilizzando l’oggetto request, che come
abbiamo visto poco fa consente al programmatore ASP di accedere ai dati inseriti dagli
utenti. Estrarre il nome e cognome è davvero semplice,
L9
L10
di codice ASP.
Essa si limita infatti ad accettare il nome e cognome del visitatore, ma demanda a un’altra pagina le
operazioni da
eseguire sui dati
(nel nostro caso, è sufficiente
visualizzarli da
qualche parte).
Per capire quale pagina si occupa di ciò, basta guardare il
valore dell’attributo action presente nella prima riga del form,
che indica a chi passare il controllo insieme alle informazioni
inserite. Nel nostro caso la pagina si chiama visnomecognome.asp e non ci resta che ve-
poiché si utilizza una sintassi
del
tipo
request.form
(nome_controllo), dove nome_controllo è il valore dell’attributo name del campo presente nel form. Il risultato finale è presentato nella figura 3.
F3
L7
F2
Post e get
Esistono due possibilità per
inviare i dati a una pagina Web.
Il primo, che abbiamo visto nell’esempio precedente, si chia- 6/97
1a lezione
ma “post” e si realizza utiliz-
zando un form il cui attributo
method ha come valore “post”.
Una seconda possibilità è di
utilizzare il metodo “get”, valorizzando di conseguenza l’attributo method.
Ma in cosa differiscono le
due possibilità? Con get, i dati
vengono non solo inviati alla
seconda pagina, ma anche visualizzati nella barra indirizzi
del browser, un po’ quello che
succede quando utilizziamo
Google per effettuare una ricerca (figura 4). Il vantaggio, in
questo caso, è che possiamo
aggiungere la pagina ai preferiti e ritornarci in futuro senza
dover reinserire il termine di ricerca. Visti i vantaggi dati dal
metodo get, sembrerebbe inutile poter disporre di un’ulteriore modalità. In realtà, il metodo get presenta due importanti limitazioni: è possibile inviare solo 1 o 2 Kbyte, visualizzare in chiaro dei dati sulla barra degli indirizzi non è accettabile per informazioni sensibili. Quando s’inviano password
o codici utente, perciò, è molto
meglio impiegare il metodo post, che non ha limiti di lunghezza e che non lascia alcuna
traccia. Se si utilizza il metodo
get, la sintassi da utilizzare è request.querystring(nome_campo).
Altri controlli HTML nei form
L’esempio che abbiamo realizzato fino a qui è alquanto
semplice, ma basta poco di più
per realizzare form completi,
utilizzando non solo caselle di
testo, ma anche caselle di selezione, checkbox e radio button. Poiché si tratta di elementi HTML, vi rimandiamo al corso Webmaster per una descrizione approfondita (vedi la settima lezione pubblicata sul numero di maggio e riportata in
PDF sul numero di settembre).
Esistono inoltre diverse risorse
on line dedicate all’argomento,
F4
come ad esempio questo tutorial in inglese [http://mastercgi.com/howtoinfo/formtutorial.shtml] o questo in italiano
[http://www.html.it/guida/index.html#forms]
Cerchiamo quindi di estendere l’attuale form, includendo
la possibilità di specificare
l’età, il sesso, gli hobby e alcune note. Il risultato è visibile in
figura 5. Analizziamo il codice
della pagina di risposta, nel listato 11, mentre tralasciamo il
codice del form, del tutto simile all’esempio precedente.
L’unica novità è introdotta
dai checkbox relativi agli
hobby, che prevedono la possibilità di una selezione multipla. In questo caso non è più
sufficiente estrarre il valore del
campo, che diventa infatti una
collezione di valori, ed è opportuno ricorrere al costrutto
for each, che consente di iterare tra tutte le corrispondenze
degli hobby scelti dal visitatore
e di visualizzarli su linee diverse della pagina.
Poiché for each lavora con
oggetti di tipo collezione, e
poiché l’intero form può essere considerato una collezione
di valori, è possibile sfruttare
lo stesso costrutto per estrarre tutti i valori di un form. Vediamo il listato 12. In questo caso viene estratto per prima cosa il nome del campo del form,
seguito dal valore. Scriviamo
request.form (campo) e non,
request.form (“campo”), in
quanto non vogliamo accedere
al contenuto dell’elemento
“campo” del form (che non esi-
L12
L13
ste), ma piuttosto
al valore che la variabile campo contiene a ogni iterazione.
Inviare dati
alla pagina:
l’oggetto
response
L’oggetto response visualizza
sulla pagina il risultato delle operazioni di elaborazione. Il metodo
più usato dell’oggetto response è
effettivamente write, che invia
al client una stringa di caratteri. Visto che è una delle operazioni più diffuse in una pagina
ASP, esiste anche un modo più
veloce per inviare dati al client,
e consiste nell’utilizzare il costrutto <%=espressione%>. In
particolare, le 2 righe di codice
mostrate nell'esempio 14 sono
del tutto equivalenti.
Attenzione però, nel secondo caso è imL11 possibile inserire più linee di
codice all’interno di <%=%>. In
questo corso ne
presentiamo un
altro che si rivela spesso molto
utile, il metodo
redirect.
Response.redirect invia invece il browser
dell’utente a
un’altra pagina,
magari in base
alla selezione
della lingua preferenziale. Per
farlo è sufficien-
te una porzione di codice simile a quanto riportato nel listato
13. Per ogni lingua sono state
create delle cartelle che ospitano le pagine ASP e, in base alla selezione dall’utente, il
browser viene indirizzato nella
directory corretta.
Abbiamo introdotto un nuovo costrutto, select case, molto utile quando si vuole confrontare il valore di una variabile con un elenco di possibilità. L’alternativa sarebbe stata
quella di utilizzare una lunga, e
poco chiara, lista di if, elseif,
end if.
F5
E14
7/97
1a lezione
5 Rendere il codice leggibile e facile
da modificare: gli “include ASP”
ensate a una problematica
concreta: volete aggiungere al sito che stiamo sviluppando per Mario Rossi una
barra che contenga alcune voci
di menu con l’elenco delle sezioni principali. Non siete però
certi che il numero delle sezioni rimanga invariato nel tempo,
magari perché non sapete quali avranno più successo e quali,
invece, abbandonare in futuro.
Se nel frattempo avete realizzato diverse pagine, e inserito
in ciascuna il menu, il lavoro di
aggiornamento diventerà ogni
giorno più impegnativo. Per
evitare tale genere di problematiche, potete realizzare file
che contengono parti di codice
o di pagina da riutilizzare in più
punti, e includerli secondo necessità. Tutto ciò sarebbe possibile anche senza ricorrere a
IIS, utilizzando i file di tipo SSI
(Server Side Include), ma in
questo modo potete non solo
riutilizzare il codice HTML, ma
intere porzioni di codice.
Proviamo allora a costruire
una pagina che includa codice
proveniente da una seconda, al
solo scopo di visualizzare la
data corrente. Ecco per prima
cosa la pagina da includere,
che chiameremo copyright.asp,
come illustrato nel listato 14.
A questo punto proviamo a
costruire una semplice pagina
che includa copyright.asp, come riportato nel listato 15.
Se provate a eseguire la pagina, otterrete il risultato di figura 6. Come vedete, oltre al
contenuto della pagina chiamata direttamente, è stato eseguito il codice di copyright.
asp, nel punto in cui è stata in-
P
F6
8/97
L16
L15
serita la direttiva #include file.
Esistono due tipologie di inclusioni. La prima, quella riportata nell’esempio, cerca il
documento da includere rispetto alla posizione del file
chiamante. In tal caso, quindi,
il
file
chiamante
e
copyright.asp si trovano nella
stessa cartella. Se l’include
avesse invece avuto una forma
del tipo <!- - #include file="car
tella/copyright.asp"--> il file
chiamante si sarebbe trovato
allo stesso livello della directory “cartella”. La seconda tipologia di inclusione prevede
l’utilizzo della direttiva:
<!- - #include virtual="copyright.asp"- -> con virtual al posto di file. In tal caso, al momento di includere il file, IIS
non si basa sulla directory corrente, ma bensì sulla “root directory” del sito. La root directory è la cartella principale che
contiene i file della vostra applicazione Web, indipendentemente dal fatto che abbiate
creato altre sottocartelle.
Un uso accorto ed efficace
della tecnica degli include vi
permette di risparmiare un bel
po’ di lavoro ed è utile, non appena avete finito di costruire il
template HTML della pagina,
spendere un po’ di tempo per
capire dove sia meglio effettuare i “tagli” che diventeranno include, così da rendere il codice
più leggibile e riutilizzarlo più
volte in contesti diversi. Ricordatevi che gli include possono
contenere non solo il codice
HTML, ma quasi sempre anche
codice ASP. Per tale motivo,
parti di pagina che potrebbero
non sembrare candidate a diventare un include, spesso lo
sono.
Ritornando all’esempio del
menu, come ci comportiamo
se l’esigenza è di evidenziare la
voce di menu con la sezione
corrente, e lasciare le altre voci invariate? La soluzione più
semplice potrebbe sembrare
quella di realizzare include diversi per ogni sezione, ognuna
con la voce di sezione di un colore diverso. Tale soluzione aggiunge pochi vantaggi, in quanto è comunque necessario gestire e aggiornare tanti include
quante sono le sezioni.
In realtà, è possibile utilizzare un solo include e sfruttare alcune righe di codice VBScript.
Il risultato finale è quello della
figura 7.
Si tratta di realizzare un include per il menu a sinistra sulla pagina che evidenzi in grassetto la sezione corrente (vedi
il listato 16).Notate come sono
stati costruiti i link per ogni sezione: oltre al nome della pagina ASP di destinazione compare un parametro, il cui valore
indica la sezione di destinazione. In questo modo, quando il
visitatore clicca su un link del
menu, oltre a richiedere il caricamento della pagina corrispondente, invia un parametro
con il nome della sezione. A
questo punto,
L14 utilizzando una
condizione, il
codice ASP dell’include verifi-
F7
ca se il parametro passato (salvato nella variabile strSezione)
corrisponde a quello della sezione che sta per essere visualizzata. In caso affermativo, la
sezione compare in grassetto e
senza link (non serve metterlo,
visto che siamo già al suo interno).
L'intestazione, i piè di pagina, i menu, la casella di ricerca
e il logo sono ottimi candidati
per diventare include. Per concludere l’esempio, copiamo il
codice del form nella pagina
scrivimi.asp la cui unica funzione consiste nel visualizzare i
dati inseriti. Per il momento il
sito di Mario Rossi offre poche
possibilità: una home page e la
navigazione tra le diverse sezioni. Lo abbiamo però costruito in modo che sia facile
modificarlo ed estenderlo. Nella prossima puntata vedremo
come.
Web Developer ASP - Lezione 1
esempio 1
numero = <valore inserito dall’utente>
moltiplicazione = numero * 2
esempio 2
Dim strSaluto
strSaluto = “Hello world”
esempio 3
a = 2
b = 3
c = a+b
esempio 4
a = “2”
b = “3”
c = a+b
esempio 5
Dim datOggi
datOggi = now()
esempio 6
dim foto(3)
foto(0) = “Foto di Parigi”
foto(1) = “Foto di Londra”
foto(2) = “Foto di Roma”
esempio 7
y = 0
For i = 1 to 10
y = y + i
Next i
esempio 8
i = 0
while i <= 5
i = i + 1
wend
esempio 9
i = 0
while i <= 5
...qui va il codice che visualizza la foto...
i = i + 1
wend
9/97
esempio 10
Dim foto(2), luogo(2)
luogo(0)=”Venezia”
luogo(1)=”Firenze”
stringa(0) = “Foto scattata a “ & luogo(0)
stringa(1) = “Foto scattata a “ & luogo(1)
esempio 11
stringa = “<b>Questo testo è in grassetto</b>”
esempio 12
Function ConcatenaStringhe(stringa1 as String, stringa2 as String)
ConcatenaStringhe=stringa1 & stringa2
End Function
Una riga di codice che richiama questa funzione potrebbe agire come segue:
Dim strStringa1, strStringa2, strContatenata
strStringa1 = “Pc “
strStringa2 = “Open”
strConcatenata = ConcatenaStringhe(strStringa1,strStringa2)
esempio 13
‘Questa riga è stata commentata
esempio 14
<% response.write “Gentile ” & nomeutente “, hai concluso
l’operazione con successo” %>
<%=“Gentile ” & nomeutente “, hai concluso l’operazione con successo”
%>
10/97
Cliccate qui per accedere alla versione elettronica dei listati. Si aprirà una pagina
Web con i link ai listati delle quattro puntate del corso. Cliccate sul link desiderato
e selezionate "Salva" dalla finestra visualizzata da Internet Explorer per indicare
dove volete salvarli. Gli esempi sono in formato ASP e perciò non direttamente
visualizzabili nel browser a meno di avere installato o attivato il servizio di
Internet Information Server sul vostro PC, nella versione per client Windows XP.
Listato 1
primapagina.asp
<html>
<head><title>La mia prima pagina ASP</title></head>
<body>
Questo testo non è codice
<br>
<%
for i = 1 to 10
response.write "Sono arrivato a " & i & "<br>"
next
%>
</body>
</html>
11/97
Listato 2
If x > y then
strRisultato = “x è maggiore di y”
else
strRisultato = “y è maggiore o uguale a x”
end if
12/97
Listato 3
If x > y then
strRisultato = “x è maggiore di y”
elseif x = y then
strRisultato = “y è uguale a x”
else
strRisultato = “y è maggiore di x”
end if
13/97
Listato 4
If numeroFotoPagina <= 5 then
...
<qui va il codice per visualizzare l’elenco delle foto>
...
else
...
<cambia pagina>
...
end if
14/97
Listato 5
OGGI.ASP
<%@ language="VBScript" %>
<%Option Explicit%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>La mia prima pagina ASP</title></head>
<body>
<%
Dim anno,mese,giorno,data,ore,minuti
anno = year(now())
mese = month(now())
giorno = day(now())
ore = hour(now())
minuti = minute(now())
response.write ("Oggi è il " & giorno & "/" & mese & "/" & anno & ",
ore " & ore & ":" & minuti)
%>
</body>
</html>
15/97
Listato 6
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>La mia prima pagina ASP</title></head>
<body>
Oggi è il 18/8/2003, ore 23:38
</body>
</html>
16/97
Listato 7
OGGI2.ASP
<%@ language="VBScript" %>
<%option explicit%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>La mia prima pagina ASP</title></head>
<body>
<script language="VBScript" runat="server">
Dim anno,mese,giorno,data,ore,minuti
anno = year(now())
mese = month(now())
giorno = day(now())
ore = hour(now())
minuti = minute(now())
response.write ("Oggi è il " & giorno & "/" & mese & "/" & anno & ",
ore " & ore & ":" & minuti)
</script>
</body>
</html>
17/97
Listato 8
DATAUTENTE.ASP
<% if hour(now()) < 16 Then %>
<b>Buongiorno!</b>
<% else %>
<b>Buonasera!</b>
<% end if %>
18/97
Listato 9
NOMECOGNOME.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Un form</title>
</head>
<body>
<b>Inserisci il tuo nome e cognome</b>
<form action="visnomecognome.asp" method="post">
Nome: <input type="text" name="txt_nome"> <br>
Cognome: <input type="text" name="txt_cognome"> <br>
<input type="submit" value="Invia">
</form>
</body>
</html>
19/97
Listato 10
VISNOMECOGNOME.ASP
<%@ language="vbscript" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>Il risultato del form</title></head>
<body>
<%
Dim nome, cognome
nome = request.form("txt_nome")
cognome = request.form("txt_cognome")
response.write ("Ciao <b>" & nome & " " & cognome & "</b>!")
%>
</body>
</html>
20/97
Listato 11
VISDATICOMPLETI.ASP
<%@ language="VBScript" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>Il risultato del form</title></head>
<body>
<%
Dim nome, cognome, sesso, eta, hobby, note
nome = request.form("txt_nome")
cognome = request.form("txt_cognome")
sesso = request.form("rad_sesso")
eta = request.form("sel_eta")
note = request.form("txa_note")
response.write
response.write
response.write
response.write
("Nome: " & nome & "<br>")
("Cognome: " & cognome & "<br>")
("Sesso: " & sesso & "<br>")
("Età: " & eta & "<br>")
For Each hobby in request.form("chk_hobby")
response.write ("Hobby: " & hobby & "<br>")
Next
response.write ("Note: " & note & "<br>")
%>
</body>
</html>
21/97
Listato 12
FOREACH.ASP
<%@ language="VBScript" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>Il risultato del form</title></head>
<body>
<%
Dim campo
For Each campo in request.form
response.write (campo & ": " & request.form(campo) & "<br>")
Next
%>
</body>
</html>
22/97
Listato 13
LINGUA.ASP
<%@ language="VBScript" %>
<%option explicit%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>Response.redirect</title></head>
<body>
<%
Dim strLingua
strLingua=request.querystring("lingua")
select case strLingua
case "it"
response.redirect "/it/default.asp"
case "fr"
response.redirect "/fr/default.asp"
case else
response.redirect "/en/default.asp"
end select
%>
</body>
</html>
23/97
Listato 14
COPYRIGHT.ASP
<%= "Copyright © 2003 Mario Rossi - Oggi è il " & day(now()) &
"/" & month(now()) & "/" & year(now())%>
24/97
Listato 15
INCLUDEFILE.ASP
<%@ language="VBScript" %>
<%option explicit%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>Il sito di Mario Rossi</title></head>
<body>
<h3>Questo è il sito di Mario Rossi</h3>
<h4>Ci trovate alcune foto e il mio weblog</h4>
<!--#include file="copyright.asp"-->
</body>
</html>
25/97
Listato 16
INCLUDEMENU.ASP
<%
Dim strSezione
strSezione = request.querystring("sezione")
%>
<table width="100">
<tr>
<td><h3>Menù</h3></td>
</tr>
<tr>
<td>
<% If strSezione = "" Then %>
<b>Home</b>
<% Else %>
<a href="menuasp.asp">Home</a>
<% End If%>
</td>
</tr>
<tr>
<td>
<% If strSezione = "foto" Then %>
<b>Foto</b>
<% Else %>
<a href="foto.asp?sezione=foto">Foto</a>
<% End If %>
</td>
</tr>
<tr>
<td>
<% If strSezione = "scrivimi" Then %>
<b>Scrivimi</b>
<% Else %>
<a
href="scrivimi.asp?sezione=scrivimi">Scrivimi</a>
<% End If %>
</td>
</tr>
</table>
26/97
2a lezione
A scuola con PC Open
Web Developer ASP
di Antonio Volpon
1 La natura senza stato del Web
a scorsa puntata ci siamo
lasciati dopo aver imparato
perché è utile costruire i siti Web ricorrendo ad un linguaggio lato server, e abbiamo
cominciato ad esplorare il
mondo di ASP, la piattaforma
Microsoft per lo sviluppo di siti dinamici. Lo scopo della nostra esplorazione, e più in generale di questo corso, è quella di aiutare Mario Rossi a costruire un proprio sito personale, un insieme di pagine con
la presentazione dell’autore,
una sezione con le foto e la possibilità di inviare qualche commento. La versione del sito finora realizzata è allo stato embrionale, ma va detto che ci
siamo concentrati più che altro
sulle basi di Visual Basic Script,
il linguaggio che utilizziamo
per costruire pagine ASP. Abbiamo poi introdotto il ruolo di
alcuni oggetti, punti cardine
per poter interagire con i dati
inseriti dagli utenti: l’oggetto
request e response.
In questa puntata, partendo
dagli esempi già visti, introdurremo il ruolo di altri importanti oggetti, come application e
session, fondamentali quando è
necessario memorizzare le
informazioni per tutto il tempo
di comunicazione con l’utente.
L
La comunicazione
fra il browser e il server
Per introdurre i concetti di
questa puntata è necessario
che ci soffermiamo ad analizzare da vicino il funzionamento
della comunicazione tra un
browser e il server Web che
ospita le pagine ASP. Se ricordate quello che abbiamo detto
la scorsa puntata, il browser,
su richiesta dell’utente, contatta il server Web, il quale verifica l’esistenza della pagina richiesta, la esegue, e restituisce
il risultato al browser.
La comunicazione tra il
browser e il server inizia con la
richiesta della pagina e termina
con la ricezione dell’ultimo carattere della risposta. Supponete ora che lo stesso utente richieda una seconda pagina allo
stesso server Web. La probabilità che questo si verifichi è in
effetti elevata (difficilmente navighiamo in Internet visitando
solo la home page dei siti). La
situazione non cambia. Anche
in questo caso la comunicazione è di tipo “mordi e fuggi”: inizia con la richiesta e termina
con la sua esecuzione.
Questo tipo di connessione
si chiama per l’appunto stateless (senza stato) in quanto il
server e il client ristabiliscono
IL CALENDARIO DELLE LEZIONI
Lezione 1:
Da sito statico
a dinamico
Lezione 2:
Campi nascosti in un form
• La durata delle sessioni e
delle applicazioni
• La gestione degli errori
Le prossime puntate
Portare il sito sul server
• La natura senza stato
del Web
• I cookie
• Dai cookie alle sessioni
• L’oggetto “application”
27/97
ogni volta la comunicazione. Il
fatto che la connessione tra il
browser e il server Web duri solo
per lo stretto necessario ha delle
importanti conseguenze, prima fra
tutte l’incapacità
del server di sapere che lo stesso
utente sta richiedendo pagine diverse.
Immaginate di
dover acquistare un libro on line. Difficilmente riuscirete a
completare questa operazione
in un’unica pagina, molto più
probabile che vi capiti di scegliere il libro da un elenco, lo
aggiungiate al carrello, procediate all’acquisto inserendo i
vostri dati e il numero di carta
di credito e riceviate conferma
del buon esito dell’operazione.
Ma se il server chiude la comunicazione ogni volta, com’è
possibile che si ricordi di voi, e
soprattutto dello stato con il
quale vi eravate lasciati? In effetti sono state sviluppate alcune metodologie per cercare di
arginare i problemi derivati dalla mancanza di stato della connessione, e ne analizziamo ora i
due principali.
Lezione 3:
ASP e i database
Lezione 4:
Uso avanzato dei database
In uno degli esempi della
scorsa puntata l’utente del sito
di Mario Rossi aveva la possibilità di comunicare le proprie
impressioni riguardanti il sito
utilizzando un form, simile a
quello di figura 1. Immaginate
che l’invio dei dati non sia l’ultima interazione che l’utente
svolge con il sito, ma che vogliate successivamente chiedergli, nel caso selezioni come
1
Hobby la voce “musica”, qual è
il cantautore preferito. In questo modo, al pari dell’acquisto
su internet, l’interazione tra il
browser e il server non avviene
più su di un’unica pagina, ma
con due pagine distinte. Poiché
la comunicazione viene ogni
volta interrotta, dobbiamo far
sì che il browser “ricordi” al
server come era terminata la
comunicazione precedente, così che i dati già inseriti non
vengano perduti. Per farlo integriamo la seconda pagina con
alcuni campi nascosti nel form,
che compileremo con i dati già
inseriti (listato 1 contenuto nel
CD Guida).
Come possiamo vedere dal
listato, per primo è inserito un
controllo che verifica il contenuto della collezione degli
hobby selezionati dall’utente.
In particolare, poiché è possibile selezionare più di hobby,
vengono man mano verificati
tutti quelli selezionati: se uno
di questi è “Musica”, il valore di
una variabile di supporto pasI listati citati nell’articolo sono
nel CD Guida nella sezione
“Corsi Open Master”
2a lezione
2
sa da false (falso) a true (vero).
A questo punto la pagina visualizza due elementi diversi, a
seconda della selezione. Nel
caso non sia stata selezionata
la voce Musica, la condizione è
false e all’utente viene presen-
tata una semplice
risposta.
Se invece l’utente ha espresso
il suo interesse
per la musica viene presentato un
altro form, nel
quale si chiedono
ulteriori informazioni, ad esempio
il nome del gruppo o del cantante preferiti.
Come abbiamo detto prima,
però, questa pagina è slegata
dalla precedente, e il server
Web non è in grado di mantenere la comunicazione.
Senza prendere degli oppor-
tuni provvedimenti, non siamo
in grado di sapere a quale utente del sito appartiene la preferenza per un cantante o un
gruppo. Per ovviare a questa
problematica nel sorgente della pagina sono stati inseriti dei
campi input, come quelli normalmente utilizzati per richiedere informazioni all’utente. In
questo caso l’attributo type è
però valorizzato con hidden,
ad indicare che nella pagina
questi controlli non saranno visibili. A prima vista potrebbe
sembrare che controlli non visibili siano di poca utilità, ma il
nostro scopo è semplicemente
di usarli e completarli con i da-
ti che l’utente ha inserito nella
pagina precedente. Ce ne rendiamo conto se osserviamo il
sorgente della pagina inviata al
browser, simile a quello presente nel listato 2. Il funzionamento di un campo nascosto è
del tutto simile a quello di un
campo usato per effettuare una
selezione. Quando l’utente indica il nome del cantante o del
gruppo e preme Invia, al server
non viene inviata solo quest’ultima informazione, ma anche i
dati relativi all’utente precedentemente compilati. Ecco
perché la pagina di risposta (figura 2) è in grado di elencare
tutte queste informazioni. di risposta di Mario Rossi potrebbe richiedere al browser di
memorizzare il nome di Giorgio. Le successive pagine del sito di Mario Rossi sono in grado
di interrogare il browser di
Giorgio chiedendo di verificare
se per caso, in passato, sia stato memorizzato il nome dell’utente, e in caso affermativo di
inviare questa informazione al
server.
Il cookie rappresenta quindi
un tipo di informazione che
non si perde ogni volta che viene chiusa la comunicazione tra
browser e server, poiché viene
memorizzata nella macchina
dell’utente e inviata ogni volta
che il server ne faccia richiesta. Per vedere come cambia
l’esempio precedente se decidiamo di utilizzare un cookie al
posto dei campi nascosti potete osservare l’esempio del listato 3. In questo caso i campi
nascosti sono sostituiti dall’istruzione response.cookie(variabile) = valore, che ha lo scopo di far memorizzare al browser una variabile e il relativo
contenuto. Nella pagina di risposta (listato 4), vediamo invece che la semplice istruzione
request.cookie(variabile) serve
per estrarre il contenuto della
variabile.
perduto quando l’utente chiude il browser. Ad ogni cookie è
però possibile associare una
data di scadenza, che indica il
tempo per il quale il browser
memorizza (tipicamente su disco fisso) questa informazione.
Questo tipo di cookie è utile in 2 I cookie
mpiegando i campi nascosti
abbiamo aggirato il limite della comunicazione Web senza
stato, ma anche questa soluzione porta con sé alcune problematiche. Nel caso della libreria on line di cui parlavamo
precedentemente, utilizzare
dei campi nascosti potrebbe rivelarsi una soluzione poco pratica, perché sono molte le
informazioni da memorizzare
nel corso delle selezioni. L’ultima pagina, quella di acquisto
effettivo, dovrebbe contenere
tanti campi nascosti quante sono le informazioni da salvare,
con il rischio di commettere
qualche errore nella costruzione del codice e soprattutto di
appesantire inutilmente la pagina.
Per questo motivo esiste
una diversa soluzione a questo
problema, a cui si ricorre utilizzando le sessioni e i cookie.
Vediamo di capire come operano.
Ogni browser Web (a meno
che l’utente non decida di limitare questa funzionalità modificando le opzioni del browser)
ha la possibilità di salvare sul
computer dell’utente alcune
informazioni
(chiamate
cookie) su richiesta del server.
Si tratta di un semplice file nel
quale gli sviluppatori del sito
possono memorizzare alcune
informazioni, ad esempio il nome dell’utente. Poniamo che
Giorgio visiti il sito di Mario
Rossi, e che compili il form indicando il suo nome. La pagina
I
28/97
Cookie temporanei
e a scadenza
Il tipo di cookie che abbiamo
utilizzato nell’esempio precedente è di tipo temporaneo: il
contenuto delle variabili viene
La privacy e gli utenti
Da quello che abbiamo appena
visto è facile capire come i
cookie siano un ottimo
strumento per memorizzare e
successivamente reperire
informazioni circa i nostri
utenti. Va però detto che nel
corso degli anni ai cookie è
stata associata una nomea
poco edificante, tutto questo
proprio perché sono usati per
memorizzare le preferenze degli
utenti, oltre che dati personali e
sensibili. Cercate quindi di
limitare l’uso dei cookie per le
situazioni in cui il loro impiego
faciliti realmente la navigazione
dell’utente, ed evitate di
memorizzare dati che possano
in qualche modo lederne la
privacy. Ricordate inoltre che
ogni browser che si rispetti dà
all’utente la possibilità di
disabilitare i cookie (figura 3),
per cui non fate affidamento
sul fatto che sia sempre
possibile salvarli sul computer
del visitatore: un sito che si
rispetti deve poter funzionare
anche senza ricorrere ai cookie.
3
2a lezione
situazioni in cui l’utente visita
spesso un sito e non vuole inserire ogni volta alcuni dati ricorrenti, come ad esempio
quelli di autenticazione.
Un’altra situazione è data
dai siti che riescono in questo
modo a capire quante volte
ogni singolo utente torna a vi-
sitare il loro sito. Si tratta di
un’informazione molto interessante in termini di marketing
Web, perché misura non solo il
numero di pagine visitate, ma
fornisce una stima molto verosimile legata al singolo visitatore. Il caso del nostro Mario
Rossi è però molto più semplice: a Mario inte4 ressa semplicemente presentare
una scritta sulla
home page che
saluti il visitatore
affezionato, come
vediamo in figura
4.
Il listato 5 affronta questa problematica. Abbiamo introdotto una
modifica alla home page del sito di Mario Rossi, così che distingua l’utente alla prima visita rispetto all’utente abituale.
Come prima cosa verifichiamo se è stato salvato un cookie
chiamato numerovisite. Se così
non è, prepariamo una stringa
contenente il messaggio per il
nuovo visitatore. Se è un utente abituale questo ha un cookie
memorizzato sul computer e
ne estraiamo il valore, cioè il
numero di volte che l’utente ha
visitato questa pagina. In ognuno dei due casi salviamo una
copia del cookie sulla macchina dell’utente incrementando
di 1 il valore corrente. Subito
dopo, con il metodo Expired
della collezione cookies andiamo ad indicare la data di sca-
denza del cookie, in notazione
inglese (e quindi il 31 dicembre
del 2004).
Dopo questa data il cookie
sarà cancellato definitivamente
dalla macchina. Per provare il
funzionamento visualizzate la
pagina sul vostro browser e ricaricatela per alcune volte: vedrete aumentare il contatore.
Adesso chiudete tranquillamente il browser e successivamente provate a caricare nuovamente la pagina: vi accorgerete che l’informazione sul numero di visite non riparte da
zero, ma dall’ultimo valore salvato.
È evidente che il cookie è
stato memorizzato nel vostro
computer e non è andato perso
con la chiusura del browser. 3 Dai cookie alle sessioni
inora abbiamo parlato della
mancanza di stato nella comunicazione tra server e
client e di quali accorgimenti è
possibile adottare per superare questo limite (campi nascosti in un form e cookie). La tecnologia ASP, insieme a IIS (Internet Information Services) rende disponibile un’altra interessante possibilità, che si basa
sull’uso di cookie temporanei:
le sessioni.
Di norma, quando un utente
richiede la prima pagina di un
sito realizzato in ASP, il server
IIS tenta di inviare un cookie di
sessione. Il contenuto del
cookie non è nient’altro che
una lunga stringa generata dal
server in modo casuale, in modo da limitare al massimo la
possibilità che due utenti del
sito utilizzino contemporaneamente la stessa stringa. A questo punto il server ha la possibilità di salvare in una propria
area di memoria quelle informazioni riguardanti l’utente
che è comodo avere sempre a
disposizione (come il suo nome utente, il carrello elettronico e così via). Etichetta questa
area di memoria con la stessa
stringa che ha inviato all’utente. Ogni volta che l’utente richiede una pagina del sito il
server interroga il browser e riceve il contenuto del cookie
(chiamato cookie di sessione),
ed estrae le informazioni che
sono state etichettate con la
F
29/97
stessa stringa. È un po’ come
se l’utente disponesse dell’unica chiave in grado di aprire la
serratura di un lucchetto che
custodisce i proprio dati. Il
vantaggio di usare le sessioni
invece dei soli cookie temporanei è che le informazioni non
sono salvate sul computer dell’utente, dove esistono dei limiti di dimensioni per i dati
che è possibile memorizzare,
ma direttamente sul server, soluzione che migliorare le prestazioni. L’unica informazione
che il browser dell’utente deve
recepire è la stringa generata
casualmente, e nient’altro.
Le sessioni in ASP
Ma come si usano le sessioni
in ASP? Vediamo un esempio,
che trovate nella cartella
cookie degli esempi inclusi nel
CD Guida che accompagna la
rivista. Si tratta di una variazione della pagina che finora
abbiamo realizzato per Mario
Rossi. In particolare, se eseguite il file personalizza.asp (riportato nel listato 6), vi trovate
di fronte ad un form per modificare il colore di sfondo dell’intero sito (il form lo abbiamo
riportato in figura 5). Selezionate a questo punto un colore
e inviate i dati: come era lecito
aspettarsi, il colore di sfondo è
stato variato secondo la vostra
scelta. Non solo: se selezionate
altre sezioni dalla barra di navigazione posta sulla sinistra
(in figura 6 presentiamo la sezione che conterrà le
foto di Mario Rossi), il colore selezionato
viene
mantenuto.
Passiamo ad
analizzare il codice di personalizza.asp per capire
come è stata realizzata. Lasciamo
stare per un attimo cosa succede
all’inizio della pagina e concentriamoci sul codice
che segue l’inclusione di includemenu.asp. Qui è
presente un form
contenente l’elenco dei colori disponibili. La action del form, che
come abbiamo visto la scorsa
puntata serve per indicare la
pagina a cui dirigersi una volta
premuto il pulsante di invio,
contiene una particolarità.
L’action corrisponde infatti alla
stessa pagina personalizza.asp,
il che vuol dire che dopo aver
inviato i dati del form viene ricaricata la stessa pagina. Potrebbe a prima vista sembrare
che questa operazione vanifichi tutti i propositi di estrarre il
colore selezionato, ma non è
così.
Se guardate quello che suc-
5
6
cede proprio prima del form,
noterete la presenza di una
condizione, la quale si preoccupa di verificare in quale dei
due possibili stati (prima di inviare il form, dopo aver inviato
il form) si trova la pagina. Viene
in particolare estratto il valore
del campo colore: se il contenuto è una stringa vuota vuol
dire che la pagina è stata selezionata digitandone il link nella
barra degli indirizzi del browser o semplicemente selezionando un link dal menu sulla sinistra, altrimenti è caricata do-
7
po aver inviato il form.
Nel primo caso si invita l’utente a selezionare il colore
(Seleziona un colore di sfondo),
nel secondo caso lo avvertiamo della selezione compiuta
(Ho cambiato il colore di sfondo
di tutte le sezioni secondo la tua
scelta). La tecnica che abbiamo
appena visto, dove la pagina di
partenza e di destinazione di
un form è la medesima, viene
spesso usata da chi sviluppa siti Web.
I vantaggi di questo tipo di
soluzione sono diversi. Per prima cosa la pagina da gestire è
unica: se un domani volete aggiungere un nuovo campo, dovete aggiornare una sola pagina. Non solo: se avete necessità di controllare i dati inseriti
dall’utente, e questo commette
qualche errore, potete agevolmente presentare dopo l’elenco degli errori il form di partenza, come tra l’altro succede
nel nostro caso (anche se con
un include avreste probabilmente potuto ottenere lo stes-
so risultato). Rimane a questo
punto da vedere
come viene memorizzato il valore del colore per
tutte le pagine del
sito. In testa alla
pagina, poco dopo il titolo, viene
replicata la stessa
condizione.
In
questo caso lo
scopo è diverso:
abbiamo utilizzato un cookie, che
viene memorizzato poco dopo
aver cambiato il colore di sfondo. La sintassi d’uso è semplicissima: si tratta di indicare un
nome da passare all’oggetto
Session e di specificare un valore (come nell’esempio, dove
viene utilizzato Session(“colore”) = valore).
Dopo aver compilato il form,
il valore della variabile colore
memorizzata nella sessione
viene utilizzato per modificare
l’attributo bgcolor del tag body,
così da cambiare il colore di
sfondo della pagina. Tutte le altre pagine del sito non devono
far altro che includere la stessa
porzione di codice poiché la
sessione viene ereditata da tutte le pagine di navigazione dell’utente.
La durata delle sessioni
Come sappiamo, non appena è stata inviata all’utente la
pagina richiesta, la comunicazione termina. Quando l’utente
richiede una seconda pagina, il
meccanismo non cambia. Se il
server mantiene in sessione i
dati dell’utente, deve però aver
modo di liberare la memoria riservata quando l’utente ha richiesto l’ultima pagina del sito,
per esempio chiudendo il
browser o proseguendo la navigazione in un altro sito.
In realtà il server non ha modo di sapere l’ultima pagina
che l’utente richiederà, ma si
comporta in un altro modo. Se
non riceve richieste dal browser per un po’ di tempo ipotizza che l’utente abbia abbandonato il sito, e di conseguenza
elimina la sessione (timeout).
Il tempo durante il quale il
server “aspetta” un’ulteriore richiesta è configurabile sia come parametro da script (con
l’istruzione session.timeout =
minuti), sia come voce nella
maschera di Internet Information Services (figura 7).
Da questo ne consegue che
se l’utente non utilizza il sito
per un certo lasso di tempo (diciamo che va a prendersi un
caffé, oppure sta compilando
un form che gli richiede di ricercare alcuni dati integrativi),
al suo ritorno la sessione potrebbe essere scaduta, e tutte
le informazioni memorizzate
sono di conseguenza perse.
Per questo motivo, in base al tipo di sito e soprattutto alla
complessità delle pagina, il
tempo di timeout delle sessioni
deve essere attentamente valutato. Più aumenta la complessità di compilazione delle pagine e più tolleranti è necessario
essere nei confronti dei nostri
visitatori.
4 L’oggetto application
bbiamo appena visto che
l’oggetto session è un ottimo aiuto quando vogliamo memorizzare informazioni
sulla navigazione e sulle scelte
dell’utente. Per ogni visitatore
del sito viene salvata una copia
delle variabili usate per la sessione, sincronizzate con il
browser dell’utente per mezzo
della stringa casuale. Ma dove
possiamo invece salvare e recuperare alcune informazioni
comuni a tutti gli utenti del sito, come ad esempio il copyright, piuttosto che i parametri
di connessione a una base di
dati, oppure alcune costanti da
A
30/97
usare in tutte le pagine?
Per questi scopi esiste un altro oggetto, simile in tutto e
per tutto all’oggetto session,
ma che si occupa di memorizzare informazioni condivise:
l’oggetto application.
Supponiamo che non vogliate dare a tutti la possibilità di
modificare il colore di sfondo
delle pagine, ma solo ad alcuni
utenti registrati. Modifichiamo
allora la pagina di personalizzazione perché richieda un nome utente ed una password.
Come per tutti gli altri esempi,
trovate i file di questo esercizio
nel CD allegato, sotto la cartel-
la Application. Aprite con il
browser l’indirizzo del file menuasp.asp, la pagina di partenza dell’esercizio.
La situazione dovrebbe essere quella di figura 8. Nulla
sembra cambiato rispetto agli
esempi precedenti, ma se provate a selezionare la voce Personalizza dal menu di sinistra,
noterete che a questo punto vi
viene chiesto di inserire un nome utente e password per l’autenticazione (figura 9). Se provare ad inserire alcuni valori
casuali e procedete, il sistema
nega l’accesso alla pagina di
configurazione. Adesso tor- 2a lezione
8
nate con il browser alla pagina
di menù e riprovate a selezionare la voce Personalizza, ma
questa volta inserite i valori
corretti per poter procedere:
Mario con nome utente e foo
come password (senza le doppie virgole).
A questo punto avete accesso alla pagina di personalizzazione e potete, analogamente
all’esempio precedente, modificare il colore di sfondo che vi
accompagnerà per tutta la navigazione di questo piccolo sito.
L’analisi del codice
Analizziamo il codice che
rende possibile tutto questo.
Per prima cosa verifichiamo il
contenuto di menuasp.asp, la
prima pagina che visualizzia-
mo nella finestra
del browser (listato 7). L’unica piccola, ma fondamentale modifica
è data dall’uso in
testa alla pagina
di due variabili di
applicazione:
utente e password.
Lo scopo di
queste due variabili è contenere gli
unici valori per i
quali sarà garantito l’accesso
alla pagina di configurazione.
Poiché le variabili di applicazione sono disponibili a tutte le
pagine del sito e a tutti gli utenti, una volta che le abbiamo definite in questa pagina, ogni altra pagina del sito è in grado di
accedere al loro contenuto.
Non è la situazione ottimale,
ma vedremo in seguito come
migliorarla. Passiamo adesso
alle altre pagine.
È bene notare che il link alla
voce personalizza presente nel
menu di sinistra non conduce
più, come nell’esempio precedente, alla pagina personalizza.asp, ma a loginpersonalizza.asp. Si tratta della pagina che
contiene il form per l’autenticazione (listato 8). È una pagina
semplicissima,
che non contiene
alcuna nuova linea
di codice rispetto
a quello che già
sappiamo realizzare. Diamo solo
un’occhiata all’attributo action del
form, che conduce alla pagina personalizza.asp. Il
percorso è quindi
questo: dal menu
a sinistra si procede alla pagina
loginpersonalizza.asp e una volta inserito il nome utente e la
password si passa a personalizza.asp.
Da quanto detto è chiaro che
sarà personalizza.asp a verificare se l’utente ha le carte in
regola per essere autenticato o
meno, per cui passiamo ad analizzarne il contenuto (listato 9).
L’unica modifica rispetto alla
versione precedente della pagina si trova all’inizio: per prima cosa memorizziamo in sessione il nome utente e la password inviati dall’utente dopo
la compilazione del form. A
questo punto confrontiamo i
valori inseriti dall’utente con
quelli presenti nelle variabili
salvate nell’oggetto Application: se i valori coincidono l’u-
9
tente ha fornito correttamente
gli estremi per l’autenticazione.
La condizione che verifica questa situazione (che comincia
con if Session("utente") = Application("utente")) termina
molte righe dopo, in particolare dopo il form per la scelta del
colore. Questo vuol dire che
solo nel caso di autenticazione
andata a buon fine presentiamo all’utente la possibilità di
variare il colore di sfondo.
Alla fine della pagina vediamo invece cosa succede se
questo non si verifica, cioè se
l’utente ha fornito dei dati non
corretti ai fini dell’autenticazione. In questo caso visualizziamo semplicemente un’indicazione della mancata autorizzazione (Attenzione: accesso
non consentito).
5 La durata delle sessioni e delle applicazioni
bbiamo visto precedentemente che la durata delle
sessioni dipende dal valore di timeout con cui abbiamo
configurato IIS oppure specificato esplicitamente nella pagina ASP. Ma quanto durano gli
oggetti salvati nell’oggetto Application, che sono comuni a
tutti gli utenti? In questo caso
la loro vita termina quando viene fermato e poi riavviato il
servizio di IIS, cioè quando il sistemista decide esplicitamente
di far ripartire il sito Web. La
A
31/97
stessa cosa avviene per le sessioni: anche queste sono eliminate in caso di riavvio del servizio IIS. Ce ne rendiamo conto
con un semplice esempio. Lanciate l’ultimo esercizio che abbiamo realizzato e cambiate il
colore di sfondo delle pagine.
A questo punto aprite la console di Internet Information
Services (in Windows 2000 Professional la trovate partendo
dal Control Panel, selezionando
Administrative Tools e successivamente Internet Information
Services).
10
Selezionate l’icona del vostro
computer nel pannello di sinistra e
attivate il menu
contestuale con il
tasto destro del
mouse (la situazione dovrebbe
essere simile a
quella riportata in
figura 10). La voce
All Tasks contiene
la sottovoce Restart IIS, che potete selezionare, in
modo da arrivare
alla situazione riportata in figura
11. Confermate la
selezione e dopo
qualche secondo
il server verrà
riavviato.
Se a questo punto ritornate
alla finestra del browser, e navigate utilizzando il menu di sinistra, noterete che il colore di
sfondo ritorna quello precedente alla sezione.
Questo si verifica perché
riavviando il server le variabili
memorizzare in sessione e nell’oggetto Application sono state eliminate, con conseguente
perdita di tutti i riferimenti al
colore di sfondo e all’utente registrato.
11
Aggiornamenti concorrenti
È necessario prestare particolare attenzione quando si modificano le variabili memorizzate con l’oggetto application.
Mentre la sessione è diversa
per ogni utente, gli oggetti salvati a livello di applicazione sono condivisi da chiunque visiti
il sito: cosa succede se 2 utenti
tentano di cambiare contemporaneamente il valore dell’oggetto application? Buona norma sarebbe indicare ad ASP che solo
un utente alla volta può modificare il valore delle variabili di
applicazioni. Per farlo si usano
due semplici istruzioni: Application.Lock poco prima di modificare il valore e Application.Unlock subito dopo.
Usare il file global.asa
L’esercizio che abbiamo appena realizzato soffre in realtà
di un piccolo, ma fondamentale
difetto. Fino a quando un utente non visita la pagina menuasp.asp il nome utente e password di Mario non sono memorizzati nelle corrispettive variabili dall’oggetto Application.
Questo vuol dire che se fermate
il servizio IIS come abbiamo visto poco fa (per cancellare il
contenuto di tutte le variabili) e
aprite per prima cosa la pagina
loginpersonalizza.asp (o qualsiasi altra ad eccezione di menuasp.asp), nell’oggetto application non sono memorizzati i
valori Mario e foo. Per rendervene conto compilate con i dati corretti il form e premendo Invia. Non c’è nulla da fare: anche
inserendo i valori per cui vi
aspettereste l’autenticazione,
la risposta della pagina sarà
sempre negativa. Potreste pensare che non si tratta poi di un
problema grave: in fondo è la
prima pagina del sito quella da
cui ogni utente comincia l’esplorazione. In realtà non è vero: anche se le home page sono
solitamente le pagine più viste
di un sito, l’utente può teoricamente cominciare la navigazione da qualsiasi punto.
Motori di ricerca
Provate a fare una ricerca su
Google per un argomento di interesse: non è detto che il motore di ricerca vi conduca alla
home page del sito. Il problema
che dobbiamo affrontare è quindi il seguente: le variabili dell’oggetto application (e, a volte,
anche quelle dell’oggetto session) dovrebbero essere memorizzate indipendentemente dalle pagine del sito. Potremmo
pensare di inserire questi valori
in ogni pagina: in questo modo
saremmo certi che, indipendentemente dalla prima pagina richiesta dal browser utente, le
variabili siano lette correttamente. In realtà la situazione è
impraticabile, soprattutto perché i costi in termini di gestione
sarebbero elevati nel caso di siti con decine di pagine: cosa fare se a un certo punto avete bi-
32/97
sogno di un’altra variabile?
La tecnologia ASP ci viene
fortunatamente incontro e offre
la possibilità di impiegare in un
unico file tutte le variabili che
vogliamo includere negli oggetti application e session. Questo
file, che si dovrà chiamare global.asa è letto ogni volta che IIS
parte, e le variabili sono memorizzate rispettivamente negli oggetti application e session. Modifichiamo quindi l’esempio per
includere questo tito di soluzione, prelevando i file dalla cartella globalasa del CD Guida.
Perché la prova funzioni correttamente è necessario copiare il
file global.asa dalla cartella appena indicata nella directory
principale che contiene tutti i
nostri esempi ASP.
Questa operazione è necessaria perché IIS verifica la presenza del file global.asa solo nella directory principale del nostro sito, e non in eventuali sottocartelle. Riavviate IIS e caricate nel browser la pagina loginpersonalizza.asp, senza passare per la home del sito (a dire
il vero potete anche farlo, visto
che abbiamo tolto ogni riferimento alle variabili Application). Se provate ad autenticarvi, passerete il controllo senza
alcun problema.
Non solo: rispetto all’esempio precedente potete caricare
qualsiasi pagina e l’effetto sarà
il medesimo, non rischiate alcuna altra sorpresa. Il motivo di
questo comportamento deriva
dal fatto che le variabili di applicazione contenenti il nome
utente e la password corretti
non sono più memorizzate nelle
singole pagine, ma centralizzate
nel file global.asa. Diamo un’occhiata al file global.asa per capire come costruirlo: abbiamo riportato il codice nel listato 10.
La struttura è del tutto simile ad
una parte di codice che possiamo inserire in qualsiasi pagina
ASP. Si riconoscono a vista d’occhio le definizioni delle variabili e il valore che gli viene associato. L’unica particolarità è la
presenza della procedura Application_OnStart. Il nome non è
casuale, ma è un modo per indicare a IIS quando eseguire le
istruzioni contenuti in questa
porzione del file global.asa.
Come potete facilmente immaginare, il codice in questo
caso viene richiamato alla partenza dell’applicazione Web, nel
nostro caso quando avviamo o
riavviamo Internet Information
Services. Quando questo evento
si verifica viene caricato il file
global.asa e se la ricerca per la
procedura Application_OnStart
ha esito positivo, si eseguono
tutte le istruzioni che la compongono. È quindi particolarmente comodo per lo sviluppatore utilizzare il file global.asa
come accentratore delle porzioni di codice da eseguire ogni
volta che parte l’applicazione. Il
file global.asa può essere in
realtà utilizzato non solo in questo contesto, ma anche quando
l’applicazione viene arrestata,
oppure per l’inizio e la fine di
una sessione (in questo caso le
procedure sono rispettivamente Application_End, Session_ OnStart e Session_OnEnd).
Ci si potrebbe chiedere che
senso ha eseguire delle istruzioni quando l’applicazione o la
sessione cessano di esistere,
ma ci sono casi in cui questi
eventi hanno senso. Pensate
per esempio a un’applicazione
di una certa complessità, che
per motivi di efficienza mantenga nell’oggetto application, senza mai salvarli, alcuni dati. Non
appena l’applicazione, per qualsiasi motivo, viene fermata, è
necessario memorizzare sul disco fisso le informazioni volatili: per farlo non c’è altro posto
se non la procedura Application_End. Un altro motivo potrebbe essere chiudere esplicitamente eventuali connessioni
alle basi di dati oppure liberare
la memoria da oggetti indesiderati.
Le variabili e la
memorizzazione sul sito
Gli esempi che abbiamo realizzato fino ad ora salvano nell’oggetto application il nome e la
password dell’utente che ha
l’autorizzazione per personalizzare lo sfondo della pagina. Una
soluzione migliore, e più generale, consisterebbe nel salvare
queste informazioni in una base
di dati, in modo da poter realizzare più profili di utenza e di
centralizzare il sistema che si
preoccupa di gestire dati personali e sensibili. Non abbiamo
optato per questa soluzione solo perché era importante concentrarci sul ruolo delle sessioni e dell’applicazione nello sviluppo con ASP, ma nella prossima puntata affronteremo invece
lo studio delle basi di dati, per
cui non dovete attendere ancora molto per capire come funziona questo mondo.
2a lezione
6 La gestione degli errori in ASP
n Visual Basic Script, così come in tutti i linguaggi di programmazione, è molto importante garantire che il codice non
produca risultati inattesi neppure quando si verificano degli errori di funzionamento. Normalmente, se non ci preoccupiamo
di gestire gli errori, la pagina
ASP non ha alcuna alternativa se
non quella di terminare immediatamente l’esecuzione. Tra i file di esempio trovate errore.asp:
come dice il nome, si tratta di
una pagina ASP che genera un
errore (listato 11).
È presente infatti un ciclo for
next che divide il contenuto di
una variabile (posta a 1000) con
quello di un’altra variabile, che
viene incrementata in modo
che il suo valore passi da -10 a
10. Questo però non si verifica
perché non appena si tenta di
eseguire una divisione per zero
si scatena una condizione di errore e l’esecuzione della pagina
si interrompe (figura 12).
I
Le contromisure
Per cautelarsi da questo tipo
di “disavventure” è buona abitudine, nelle parti critiche del
codice, verificare se siamo entrati in condizione di errore, e
reagire conseguentemente. Un
primo metodo è l’introduzione
dell’istruzione on error resume
next, praticamente una frase
che potremmo tradurre come
“in caso di errore prosegui oltre”. In effetti è proprio questo
che si verifica: dal punto in cui è
inserita questa istruzione ogni
errore viene ignorato e l’esecu-
33/97
zione del codice prosegue dalla
riga successiva. Per rendersi
conto di cosa succede potete
eseguire una versione modificata dell’esempio precedente, erroreresume.asp (listato 12).
Questa volta, non appena viene eseguita la riga con la divisione per zero il codice non si
arresta, ma continua la sua esecuzione dalla riga successiva
(figura 13). Potrebbe a prima vista sembrare che in questo modo tutti i nostri problemi abbiano trovato soluzione. In realtà il
fatto che si verifichi una situazione imprevista, e che il codice
si arresti, spesso indica che il
problema sta a monte che va risolto.
Immaginate di chiedere ad
un utente di inserire il proprio
nome e anno di nascita, e di voler calcolare l’età della persona.
La situazione è illustrata in figura 14. Provate a richiamare il file con il browser (si chiama annoeta.asp) e a compilare il form
con dati congruenti. La pagina
di risposta vi risponde conseguentemente (figura 15). Fino a
quando l’utente inserisce un valore numerico nel secondo campo non ci sono problemi nel
calcolare l’età, ma poiché non
avete controllo sull’input del visitatore, può anche darsi che
questo inserisca dei caratteri al
posto dell’anno, come vediamo
in figura 16. Il risultato di questa
situazione inattesa è un errore
della pagina (figura 17).
Se guardiamo il codice della
pagina di risposta (annoetarisposta. asp, listato 13) notiamo
che viene eseguita
12 la funzione cint sul
valore del campo
anno di nascita. Lo
scopo della funzione cint è di convertire una variabile di tipo Variant
13 (che, come dicevamo nella prima
puntata del corso,
è l’unico vero tipo
14 dato con cui lavora Visual Basic
Script) in un sottotipo numerico intero. Questa funzione si aspetta in
ingresso una stringa che però contenga esclusivamente numeri: se
non è così restituisce sistematicamente un errore.
Ecco spiegato perché nel secondo
caso l’esecuzione
della pagina viene
interrotta.
Per evitare questa conseguenza è
necessario capire
se si è verificato
un errore, e agire
di conseguenza.
Integriamo quindi
il codice di questa
pagina in modo
da farlo diventare
il contenuto del listato 14, che si riferisce al file
annoetarisposta2.asp. Per prima cosa è necessario inserire,
poco prima della riga con la
funzione cint, l’istruzione on error resume next. Si
tratta di un’operazione necessaria,
pena l’arresto non
appena si verifica
la condizione di
errore. La vera novità si trova nel codice che segue la funzione cint e
coinvolge l’oggetto Err. Quest’ultimo è un oggetto interno di
VBScript che in caso di errore
viene creato con informazioni
dettagliate sulla problematica
riscontrata. Tra i metodi di questo oggetto due si rivelano particolarmente importanti: Description e Number. Il primo presenta una descrizione del problema che si è verificato, mentre il secondo è un numero univoco per ogni errore. All’interno
della nostra pagina verifichiamo quindi, come prima cosa, se
l’oggetto Err esiste, il che indica
la presenza di un errore nella
pagina. A questo punto, senza
che l’esecuzione della pagina si
interrompa bruscamente, abbiamo tutto il tempo di informare il visitatore del verificarsi
di una situazione inattesa, come
è possibile vedere in figura 18.
Sta a noi decidere quali informazioni presentare all’utente,
ma in questo caso abbiamo
scelto di visualizzare il dettaglio
dell’errore e il suo codice. Non
solo: poiché il codice di errore è
univoco, e 13 si riferisce a Type
Mismatch (ovvero, è stato usato
un tipo di dato diverso da numerico nel richiamare la funzio-
15
16
17
18
ne cint), possiamo inserire una
condizione per dare qualche indicazione aggiuntiva all’utente.
Conclusioni
Nel corso di queste due puntate abbiamo cercato di proporvi alcuni significativi esempi
di base per la programmazione
Visual Basic Script in riferimento alla piattaforma ASP. Siete
ora in grado di realizzare qualunque tipo di sito abbiate in
mente, anche se all’aumentare
della complessità, quando il tipo e numero di dati da gestire
aumenta, avrete bisogno di affidarvi ad una base di dati per
memorizzare ed estrarre informazioni. Fino ad ora, in effetti, ci
siamo concentrati sui fondamenti del linguaggio e su una
descrizione degli oggetti coinvolti. Il pregio di una piattaforma come ASP è però la possibilità di colloquiare in modo trasparente e tutto sommato semplice con le basi di dati. E nella
prossima puntata affronteremo
per l’appunto il mondo delle basi dati relazionali, introducendo
qualche concetto fondamentale
per capirne il funzionamento e
lo scopo, per poi passare all’integrazione con ASP.
Cliccate qui per accedere alla versione elettronica dei listati. Si aprirà una pagina Web con i
link ai listati delle quattro puntate del corso. Cliccate sul link desiderato e selezionate "Salva"
dalla finestra visualizzata da Internet Explorer per indicare dove volete salvarli. Gli esempi
sono in formato ASP e perciò non direttamente visualizzabili nel browser a meno di avere
installato o attivato il servizio di Internet Information Server sul vostro PC, nella versione per
client Windows XP.
LISTATO 1
DATICOMPLETI2.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Un form</title>
</head>
<body>
<%
Dim strHobby
Dim blnMusica
blnMusica = false
strHobby = request.form("chk_hobby")
For Each hobby in request.form("chk_hobby")
If hobby = "Musica" Then
blnMusica = true
End If
Next
%>
<% if blnMusica = true Then %>
<p>Caro <%=request.Form("txt_nome")%>, ho visto che ti interessi di musica. Ti
dispiace indicarmi il nome del tuo cantante o gruppo preferito?</p>
<form action="visdaticompleti2.asp" method="post">
<input type="hidden" name="txt_nome" value="<%=request.Form("txt_nome")%>">
<input type="hidden" name="txt_cognome"
value="<%=request.Form("txt_cognome")%>">
<input type="hidden" name="rad_sesso" value="<%=request.Form("rad_sesso")%>">
<input type="hidden" name="sel_eta" value="<%=request.Form("sel_eta")%>">
<input type="hidden" name="chk_hobby" value="<%=request.Form("chk_hobby")%>">
<input type="hidden" name="txa_note" value="<%=request.Form("txa_note")%>">
Cantante o gruppo preferito <input type="text" name="txt_cantante">
<input type="submit" value="Invia">
</form>
<% else %>
<p>Grazie per aver inviato i tuoi commenti, peccato non ti interessi di
musica!</p>
<% end if %>
34/97
</body>
</html>
35/97
LISTATO 2
SORGENTI DI DATICOMPLETI2.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Un form</title>
</head>
<body>
<p>Caro Mario, ho visto che ti interessi di musica. Ti dispiace indicarmi il
nome del tuo cantante o gruppo preferito?</p>
<form action="visdaticompleti2.asp" method="post">
<input
<input
<input
<input
<input
<input
type="hidden"
type="hidden"
type="hidden"
type="hidden"
type="hidden"
type="hidden"
name="txt_nome" value="Mario">
name="txt_cognome" value="Rossi">
name="rad_sesso" value="M">
name="sel_eta" value="0-20">
name="chk_hobby" value="Musica">
name="txa_note" value="Ecco qualche nota">
Cantante o gruppo preferito <input type="text" name="txt_cantante">
<input type="submit" value="Invia">
</form>
</body>
</html>
36/97
LISTATO 3
DATICOMPLETICOOKIE2.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Un form</title>
</head>
<body>
<%
Dim strHobby
Dim blnMusica
blnMusica = false
strHobby = request.form("chk_hobby")
For Each hobby in request.form("chk_hobby")
If hobby = "Musica" Then
blnMusica = true
End If
Next
response.cookies("txt_nome") = request.Form("txt_nome")
response.cookies("txt_cognome") = request.Form("txt_cognome")
response.cookies("rad_sesso") = request.Form("rad_sesso")
response.cookies("sel_eta") = request.Form("sel_eta")
response.cookies("chk_hobby") = request.Form("chk_hobby")
response.cookies("txa_note") = request.Form("txa_note")
%>
<% if blnMusica = true Then %>
<p>Caro <%=request.Form("txt_nome")%>, ho visto che ti interessi di musica. Ti
dispiace indicarmi il nome del tuo cantante o gruppo preferito?</p>
<form action="visdaticompleticookie2.asp" method="post">
Cantante o gruppo preferito <input type="text" name="txt_cantante">
<input type="submit" value="Invia">
</form>
<% else %>
<p>Grazie per aver inviato i tuoi commenti, peccato non ti interessi di
musica!</p>
<% end if %>
</body>
</html>
37/97
LISTATO 4
VISDATICOMPLETICOOKIE2.ASP
<%@ language="vbscript" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>Il risultato del form</title></head>
<body>
<%
Dim nome, cognome, sesso, eta, hobby, note, cantante
nome = request.cookies("txt_nome")
cognome = request.cookies("txt_cognome")
sesso = request.cookies("rad_sesso")
eta = request.cookies("sel_eta")
note = request.cookies("txa_note")
cantante = request.cookies("txt_cantante")
response.write
response.write
response.write
response.write
response.write
("Nome: " & nome & "<br>")
("Cognome: " & cognome & "<br>")
("Sesso: " & sesso & "<br>")
("Età: " & eta & "<br>")
("Cantante: " & cantante & "<br>")
For Each hobby in request.form("chk_hobby")
response.write ("Hobby: " & hobby & "<br>")
Next
response.write ("Note: " & note & "<br>")
%>
</body>
</html>
38/97
LISTATO 5
MENU.ASP
<%Option Explicit%><%
Dim numVisite
Dim strMessaggio
numVisite = request.cookies("numerovisite")
if numVisite = "" then
numVisite = 1
strMessaggio = "Benvenuto nel sito di Mario Rossi. Grazie per la tua
visita!"
else
numVisite = numVisite + 1
strMessaggio = "Bentornato nel sito di Mario Rossi. Questa è la " &
numVisite & " volta che visiti questa pagina!"
end if
response.cookies("numerovisite") = numVisite
response.cookies("numerovisite").Expires = #12/31/2004#
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Il sito di Mario Rossi</title>
</head>
<body>
<table width="100%" border="1" cellpadding="0" cellpadding="2">
<tr>
<td width="100">
<table width="100">
<tr>
<td><h3>Menù</h3></td>
</tr>
<tr>
<td><a href="home.asp">Home</a></td>
</tr>
<tr>
<td><a href="foto.asp?sezione=foto">Foto</a></td>
</tr>
<tr>
<td><a href="scrivimi.asp?sezione=scrivimi">Scrivimi</a></td>
</tr>
</table>
</td>
<td>
<div align="center"><%=strMessaggio%></div>
</td>
</tr>
</table>
</body>
</html>
39/97
LISTATO 6
COOKIE/PERSONALIZZA.ASP
<%
if request.QueryString("colore") <> "" then
Session("colore") = request.QueryString("colore")
end if
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Il sito di Mario Rossi</title>
</head>
<% if Session("colore") <> "" then %>
<body bgcolor="<%=Session("colore")%>">
<% else %>
<body>
<% end if %>
<table width="100%" border="1" cellpadding="0" cellpadding="2">
<tr>
<td width="100">
<!--#include file="includemenu.asp"-->
</td>
<td align="center">
<% if request.QueryString("colore") = "" then %>
Seleziona un colore di sfondo
<% else %>
Ho cambiato il colore di sfondo di tutte le sezioni secondo la tua scelta
<% end if %>
<form action="personalizza.asp" method="get">
<select name="colore">
<option value="#FFFF99">giallo</option>
<option value="#FFCCCC">rosa</option>
<option value="#66CCFF">celeste</option>
<option value="#FFFFFF">bianco</option>
</select>
<input type="hidden" name="sezione" value="personalizza">
<input type="submit" value="Seleziona">
</form>
</td>
</tr>
</table>
</body>
</html>
40/97
LISTATO 7
APPLICATION/MENUASP.ASP
<%
Application("utente") = "Mario"
Application("password") = "foo"
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Il sito di Mario Rossi</title>
</head>
<% if Session("colore") <> "" then %>
<body bgcolor="<%=Session("colore")%>">
<% else %>
<body>
<% end if %>
<table width="100%" border="1" cellpadding="0" cellpadding="2">
<tr>
<td width="100">
<!--#include file="includemenu.asp"-->
</td>
<td><h1><div align="center">Questa è la Home Page del sito</div></h1></td>
</tr>
</table>
</body>
</html>
41/97
LISTATO 8
APPLICATION/LOGINPERSONALIZZA.ASP
<%
if request.QueryString("colore") <> "" then
Session("colore") = request.QueryString("colore")
end if
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Il sito di Mario Rossi</title>
</head>
<% if Session("colore") <> "" then %>
<body bgcolor="<%=Session("colore")%>">
<% else %>
<body>
<% end if %>
<table width="100%" border="1" cellpadding="0" cellpadding="2">
<tr>
<td width="100">
<!--#include file="includemenu.asp"-->
</td>
<td align="center">
<strong>Login al sito</strong>
<form action="personalizza.asp" method="get">
<strong>Nome Utente</strong>: <input type="text" name="utente"
size="20"><br />
<strong>Password</strong>: <input type="password" name="password"
size="20"><br />
<input type="hidden" value="personalizza">
<input type="submit" value="Invia">
</form>
</td>
</tr>
</table>
</body>
</html>
42/97
LISTATO 9
APPLICATION/PERSONALIZZA.ASP
<%
' Estraggo il nome utente e la password inseriti dall'utente e li salvo in
sessione
if request.QueryString("utente") <> "" then
Session("utente") = request.QueryString("utente")
Session("password") = request.QueryString("password")
end if
' L'utente si è correttamente registrato se i dati di sessione sono quelli
salvati nell'oggetto application
if Session("utente") = Application("utente") And _
Session("password") = Application("password") Then
%>
<%
if request.QueryString("colore") <> "" then
Session("colore") = request.QueryString("colore")
end if
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Il sito di Mario Rossi</title>
</head>
<% if Session("colore") <> "" then %>
<body bgcolor="<%=Session("colore")%>">
<% else %>
<body>
<% end if %>
<table width="100%" border="1" cellpadding="0" cellpadding="2">
<tr>
<td width="100">
<!--#include file="includemenu.asp"-->
</td>
<td align="center">
<% if request.QueryString("colore") = "" then %>
Seleziona un colore di sfondo
<% else %>
Ho cambiato il colore di sfondo di tutte le sezioni secondo la tua scelta
<% end if %>
<form action="personalizza.asp" method="get">
<select name="colore">
<option value="#FFFF99">giallo</option>
<option value="#FFCCCC">rosa</option>
<option value="#66CCFF">celeste</option>
<option value="#FFFFFF">bianco</option>
</select>
<input type="hidden" name="sezione" value="personalizza">
<input type="submit" value="Seleziona">
43/97
</form>
</td>
</tr>
</table>
</body>
</html>
<%
else
' L'utente non si è registrato correttamente
%>
<html>
<head><title>Errore di accesso</title></head>
<body>Attenzione: accesso non consentito</body>
</html>
<%
end if %>
44/97
LISTATO 10
GLOBAL.ASA
<script language="VBScript" runat="server">
Sub Application_OnStart()
Application("utente") = "Mario"
Application("password") = "foo"
End Sub
</script>
45/97
LISTATO 11
ERRORE.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Pagina con errore</title>
</head>
<body>
<%
Dim i
Dim j
i = 1000
for j = -10 to 10
response.write i/j
next
%>
</body>
</html>
46/97
LISTATO 12
ERRORERESUME.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Pagina con errore</title>
</head>
<body>
<%
Dim i
Dim j
i = 1000
on error resume next
for j = -10 to 10
response.write i/j
next
%>
</body>
</html>
47/97
LISTATO 13
ANNOETARISPOSTA.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Pagina che richiede nome e anno di nascita</title>
</head>
<body>
<%
Dim anno
Dim eta
anno = cint(request.QueryString("anno"))
eta = Year(Now()) - anno
%>
Ciao <%=request.QueryString("nome")%>, hai <%=eta%> anni.
</body>
</html>
48/97
LISTATO 14
ANNOETARISPOSTA2.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Pagina che richiede nome e anno di nascita</title>
</head>
<body>
<%
Dim anno
Dim eta
on error resume next
anno = cint(request.QueryString("anno"))
if Err then
response.write "Gentile utente, si è verificato un errore nella
compilazione dei tuoi dati <br>"
response.write "Descrizione dell'errore: " & Err.Description &
"<br>"
response.write "Codice dell'errore: " & Err.Number & "<br>"
If Err.Number = 13 Then
response.write "Devi inserire un numero come anno di
nascita<br>"
End If
response.write "Torna alla <a href=""annoeta2.asp"">pagina
precedente</a>"
response.end
end if
eta = Year(Now()) - anno
%>
Ciao <%=request.QueryString("nome")%>, hai <%=eta%> anni.
</body>
</html>
49/97
3a lezione
A scuola con PC Open
Web Developer ASP
di Antonio Volpon
1 I database relazionali
ontinuiamo la nostra
esplorazione della tecnologia ASP e affrontiamo in
queste due ultime puntate un
argomento fondamentale per
sfruttarne appieno le potenzialità: l’uso dei database. Vedremo innanzitutto cosa è un database, quando adottarlo e le
parti di cui si compone. Passeremo poi a introdurre il ruolo
del linguaggio SQL (Structured
Query Language) utilizzato per
interrogare le basi di dati e infine vedremo come utilizzare
un database all’interno delle
applicazioni ASP.
C
Le differenze con un foglio
elettronico
Molti dei nostri lettori conoscono con tutta probabilità i
programmi compresi con i
pacchetti della famiglia Office:
Word, Excel, PowerPoint. Excel, in particolare, è uno strumento versatile che consente
di lavorare su righe di dati in
modo preciso ed efficiente. A
prima vista Excel sembrerebbe
un database: vi si possono memorizzare delle informazioni
sulle righe, realizzare ricerche
e anche modifiche. In realtà un
database si distingue da prodotti quali Excel perché permette di salvare dati e infor-
mazioni molto più complessi, e
di porli in relazione con altre
realtà. Anche gli strumenti utilizzati per realizzare interrogazioni su questi dati sono più
potenti, tanto che per questi
scopi è stato creato un vero e
proprio linguaggio (chiamato
SQL). Rispetto ad Excel, che
ragiona essenzialmente in termini di riga, un database relazionale introduce il concetto di
tabella, che indica una parte
della realtà in esame.
La teoria dei database relazionali è stata introdotta nel
1969 da Edgard Codd, un ricercatore di IBM che ha applicato
diversi concetti presi dal mondo della matematica. Non sono
necessarie in realtà particolari
conoscenze per capire il funzionamento di una base di dati, che ruota in realtà intorno ai
concetti di tabella, campo e record. Vediamo di capire di cosa si tratta.
Un esempio pratico:
condividere le fotografie
In queste due puntate ci
concentreremo, come sempre,
su un problema specifico. Come ormai sapete, il nostro
compito è di aiutare Mario
Rossi nella costruzione del
proprio sito personale. In par-
IL CALENDARIO DELLE LEZIONI
Lezione 1:
Da sito statico
a dinamico
Lezione 2:
• Creare un database con
Access
• Le tabelle e le relazioni
• Lo standard SQL per
interrogare il database
Portare il sito sul server
Lezione 3:
ASP e i database
Le prossime puntate
• I database relazionali
Uso avanzato dei database
50/97
Lezione 4:
La scelta di Access
Per gli esempi che
accompagnano queste 2
puntate utilizzeremo dei
database in formato Access.
La scelta deriva da diverse
considerazioni. Prima di tutto
Access è un prodotto che fa
parte della famiglia Office
(nella versione Professional) ed
è quindi particolarmente
diffuso. Utilizzare Access è
inoltre alquanto semplice
rispetto ad altri gestori di
database professionali, e le
prestazioni sono di tutto
rispetto se, come nel nostro
caso, stiamo realizzando un
sito amatoriale, senza picchi di
traffico.
Il nostro è un corso di ASP e
non di Access, quindi non ci
fermeremo ad analizzare in
ticolare Mario ha recentemente acquistato una macchina fotografica digitale, e vorrebbe
condividere con gli amici via
Web gli scatti più interessanti.
Potrebbe farlo realizzando alcune pagine statiche (vedi la
differenza tra sito statico e dinamico che abbiamo affrontato nella prima puntata del corso Web Master ASP, pubblicata
nel numero di Novembre di PC
Open), ma ha un’idea diversa.
Quella che vorrebbe realizzare
è una pagina che non si limiti a
visualizzare l’elenco delle ultime foto inserite, ma che dia al
visitatore del sito la possibilità
di svolgere qualche ricerca, in
modo da visualizzare le foto
che ritraggono un particolare
tema o che siano state scattate
in un determinato luogo. Vorrebbe anche avere la possibilità di aggiungere velocemente
dettaglio le caratteristiche di
questo prodotto, ma è utile
saper creare le tabelle ed
eseguire qualche semplice
interrogazione. Vediamo quindi
come realizzare la tabella delle
Foto (o meglio, la prima
versione di questa tabella),
con Access. Abbiamo scelto di
utilizzare Access 2000, ma non
preoccupatevi se possedete
una versione diversa: per i
nostri scopi le differenze tra le
versioni sono del tutto
trascurabili.
Nessun problema neppure se
non avete Access installato:
sarete comunque un grado di
provare gli esempi ASP che
realizzeremo, poiché i file di
esempio sono sempre
prelevabili dal nostro sito.
nuove foto che scatterà durante le prossime vacanze. Per
aiutarlo in questa richiesta realizzeremo in effetti una base di
dati.
Abbiamo detto poco fa che
un database è un insieme di
dati. Aggiungiamo adesso che
questo insieme di dati è dotato
di un certo tipo di struttura, è
cioè organizzato secondo una
logica definita da chi si è occupato di costruirlo. Pensiamo
al caso di Mario Rossi, cioè la
costruzione di un database da
pubblicare sul Web e che contenga una descrizione delle foto interessanti (useremo di seguito i termini database o base
di dati per indicare lo stesso
concetto).
La fase logica
La prima fase che porta alla
costruzione di una base di da-
3a lezione
ti è essenzialmente logica. Si
tratta di rispondere alla domanda: quali sono le informazioni di cui ho bisogno per realizzare la pagina richiesta?
Quali, tra tutti i dati che posso
memorizzare a proposito di
una foto, hanno senso nel contesto in esame? Quello che vogliamo memorizzare è per prima cosa il nome del file contenente la foto, così da visualizzarla su browser. Sicuramente
abbiamo poi bisogno di sapere
qual è l’argomento della foto,
visto che Mario Rossi vuol dare ai suoi utenti la possibilità di
compiere ricerche in base al
tema, e la stessa cosa vale per
il luogo. Un’ulteriore informazione che è bene salvare sul
database è una data, così da
poter svolgere in futuro qualche interrogazione per capire
quante foto sono state scattate
nel corso dei mesi. Una volta
decisi quali dati memorizzare,
il resto del lavoro è semplice.
Il concetto di tabella
Come prima cosa costruiamo allora una tabella. Una ta-
bella, nella teoria relazionale
dei dati, rappresenta la descrizione di una realtà in esame.
Nel nostro caso quello che
possiamo fare è costruire una
tabella che descriva le foto delle vacanze.
Ogni tabella è poi composta
da un certo numero di attributi (nel nostro caso il nome del
file, la data, il luogo) che vengono chiamati campi. I campi
sono i veri contenitori dei dati,
mentre la tabella è essenzialmente un contenitore di campi
(in figura 1 potete vedere un’ipotetica tabella per le nostre
foto, realizzata con Access).
Quando popoliamo il database, ossia quando inseriamo i
dati veri e propri, e in particolare nel popolare la tabella,
specifichiamo diversi valori
per i campi, ad esempio indicando che il nome del file è
“dsc0021”, che il luogo è “Venezia” piuttosto che “Roma”.
Ciascuna foto che inseriamo
nella tabella prende il nome di
record (in figura 2 sono riportati alcuni record per la tabella
Foto).
1
2
2 Creare un database con Microsoft Access
opo averlo installato, eseguite Access dal vostro
computer (lo trovate sicuramente tra i programmi del
menu Start): vi verrà chiesto di
aprire un database esistente
oppure di crearne uno nuovo,
proprio quello che vogliamo.
Scegliete dove salvare il file,
dandogli un nome significativo
(ad esempio foto). Prendete
nota della cartella in cui avete
salvato il database, perché dovrete successivamente spostarlo nella directory principale del vostro sito (vedremo più
D
avanti come fare). Vi troverete
a questo punto nella schermata di figura 3. Avete davanti a
voi il pannello di Access, lo
strumento usato per creare gli
oggetti del database (come le
tabelle), per eseguire interrogazioni, ma anche per svolgere
alcune attività che non rientrano nel nostro corso ASP, come
la generazione di report o la
scrittura di codice. Vogliamo
invece realizzare una tabella, e
per farlo basta assicurarsi che
nel pannello sia selezionata la
voce Tabella. A questo punto,
tra le voci presenti
3 sulla destra scegliete Crea una tabella in visualizzazione struttura e
siete pronti per descrivere tutti i
campi di cui è composta la tabella (figura 4).
Gli attributi
dei campi
Come
abbiamo
detto nel para- 51/97
4
5
3a lezione
grafo precedente, i campi sono
gli attributi che definiscono la
realtà in esame, nel nostro caso la foto. Come prima cosa inseriamo quindi “Nome”, a indicare il nome del file contenente l’immagine (figura 5). Se vi
spostate con il tabulatore, noterete che Access vi richiede
di inserire un “tipo dati” per il
campo appena definito.
Quello che vi viene chiesto è
in pratica di decidere il formato per l’informazione da salvare: si tratta di un testo, di un
numero, di una data (e con
quali dimensioni)? Per una descrizione approfondita dei tipi
di dati disponibili in Access vi
rimandiamo alla guida in linea,
ma per il nome della foto ci
sembra corretto definire il
campo come un testo di lunghezza massima di 50 caratteri
(figura 6).
Alla foto vorremo sicuramente associare un Titolo, e
scegliamo di usare un campo,
sempre di tipo testo ma questa
volta di lunghezza 200. Si tratta
poi di inserire un campo Luogo
dello stesso tipo, come Provincia e infine un campo Data,
questa volta di tipo data a indicare la data di scatto della fotografia.
La versione finale della tabella compare in figura 7.
La chiave primaria
di una tabella
Possiamo a questo punto
salvare la tabella: Access vi
chiede di inserire un nome opportuno con il quale riferirla
successivamente, e non c’è
dubbio che la cosa migliore
sia di chiamarla Foto. Non appena fornite di un nome della
tabella, però, Access vi risponde con una finestra che
richiede la vostra immediata
attenzione (visto che contiene
un punto esclamativo) (figura
8), consigliandovi di indicare
una chiave primaria per la tabella. Di cosa si tratta esattamente?
Anche se non è obbligatorio,
è buona norma che ogni tabella contenga un campo i cui valori siano univoci per ogni record che inserite. Il vostro codice fiscale, tanto per fare un
esempio, è univoco.
Per questioni di efficienza e
per facilitare le operazioni tra
tabelle (che vedremo in seguito) è buona abitudine definire
o creare un campo di questo tipo in ogni tabella che andremo
52/97
a realizzare. Poiché Mario Rossi possiede una macchina fotografica digitale che dà ad
ogni foto un nome composto
da un prefisso e un progressivo (ad esempio “dsc1234”), potremmo scegliere il campo Nome della tabella come chiave
primaria. Un’alternativa è quella di inserire un campo fittizio
(ad esempio “ID” per identificativo) e scegliere come tipo
di dato Contatore. Ogni volta
che inseriremo un record nella
tabella il valore del contatore
si incrementerà automaticamente di 1, realizzando quindi
un campo contenente valori
ogni volta diversi.
Creiamo allora una chiave
primaria, ma per prima cosa
premiamo il pulsante Annulla
come risposta alla domanda di
Access.
A questo punto selezioniamo la riga contenente il campo
Nome della tabella e dal menu
di Access selezioniamo l’icona
che rappresenta il disegno di
una chiave.
Noterete che a sinistra del
campo Nome comparirà una
piccola chiave, ad indicare che
quel campo conterrà sempre
valori univoci per ogni record
inserito (figura 9).
Non si tratta solo di un’indicazione: Access non vi consentirà neppure se lo volete di
inserire due volte lo stesso nome per l’immagine.
Salvate di nuovo la tabella
chiamandola Foto e ritornerete
nel pannello di Access, dove la
vedrete comparire (figura 10).
Finora abbiamo definito una
tabella e i suoi campi: si tratta
a questo punto di popolare la
tabella con alcuni dati, e quindi con alcuni record. Vedremo
in particolare come creare solo alcuni record, visto che nel
CD Guida abbiamo inserito tutti i file di esempio, compresi i
database che useremo per gli
esercizi.
Per popolare la tabella è sufficiente aprirla con un doppio
clic dal pannello di Access, così da entrare in modalità inserimento. Inseriamo quindi alcuni dati, come possiamo vedere in figura 11.
Per verificare cosa vuol dire
aver definito una chiave primaria provate a inserire un record utilizzando un nome già
presente: come vedete dalla figura 12 questa operazione non
è permessa.
6
7
8
9
10
11
12
3a lezione
3 Consigli per impostare una tabella
abelle, campi, record: questi gli elementi fondamentali di una base di dati. In
realtà, esistono una serie di regole da tenere in considerazione quando definiamo una o più
tabelle e che adesso introdurremo brevemente. È importante costruire una base di dati
che risulti efficiente, perché
nessun programma, per quanto
bene sia scritto, riesce a sopperire i limiti di una base di dati deficitaria. Le tabelle, in particolare, dovrebbero limitarsi a
descrivere uno e un solo oggetto della realtà in esame.
Il motivo di questi accorgimenti è evidente se diamo
un’occhiata alla tabella di figura
13. Come vedete abbiamo popolato i record con alcuni dati
significativi, proprio quelli che
andremo a visualizzare nelle nostre pagine ASP. Un problema di
questa tabella è che contiene diverse ripetizioni di valori nei
campi Provincia e Stato.
T
I dati devono essere coerenti
Caratteristica saliente di
ogni base di dati è la necessità
di ospitare dati che siano il più
possibile coerenti tra loro. Se
però nel campo Nazione scrivo
Italia in un caso, Italy in un altro
e magari IT in un terzo non ho
sicuramente partecipato a
mantenere i dati coerenti. Questa è proprio la situazione della
tabella in figura. Se un utente inserisce un nuovo record non ho
nessuna possibilità di guidarlo
affinché inserisca un nome di
nazione che rispetti lo standard
definito, ma questo potrà inserire ogni volta dei valori leggermente o completamente diversi. Se domani volete contare
quante immagini scattate in Italia sono presenti nella tabella
(operazione semplicissima, come vedremo quando cominceremo a parlare di SQL), in questo caso non ci riuscirete.
Un altro limite di questa
struttura deriva dal fatto che
rende difficile le modifiche sui
dati. Immaginate di dover sostituire la voce Italy con Italia,
in quanto il sito di Mario Rossi
è per il momento (anche se Mario già aspira a tradurlo) in lingua italiana. Con questa struttura non potete far altro che sostituire ogni voce, operazione
non impossibile (date le interessanti funzioni di Access), ma
sicuramente scomoda in caso
di interventi ripetuti.
Abbiamo detto precedentemente che ogni tabella dovrebbe rispecchiare una realtà atomica. In effetti, se prestiamo attenzione al significato di Provincia e Stato, ci accorgiamo che
queste non sono caratteristiche
peculiari di una foto, ma piuttosto di altre tabelle, che potremmo chiamare Provincia e Stato.
Costruiamo allora altre due tabelle, in modo del tutto analogo
a quello usato per creare la tabella foto (riportiamo la struttura rispettivamente nelle figure
14 e 15). Ogni tabella è composta da due campi, di cui il primo
è la chiave primaria. Abbiamo
scelto in questo caso di usare la
sigla della provincia e il codice
dello stato come chiave primaria, così da garantire l’univocità
di questi valori. Nelle figure 16 e
17 potete notare alcuni record
di esempio per le tabelle, che rispecchiano i record inseriti nella tabella Foto.
A questo punto interveniamo sulla tabella Foto in modo
che i campi Provincia e Stato
non si riferiscano più, come
succede adesso, alle descrizioni
delle province e degli stati, ma
alle chiavi primarie. Per farlo sostituiamo il campo Provincia
con IdProvincia e Stato con IdStato (tipo di dato testo di lunghezza 3 e 2) e li riempiamo rispettivamente con la sigla della
provincia e il codice dello stato,
così da ottenere qualcosa di simile alla tabella di figura 18. Il concetto di “normalizzazione”
Esiste una soluzione che permette di rendere più facili le modifiche alle
tabelle e di trattare dati “coerenti”: si tratta della normalizzazione, ovvero
di una serie di tecniche complementari (ciascuna chiamata Prima Forma
Normale, Seconda Forma Normale e altre) che aiutano lo sviluppatore
nella costruzione di una base di dati efficiente. Non entreremo nel
dettaglio di queste tecniche, ci limiteremo a capire come intervenire sulla
nostra tabella perché sia efficiente e facilmente mantenibile.
53/97
13
14
15
16
17
18
3a lezione
4 Le relazioni tra le tabelle
no dei punti cardine, nonché uno dei punti forza
dei database relazionali è
dato dalla possibilità di definire legami tra le tabelle (chiamati relazioni).
Si tratta adesso di capire cosa vogliamo realizzare attraverso le relazioni nel nostro
particolare contesto. Il nostro
obiettivo è di legare il campo
IdProvincia e IdStato delle tabelle Provincia e Stato con i rispettivi campi della tabella Foto, in modo che in quest’ultima
tabella non sia possibile inserire valori non presenti nelle prime 2. Vediamolo con un esempio. Aprite la tabella Foto con
un doppio clic e provate ad inserire alcuni dati di prova per
una fotografia. In particolare,
inserite dei valori assolutamente inventati per i campi IdProvincia e IdStato, ad esempio
“AA” e “BB”. Access non fa una
piega: vi permette di inserire i
valori scelti anche se non esistono nessuna Provincia e nessuno Stato definiti nelle rispettive tabelle.
Questo rappresenta un problema perché, come abbiamo
detto precedentemente, uno
dei vantaggi e degli scopi di un
database è di mantenere l’integrità referenziale dei dati che
ospita. Per superare questa limitazione ci vengono in aiuto
le relazione tra tabelle che Access, da buon database relazionale, permette di definire in
modalità grafica semplificando
al massimo questa operazione,
tanto da renderla quasi divertente.
U
La procedura nel dettaglio
Prima di tutto eliminate il record che avete appena inserito
nella tabella Foto e assicuratevi che non siano presenti record con IdProvincia e IdStato
non presenti anche nelle tabelle Stato e Provincia. Adesso
portatevi nella maschera di gestione delle tabelle e selezionate l’icona relazioni dalla barra
dei menu. A questo punto si
tratta di aggiungere le tabelle
tra cui realizzare le relazioni,
nel nostro caso tutte, visto che
si tratta di selezionare Foto,
Provincia e Stato (per selezionare più tabelle tenete premuto il tasto CTRL della tastiera
mentre effettuate la selezione
54/97
con il tasto sinistro del mouse).
Confermate l’operazione e vedrete comparire le tabelle nella
finestra Relazioni di Access.
A questo punto dobbiamo
informare Access della nostra
intenzione, ovvero di legare il
campo IdProvincia della tabella Provincia a quello della tabella Foto, così da porli in stretta relazione. Premete il tasto sinistro del mouse sopra il campo IdProvincia della tabella
Provincia e trascinatelo verso
il campo IdProvincia della tabella Foto. A questo punto rilasciate il pulsante del mouse: la
situazione che vi si presenta è
quella di figura 19.
Cerchiamo di capire il significato della schermata. Access
ci propone di realizzare una relazione tra le due tabelle ponendole in relazione. Non solo:
se prestate attenzione alla parte bassa della figura, vedrete
un checkbox con la scritta Applica integrità referenziale: è
proprio quello di cui abbiamo
bisogno, per cui lo selezioniamo. A questo punto agite sul
pulsante Crea e noterete che il
diagramma delle relazioni cambia, in particolare è stato aggiunto un segmento di unione
tra le tabelle Provincia e Foto,
come in figura 20. Ripetete
adesso la stessa operazione
per il campo IdStato, trascinando il campo dalla tabella
Stato alla tabella Foto e applicando l’integrità referenziale,
così portarvi nella situazione
descritta dalla figura 21.
Abbiamo finito: potete chiudere la finestra relazioni e provare a ripetere l’inserimento
precedente. Dalla maschera di
gestione delle tabelle aprite
con un doppio clic la tabella Foto e provate nuovamente ad inserire dei valori arbitrari per i
campi IdProvincia e IdStato (ad
esempio ancora una volta “AA”
e “BB”). Questa volta Access
non vi consente l’operazione
(figura 22): è infatti necessario
utilizzare una provincia o uno
stato in una delle relative tabelle. È quindi buona norma,
prima di popolare i record di
questo database, riempire per
prima cosa le tabelle Stato e
Provincia con i valori che poi
utilizzeremo nella tabella Foto.
Non è una regola ferrea (altrimenti saremo di fronte ad un li-
19
20
21
22
mite): potete sempre, quando
nasce l’esigenza, uscire dalla
tabella Foto e inserire i record
richiesti in Stato e Provincia.
Terminiamo qui la nostra visita di Access: abbiamo imparato tutto quello che ci serve per
costruire una base di dati. È
adesso arrivato il momento di
capire come possiamo usare
questo database per costruire
applicazioni ASP.
Vediamo per prima cosa dove posizionare la base di dati e
come creare un collegamento
da una pagina.
3a lezione
5 Usare un database Access da ASP
ealizzare da una pagina
ASP la connessione ad un
database Access è un’operazione semplice, che richiede però una certa accortezza per evitare errori difficilmente rintracciabili. Come
sempre, trovate gli esercizi che
accompagnano questa puntata
nel nostro CD, ma vediamo comunque passo per passo come
utilizzare il database.
Portiamoci nella cartella
principale del nostro sito,
quella per intenderci che abbiamo configurato in Internet
Information Services.
Per chiarezza (ma non esiste nessun obbligo) creiamo
una cartella chiamata “database” e copiamo al suo interno la
base di dati che abbiamo realizzato poco fa. A questo punto
entriamo nel vivo e passiamo
ad analizzare il codice che la
compone. La pagina è elencofoto.asp, presente in figura
23, e visualizza l’elenco dei record presenti nella tabella Foto. Il risultato è semplice ma interessante: per la prima volta
da quando lavoriamo con le
pagine ASP sono visualizzati
dati che provengono da una
fonte esterna, un database. Anche se l’esempio è quasi banale, è facile capire come l’utilizzo delle basi di dati nel contesto della programmazione Web
apre delle possibilità che fino
ad ora, utilizzando il solo linguaggio, non siamo riusciti a
raggiungere.
Passiamo ora a un attento
studio delle righe di codice che
permettono di raggiungere
questo importante traguardo
(listato 1). La pagina utilizza
quasi tutte le strutture di ASP
che già conosciamo, integrando la comunicazione con il database. Spenderemo un po’ di
tempo ad analizzare le righe
che compongono questo
esempio, perché un esercizio
così semplice contiene gran
parte delle nozioni di cui abbiamo bisogno per utilizzare i
database con ASP. Procediamo
allora per gradi: la tecnologia
ADO per collegarsi ai database.
R
I listati citati nell’articolo sono
nel CD Guida nella sezione
“Corsi Open Master”
55/97
ASP non dispone nativamente di un supporto per i database, ma utilizza invece la
tecnologia ADO (ActiveX Data
Objects), che fornisce uno strato di interfaccia tra la pagina
ASP e la base di dati.
Questo vuol dire che per
realizzare i programmi di queste puntate non solo dovete
avere installato Internet Information Services, ma anche
ADO. Non preoccupatevi: con
tutta probabilità il supporto
ADO è già installato sul vostro
computer, visto che è utilizzato da un vasto numero di applicazioni anche non Web, ma
se così non fosse potete scaricare la versione più recente
collegandovi al sito www.mi
crosoft.com/data/.
Le connessioni
La prima cosa da fare per
utilizzare un database è quella
di stabilire una comunicazione
tra la pagina ASP e i dati che
vogliamo interrogare. In ADO
la comunicazione avviene
creando un oggetto di tipo
connessione: è lo scopo della
riga di codice che inizia con
“Set conn”.
Finora non abbiamo ancora
introdotto il ruolo del metodo
CreateObject dell’oggetto Server di ASP. Lo scopo del metodo è quello di creare e istanziare un oggetto che non fa
parte del modello ad oggetti di
ASP (come Request, Response, e così via), ma che è possibile richiamare da una pagina
ASP.
Un programmatore di linguaggio C++, ad esempio, potrebbe creare una libreria di
funzioni e richiamarla all’interno di una pagina ASP, con il benificio di aumentare le prestazioni dell’applicazione, visto
che C++ è un linguaggio compilato.
Il concetto non è di facile
comprensione, ma non preoccupatevi, visto che nel corso
questo è l’unico ambito in cui
lo useremo.
L’unica cosa che è bene ricordare è che ADO non fa parte di ASP, e quindi per richiamare gli oggetti ADO da una
pagina è necessario usare il
metodo CreateObject. Anche
la sintassi sarà sempre quella
che presentiamo nell’esempio,
che farete bene a copiare e incollare quando realizzerete le
vostre applicazioni in modo
del tutto indipendente.
A questo punto “conn” diventa l’oggetto connessione
che useremo nell’esempio.
Una volta creata la connessione, dobbiamo aprirla, così da
stabilire il canale di comunicazione tra la pagina e il database. È appunto lo scopo della riga successiva, che utilizza l’evento Open dell’oggetto connessione appena creato. Nell’aprire la connessione dobbiamo specificare il tipo di database che andremo ad utilizzare
e soprattutto la posizione della
cartella in cui si trova, nonché
il nome che consente di identificarlo. Anche per quanto riguarda la sintassi da usare non
ci soffermiamo più del dovuto:
è quella presentata nel listato.
L’unica parte degna di nota è il
metodo MapPath dell’oggetto
Server.
Il metodo MapPath
dell’oggetto server
Lo scopo di questa istruzione è calcolare il percorso fisico
di un file partendo dal percorso Web. Spieghiamo il concetto con un esempio.
Quando digitate un URL
(Uniform Resource Locator)
nella barra degli indirizzi del
browser, specificate il percorso partendo dalla directory
principale del server Web. Se
ad esempio scrivete http://lo
calhost/miapagina.asp e la di-
rectory principale del server è
c:\inetpub, il percorso fisico
del file nel vostro PC è c:\inetpub\miapagina.asp. Lo scopo
del metodo MapPath è proprio
quello di restituire il percorso
completo del file ricevendo come input unicamente l’URL
della pagina.
Ma perché usare questo metodo quando avremmo potuto
semplicemente scrivere il percorso “a mano”?
In generale, quando costruiamo un’applicazione Web
dovremmo cercare di essere il
più generalisti possibili, ed evitare di “cablare” all’interno
della pagina informazioni che
domani potrebbero variare. Se
state realizzando questo esercizio e lo volete successivamente far ospitare da un provider, molto probabilmente il
percorso della directory principale del server cambierà.
Memorizzando il percorso del
database nella pagina, prima
di portare in questo nuovo ambiente le pagine, sarete costretti a modificarlo, e questo
per ogni pagina personalizzata. Utilizzando il metodo MapPath lasciate al server il compito di calcolare qual è il percorso del file, così potete portare la pagina in qualsiasi altro
ambiente.
Non a caso, se prendete i file di questa puntata dal nostro
CD e li copiate nel vostro PC,
non avete bisogno di apportare alcun adattamento per eseguirli correttamente.
23
3a lezione
6 Lo standard SQL per interrogare il database
assiamo ora alla riga che
valorizza la stringa SQL. È
una riga fondamentale per
il nostro scopo: definisce quali e quanti dati andare a recuperare dal database, e da quale tabella. SQL (Structured
Query Language) è a tutti gli effetti un linguaggio usato per interrogare e modificare le basi
di dati. È uno standard (seppur
con diverse e a volte inopportune varianti): la sintassi che
imparemo per Access è in
realtà utilizzabile anche in altre realtà. I fondamenti di SQL
sono alquanto semplici da imparare. Una query di selezione
(dove per query intendiamo
un’interrogazione al database)
ha una struttura minima del tipo:
SELECT elenco_dei_campi FROM
nome_tabella
che potrebbe essere tradotta
come “seleziona i campi elenco_dei_campi dalla tabella nome_tabella”. L’elenco dei campi da selezionare va sempre
separato da una virgola. Torniamo ora alla select del nostro esempio e confrontiamola
con la sintassi appena citata:
SELECT Titolo, Luogo FROM Foto
Non dovremmo avere dubbi
sullo scopo di questa query:
estrarre dalla tabella Foto il titolo e il luogo di tutte le foto
memorizzate.
Per il momento ci fermiamo
qui e proseguiamo ad analizzare l’esempio, ma torneremo tra
breve ad arricchire la nostra
conoscenza di SQL.
P
I recordset ADO
Una volta stabilita la connessione con il database e costruita la stringa in linguaggio
SQL abbiamo bisogno di un’altra struttura, un oggetto che
contenga i record che andremo ad estrarre dalla base di
dati: si tratta dell’oggetto Recordset (cioè insieme di record). Lo andiamo a istanziare
allo stesso modo della connessione, poiché anche Recordset
è un oggetto proprio di ADO e
non di ASP. Anche l’oggetto Recordset dispone di un metodo
Open, al quale passiamo alcuni
parametri.
Come prima cosa è necessario indicare al Recordset quale
è la stringa SQL che deve utilizzare per restituire i dati, e
56/97
che abbiamo memorizzato nella variabile “sql” (non fatevi
ingannare dal nome che abbiamo dato alla variabile: avremmo potuto usare quasiasi
stringa). È inoltre fondamentale legare il Recordset alla connessione che abbiamo aperto
con il database Access.
Ma perché bisogna seguire
questa procedura, visto che
ADO avrebbe potuto automaticamente legare il Recordset
con la connessione aperta? In
realtà molte applicazioni Web
dispongono di connessioni a
database diversi, di conseguenza il sistema non è in grado a priori di decidere quale
Recordset associare ad ogni
connessione; è un’operazione
di nostra competenza.
È possibile specificare altri
due parametri all’apertura del
Recordset, e allo scopo abbiamo utilizzato due costanti definite ad inizio pagina. Senza
spingerci nel dettaglio, questi
parametri indicano all’oggetto
le nostre intenzioni riguardo i
dati che andremo ad estrarre.
Il primo adOpenForwardOnly
indica che vogliamo accedere
ai dati solo una volta, spostandoci dal primo all’ultimo record presenti. Indicando al Recordset che per noi questa
scelta non rappresenta un limite evitiamo di sprecare inutili risorse e rendiamo la navigazione tra i risultati più efficiente. Il secondo parametro,
adLockReadOnly è utilizzata
quando i dati sono utilizzati
solo per lettura, anche questo
è il nostro caso.
Scorrere i record
di un Recordset
Spostiamoci ora nella parte
finale del codice. Troviamo per
prima cosa un ciclo “do until”.
Questa titpologia di ciclo (che
non abbiamo visto nella prima
puntata) è eseguito fino a
quando non diventa vera l’espressione che lo segue. E l’espressione che lo segue utilizza un metodo del Recordset
chiamato Eof. Il risultato del
metodo Eof (dove Eof sta per
End Of File, fine del file) è sempre falsa, a meno che non ci
troviamo dopo l’ultimo record
restituito.
Il significato del ciclo è quindi questo: “fino a quando non
hai visualizzato tutti i record,
ripeti questo ciclo”. Ci rimane
allora da vedere come visualizzare i record. All’interno del
ciclo viene costruita una lista
HTML ricorrendo al tag <li> ed
è usato un ulteriore metodo
dell’oggetto Recordset, Fields.
La sintassi è molto semplice
ed intuitiva: recordset.fields
(nome_campo). In effetti il metodo Fields restituisce il contenuto del campo richiesto per il
record corrente, proprio quello di cui abbiamo bisogno. Per
ogni foto estraiamo quindi il
Titolo della foto e il luogo dove
è stata scattata, e li presentiamo in una lista HTML. Segue
questa riga rs.movenext, ancora una volta un metodo del Recordset.
Come è facile intuire, utilizziamo questo metodo per spostarci sul successivo record
del Recordset e ricominciare il
ciclo, a meno che non ci troviamo sull’ultimo record della
tabella. In questo caso infatti la
condizione rs.Eof diventa vera,
e l’esecuzione
della pagina 24
esce dal ciclo.
Nello scrivere
la pagina ASP
e soprattutto il
ciclo è facile
dimenticarsi
di includere il
metodo MoveNext. Prestate
attenzione a
non commettere mai questa leggerezza
perché in questo caso la
condizione
del ciclo non 25
diventerà mai
vera, e l’esecuzione della
pagina terminerà
solo
quando viene
raggiunto il timeout di esecuzione.
Chiudere
quanto si è
aperto
In genere gli
oggetti creati
da ASP vengono
liberati
non appena
cessano di essere utilizzati o
quando escono dalla “visibilità” della pagina. È comunque
sempre buona norma rilasciare il prima possibile gli oggetti
che non servono più alla nostra pagina. Da un lato liberate
la memoria, dall’altro siete sicuri che non rimangano accidentalmente delle connessioni
al database. Questo è quello di
cui si occupa l’ultima parte del
codice. Viene per prima cosa
chiuso il Recordset, e per sicurezza viene annullato come oggetto; stessa sorte tocca poi alla connessione. Notate che
l’ordine in cui svolgiamo queste operazioni non è casuale.
Per prima cosa chiudiamo il
Recordset, che per funzionare
utilizza una connessione, e poi
chiudiamo quest’ultima. Non
importa quanto semplice sia il
codice che andate a visualizzare: è comunque sempre buona norma rilasciare esplicitamente gli oggetti che usate nel
costruire le vostre applicazioni.
3a lezione
Visualizzare
la foto selezionata
L’esempio precedente ci è
servito per introdurre ADO e
gli oggetti Connection e Recordset, ma ai fini pratici del sito lascia un po’ a desiderare.
L’auspicio di Mario Rossi è di
presentare una pagina come
quella realizzata, ma avere anche la possibilità di selezionare una voce dall’elenco e vedere la relativa foto. Modifichiamo allora l’esempio per rendere operativa questa modifica.
Nel contempo modifichiamo
anche la stringa SQL utilizzata
per estrarre i record, così da
presentare altre caratteristiche del linguaggio SQL.
La nuova pagina è riportata
in figura 24. Come vedete l’elenco è del tutto simile all’esempio precedente, solo che
ogni voce è ora diventata un
link. Abbiamo anche aggiunto
un indicatore con il totale delle foto presenti nel database,
così gli utenti affezionati sono
in grado di rendersi conto del
numero di foto che Mario carica nel corso delle settimane.
Se selezionate uno dei link si
apre una seconda pagina, che
visualizza il dettaglio della foto
selezionata (figura 25). Proprio
quello di cui aveva bisogno
Mario Rossi! Vediamo ora come abbiamo realizzato il codice che rende possibile tutto
questo (Listato 2).
Il trucco consiste nel definire due stringhe SQL: la prima
utilizzata per contenere il numero totale delle foto, la seconda per selezionare tutti i record di interesse. Ci occuperemo tra un attimo di come ottenere queste informazioni nel
linguaggio SQL, ma per il momento vediamo come utilizziamo l’oggetto Recordset. Non
abbiamo in effetti bisogno di
creare due distinti Recordset,
uno per il totale e uno per l’elenco, ma possiamo riutilizzare lo stesso oggetto in contesti
diversi.
Come è possibile notare
guardando il codice sorgente,
la prima volta è aperto il Recordset utilizzando la stringa
sql1, dopodiché ne viene
estratto il numero di record ed
è chiuso.
Infine viene riaperto utilizzando la seconda stringa SQL
(sql2), che restituisce l’elenco
di tutti i record presenti nelle
base di dati. Esaminiamo la
sintassi di queste interroga- 57/97
Costruire dinamicamente le interrogazioni
Estendiamo a questo punto i concetti esposti
26
finora, e partiamo da un’esigenza di Mario
Rossi. Mario vorrebbe infatti dare la possibilità
ai propri utenti di effettuare ricerche all’interno
dell’archivio di foto, così che sia possibile
specificare un termine che compone il titolo
della foto. La pagina di risposta conterrà quindi
solo le foto che rispondono ai criteri espressi
dall’utente. Potete provare questa funzionalità
puntando il vostro browser alla cartella ricerca e
in particolare visualizzando la pagina
ricerca.asp.
Compare un form: provate a questo punto a
inserire un termine contenuto nel titolo della
foto, come ad esempio “fiordaliso” (figura 26).
Avviate la ricerca, e come potevamo aspettarci
troviamo una pagina del tutto simile a quella
degli esempi precedente, ma che contiene
esclusivamente le foto ricercate
(figura 27). Come di consueto entriamo adesso
nel dettaglio del codice ASP che rende possibile
questa interessante possibilità.
Vediamo per prima cosa il contenuto della pagina con il form di ricerca, ricerca.asp, che si trova nella
cartella “ricerca” degli esempi della puntata (listato 3). Si tratta di una pagina che non ci spaventa, in
quanto composta da un semplice form in cui inserire il termine di ricerca. Passiamo allora ad affrontare
la pagina che contiene il vero e proprio codice di ricerca, elencofoto.asp (listato 4).
Non ci sono veri e propri stravolgimenti rispetto a quello che abbiamo realizzato fino ad ora. In realtà ci
siamo limitati a modificare la query SQL così da filtrare i dati di interesse, operazione non rara quando si
tratta di interrogare una base di dati. Questa volta le due stringhe sql1 e sql2 dipendono dal campo
compilato nel form: a una parte fissa di contenuto viene aggiunto il valore inserito dall’utente.
Per farlo si usa una query SQL con una forma del tipo:
SELECT elenco_campi FROM Tabella WHERE campo operatore criterio
La sintassi della prima parte è quella che siamo soliti usare, mentre abbiamo aggiunto qualche cosa di
nuovo nella seconda. Quando vogliamo filtrare i risultati presenti in una tabella, possiamo utilizzare la
parola chiave “where” e farla seguire dai criteri. Se volessimo cercare tutte le foto che contengono un
determinato titolo (ad esempio “montagna”, scriveremo qualche cosa del tipo:
SELECT * FROM Foto WHERE Titolo = ‘montagna’
È facile capire il significato della query: “seleziona tutti i record della tabella foto il cui titolo è uguale a
‘montagna’”). La presenza dell’apice singolo a chiudere il termine di ricerca è obbligatorio quando
lavoriamo con le stringhe, mentre non va usato nel caso di numeri. L’interrogazione che utilizziamo
nell’esempio è però leggermente diversa da quella appena vista, perché leggermente diversa è la nostra
esigenza. In effetti noi vogliamo estrarre non tutte le foto che hanno un certo termine come titolo, ma
tutte quelle che hanno un titolo che contiene il termine (tanto per fare un esempio reale, vogliamo che
cercando “fiordaliso” venga trovata anche la foto il cui titolo è “Fiordaliso Montano”).
La sintassi da usare in questo caso è leggermente diversa:
SELECT * FROM Foto WHERE Titolo like ‘%fiordaliso%’
Utilizziamo l’operatore “like” al posto di “=”, proprio perché non cerchiamo un’uguaglianza stretta tra il
titolo del campo e il valore ricercato.
27 Sono presenti inoltre due simboli di
percentuale, uno all’inizio e uno alla fine del
termine di ricerca. Come l’asterisco nel DOS, si
tratta di caratteri jolly che stanno ad indicare
“qualsiasi ripetizione di caratteri”. Il significato
di tutta la query diventa quindi “seleziona tutti i
record della tabella titolo il cui titolo contenga
fiordaliso e qualsiasi carattere prima o dopo
questo termine (anche nessuno)”. Se avessimo
voluto selezionare tutte le foto che iniziano con
fiordaliso avremmo scritto qualche cosa del
tipo:
SELECT * FROM Foto WHERE Titolo like
‘fiordaliso%’
Viceversa, se fossimo interessati a tutti i record
che terminano con fiordaliso, avremmo scritto
qualche cosa del tipo:
SELECT * FROM Foto WHERE Titolo like
‘%fiordaliso’
3a lezione
zioni. La prima stringa utiliz-
zata contiene il seguente codice:
SELECT count(nome) AS contatore
FROM Foto
La struttura è del tutto simile all’esempio precedente, ma
la parte relativa alla scelta dei
campi ha subìto alcune importanti modifiche. È stata in particolare usata una funzione
detta di “aggregazione”, non
allo scopo di restituire i record
della tabella, ma di effettuare
un’analisi statistica sui dati
presenti.
La funzione count, a cui viene passato il nome di un campo (nome), è quella di restituire (di “contare”) il numero di
record con nome della foto diverso uno dall’altro (in poche
parole, tutte le foto inserite
nella base dati).
La seconda query restituisce lo stesso elenco di prima,
ma l’abbiamo leggermente modificata per introdurre altre caratteristiche dello standard
SQL:
SELECT * FROM Foto ORDER BY
Data DESC
In questo secondo caso
manca completamente l’elenco dei campi, che è stato sostituito da un carattere jolly, l’asterisco (*). Il significato di tale sintassi è “selezionare tutti i
campi della tabella Foto”.
Quindi, senza dover elencare i
campi uno per uno, un’operazione nella quale è facile commettere errori quando sono
tanti, è possibile usare l’asterisco. Anche se realizziamo applicazioni semplici, vale comunque la pena di non esagerare con l’uso di questa sintassi. Impiegare l’asterisco solo
perché serve un campo su 10
non è una buona scelta, poiché
le operazioni di lettura dalla
base dati saranno certamente
più lente.
Questa query ha un’altra
particolarità che la distingue
dall’esercizio precedente: termina con ORDER BY. Com’è facile intuire, in tal modo è possibile ordinare i risultati secondo un campo.
Ad esempio, potreste voler
ordinare i dati secondo la data
di scatto della foto, in modo
che le fotografie più recenti
compaiano all’inizio. In questo
modo gli utenti hanno la possibilità di trovare le foto recenti
sempre nelle posizioni più vicine all’inizio della pagina,
mentre le foto ormai datate si
sposteranno progressivamen-
58/97
te in fondo alla pagina. Utilizziamo quindi ORDER BY seguito dal campo Data della tabella
Foto e dalla parola chiave DESC, diminutivo di Descending.
Se avessimo voluto ordinarle
dalla più datata alla più recente avremmo invece utilizzato
ASC (Ascending) oppure nulla,
visto che è il comportamento
standard.
Abbiamo anche modificato
il codice che produce l’elenco
delle foto, aggiungendo un
link. Se prestate attenzione a
come lo abbiamo costruito, vedrete che compare un parametro, il nome della foto. In tal
modo la pagina di dettaglio
della foto riceverà il nome con
cui abbiamo salvato l’immagine sul disco del server, e sarà
così in grado di visualizzarla.
In effetti, se passiamo a verificare il codice della seconda
pagina, per prima cosa è
estratto il valore del parametro, il nome del file della foto. A
questo punto, a metà pagina,
inseriamo un tag di tipo IMG.
Le immagini sono state precedentemente salvate nella cartella foto del server, per questo facciamo precedere da
questa cartella il percorso dell’immagine.
Quando il server esegue l’istruzione ASP contenuta nel
tag IMG inserisce il nome fisico
dell’immagine e a questo punto il browser dispone di tutti
gli elementi per visualizzarla
nella pagina.
Conclusioni
Terminiamo qui la prima
puntata dedicata all’esplorazione delle basi dati e alla loro
integrazione con ASP. A questo
punto siete in grado di interrogare qualsiasi tabella, con particolare riferimento a quelle
realizzate con Access, anche
se la struttura è del tutto ripetibile in altre realtà.
Abbiamo però ancora qualche importante concetto da
vedere. Ancora non sappiamo,
ad esempio, realizzare delle
query che interessino più tabelle, nel nostro caso Foto,
Provincia e Stato.
Ci siamo poi soffermati sulle
query di selezione, ma ne esistono di altri tipi, in particolare quelle che vi consentono di
inserire, modificare e cancellare i record dalle tabelle. E proprio di questo parleremo nell’ultima puntata del corso Web
Developer ASP.
Cliccate qui per accedere alla versione elettronica dei listati.
LISTATO 1
ELENCOFOTO.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Le foto di Mario Rossi</title>
</head>
<body>
<h1>Le mie foto preferite</h1>
<ul>
<%
Const adOpenForwardOnly = 0
Const adLockReadOnly = 1
Dim sql
Dim conn, rs
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/database/foto.mdb")
sql = "SELECT Titolo, Luogo FROM Foto"
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql, conn, adOpenForwardOnly, adLockReadOnly
do until rs.eof
%>
<li><%=rs.Fields("Titolo")%>, scattata a <%=rs.Fields("Luogo")%></li>
<%
rs.movenext
loop
rs.close
set rs = nothing
conn.close
set conn = nothing
%>
</ul>
</body>
</html>
59/97
LISTATO 2
ELENCOFOTOLINK.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Le foto di Mario Rossi</title>
</head>
<body>
<h1>Le mie foto preferite</h1>
<%
Const adOpenForwardOnly = 0
Const adLockReadOnly = 1
Dim contatore
Dim sql1,sql2
Dim conn, rs
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/database/foto.mdb")
sql1 = "SELECT count(nome) AS contatore FROM Foto"
sql2 = "SELECT * FROM Foto ORDER BY Data DESC"
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql1, conn, adOpenForwardOnly, adLockReadOnly
contatore = rs("contatore")
rs.Close()
rs.Open sql2, conn, adOpenForwardOnly, adLockReadOnly
%>
Sono presenti <%=contatore%> foto <br><br>
<%
do until rs.eof
%>
<li><a
href="dettagliofoto.asp?nome=<%=rs("Nome")%>"><%=rs("Titolo")%>,
scattata a <%=rs("Luogo")%></a></li>
<%
rs.movenext
loop
'rs.close
60/97
'set rs = nothing
'conn.close
'set conn = nothing
%>
</ul>
</body>
</html>
61/97
LISTATO 3
RICERCA/RICERCA.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Le foto di Mario Rossi</title>
</head>
<body>
<h1>Cerca tra le mie foto preferite</h1>
<form action="elencofoto.asp" method="get">
Cerca la foto: <input type="text" name="rfoto"><br>
<input type="submit" value="Cerca">
</form>
</body>
</html>
62/97
LISTATO 4
RICERCA/ELENCOFOTO.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Le foto di Mario Rossi</title>
</head>
<body>
<h1>Le mie foto preferite</h1>
Hai selezionato le foto che parlano di
<%=request.QueryString("rfoto")%><br>
<%
Const adOpenForwardOnly = 0
Const adLockReadOnly = 1
Dim contatore
Dim sql1,sql2
Dim conn, rs
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/database/foto.mdb")
sql1 = "SELECT count(nome) AS contatore FROM Foto WHERE Titolo like
'%" & request.QueryString("rfoto") & "%'"
sql2 = "SELECT * FROM Foto WHERE Titolo like '%" &
request.QueryString("rfoto") & "%' ORDER BY Data DESC "
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql1, conn, adOpenForwardOnly, adLockReadOnly
contatore = rs("contatore")
rs.Close()
rs.Open sql2, conn, adOpenForwardOnly, adLockReadOnly
%>
Sono presenti <%=contatore%> foto che soddisfano i criteri di
ricerca<br><br>
<%
do until rs.eof
%>
<li><a
href="dettagliofoto.asp?nome=<%=rs("Nome")%>"><%=rs("Titolo")%>,
scattata a <%=rs("Luogo")%></a></li>
<%
63/97
rs.movenext
loop
'rs.close
'set rs = nothing
'conn.close
'set conn = nothing
%>
</ul>
</body>
</html>
64/97
4a lezione
A scuola con PC Open
Web Developer ASP
di Antonio Volpon
1 Gestire un elenco di foto: la paginazione
iamo arrivati alla fine del
nostro viaggio all’interno
del mondo ASP. Nelle prime due puntate del corso (pubblicate nei numeri di novembre
e dicembre di PC Open) abbiamo avuto modo di capire l’importanza di questa piattaforma per lo sviluppo di siti Web,
ed evidenziato le differenze rispetto a un sito statico. Nel
corso della terza puntata (pubblicata nello scorso numero)
abbiamo invece apprezzato l’uso di ASP insieme alle basi di
dati, così da sfruttarne appieno
le potenzialità.
Dopo aver introdotto il ruolo
dei database relazionali e la
sintassi del linguaggio SQL, siamo passati ad affrontare un
esempio pratico: costruire una
galleria di immagini per il committente del nostro sito, il signor Mario Rossi.
Ci siamo lasciati dopo aver
costruito una pagina contenente un campo dal quale effettuare la ricerca nel database delle
S
foto (figura 1). Il risultato è un
elenco di foto che soddisfano il
criterio e da cui è possibile
aprire la foto che interessa. In
questa ultima puntata cercheremo come prima cosa di migliorare il modo con cui viene
presentata la lista di foto, introducendo un meccanismo di
“paginazione”. Passeremo poi
ad aiutare Mario Rossi nel gestire on line il proprio catalogo
di foto, creando una maschera
di amministrazione (protetta
da password) con la quale avrà
la possibilità di inserire, modificare ed eliminare le nuove foto che scatterà nel corso delle
prossime stagioni. Per farlo
completeremo le nostre conoscenze del linguaggio SQL introducendo la sintassi che consente di introdurre, aggiornare
e cancellare i record di una tabella.
Suddividere un elenco
Abbiamo lasciato un Mario
Rossi soddisfatto grazie alla
1
65/97
IL CALENDARIO DELLE LEZIONI
Lezione 1:
Lezione 4:
Da sito statico
a dinamico
Gestire un elenco di
fotografie
Lezione 2:
• L’inserimento
Portare il sito sul server
• La modifica
Lezione 3:
ASP e i database
relazionali
• La cancellazione
2
4a lezione
3
per definire il numero di elementi da far comparire in ogni
pagina di risultati. Questo è
quello che si ottiene con la riga
seguente:
rs.PageSize = pagSize
Il valore di pagSize è definito
una volta per tutte a inizio pagina, così da rendere più semplici eventuali variazioni future. A questo punto è possibile
aprire l’oggetto recordset, come sempre, ma per farlo utilizziamo una costante diversa per
il tipo cursore. Utilizziamo infatti una sintassi del tipo:
rs.Open sql2, conn, adOpenStatic,
adLockReadOnly
4
possibilità di effettuare ricerche nel proprio sito. Ben presto Mario si è però accorto che
all’aumentare del numero di foto nel proprio archivio on line,
l’elenco comincia a diventare
decisamente lungo e poco presentabile ai visitatori del suo sito (figura 2). Per questo motivo
è interessato a capire se esiste
un modo per suddividere l’elenco in più pagine, un po’ come si comporta Google (figura
3) quando visualizza i risultati
di una ricerca. Potevamo negare a Mario questa caratteristica
da inserire nel suo amato sito?
Certamente no, e con alcuni
semplici interventi, l’aspetto
della pagina di risposta diven-
66/97
terà quello rappresentato in figura 4. Come potete notare, in
fondo alla pagina è presente
un elenco di numeri, che rappresentano in gergo la “paginazione”, ovvero il meccanismo
utilizzato dagli utenti per spostarsi tra le diverse pagine dell’elenco. Per poter realizzare
questa caratteristica è necessario modificare il file di partenza, così da ottenere quanto
riportato nel listato 1 (elencofoto2.asp).
La procedura nel dettaglio
Vediamo operativamente le
aree su cui intervenire. Il recordset dispone di un metodo,
PageSize, che può essere usato
Per suddividere la navigazione in pagine, non è più sufficiente utilizzare un recordset
di tipo Forward Only, che può
essere navigato solo in un senso (cioè da un record al successivo). Un recordset di tipo
OpenStatic è una copia speculare dei dati in tabella, che non
possono essere modificati o eliminati, ma con il pregio di essere molto veloce durante le
letture. Poiché il nostro scopo
è solo quello di visualizzare i
dati, questa soluzione rappresenta il migliore compromesso.
Se osservate con attenzione il
codice vedrete che la costante
adOpenStatic è stata definita
all’inizio della pagina, con valore 3. Avremmo potuto utilizzare direttamente questo valore nel codice, ma la nostra soluzione è sicuramente più ordinata ed elegante.
Dopo aver aperto il record è
il momento di informare il recordset riguardo il numero di
pagina che vogliamo visualizzare. All’inizio sarà sicuramente la prima pagina, ma successivamente sarà l’utente, selezionando i link della paginazione, a indicare dove spostarsi.
Per vedere come questo si verifica è necessario osservare la
pagina dal browser e poi capire
cosa c’è scritto nel codice.
Spostatevi per prima cosa
con il mouse sopra i link che
formano la paginazione e osservate l’indirizzo che compare nella barra di stato del
browser (la barra di stato è
rappresentata dalla fascia nella parte bassa della finestra
del browser). Come potete notare, l’indirizzo ha una forma
del tipo:
http://localhost/elencofoto2.asp?
pag=2 (quando selezioniamo la
seconda pagina)
oppure
http://localhost/elencofoto2.asp?
pag=3 (per la terza pagina)
e così via.
In particolare, quando selezioniamo un link viene caricata
sempre la pagina elencofoto2.asp, ma sarà il parametro
pag (che indica il numero di pagina con le foto da visualizzare)
a cambiare di volta in volta.
È lecito quindi aspettarsi
che all’interno del codice della
pagina, da qualche parte, venga estratto il valore del parametro pag e che questo venga
utilizzato per richiedere al recordset la pagina corrispondente. Ed è in effetti quello che
si verifica in questa parte del
codice:
'Estrae il numero di pagina
pagNum = cint(request.Query
String("pag"))
If pagNum = 0 Then pagNum = 1
Lo scopo di questa parte di
codice è chiaro: viene estratto
il valore della pagina da visualizzare e assegnato alla variabile pagNum. La prima volta che
il visitatore richiede la pagina,
tuttavia, non specifica alcun
numero e in questo caso (come
si vede nella seconda linea di
codice), l’utente viene diretto
alla prima pagina. La riga:
rs.AbsolutePage = pagNum
assegna il valore appena estratto al metodo AbsolutePage del
recorset: lo scopo è proprio
quello di restituire la pagina
voluta. Queste sono tutte le
informazioni necessarie al recordset per posizionarsi sulla
pagina corretta.
L’ultima modifica di cui abbiamo bisogno per gestire più
pagine di foto riguarda il ciclo
che estrae i record. In questo
caso non è sufficiente visualizzare, come abbiamo fatto finora, tutti i record presenti nel recordset (utilizzando un ciclo
do until rec.eof). Vogliamo invece limitare il numero di record presentati a quelli che
compongono la pagina: possiamo allora utilizzare una sintassi di questo tipo:
for i = 1 to pageSize
<visualizza i dati della foto>
next
4a lezione
Anche questa porzione di
codice, dopo 3 puntate del corso ASP, non ha per noi troppi
segreti: si tratta di un ciclo che
va da 1 a pageSize, ovvero dalla prima fino all’ultima foto della pagina (ricordatevi che il valore di pageSize è stato definito
ad inizio pagina).
Solo con queste 2 righe,
però, rischia di generarsi un errore in fase di esecuzione.
Provate infatti a pensare cosa succede se visualizzate 35
foto in pagine da 10 elementi. Il
ciclo for next sarebbe equivalente al seguente:
for i = 1 to 10
<visualizza i dati della foto>
next
L’ultima pagina (la quarta)
contiene solo 5 foto. Il ciclo
precedente cerca in ogni caso
di visualizzare anche la foto numero 6, e il codice genera un
errore.
È necessario inserire qualche cautela, e aggiungere all’interno del ciclo qualcosa di
questo tipo:
if not rs.EOF Then
<visualizza i dati della foto>
else
exit for
end if
Il ciclo for next viene eseguito solo se ci sono altri record
nel recordset, altrimenti (con
exit for) ne forziamo l’uscita.
Ricapitoliamo la situazione
Nei paragrafi precedenti abbiamo stabilito quante foto visualizzare per ogni pagina, come fare a spostarci da una pagina all’altra, e siamo riusciti a
visualizzare senza errori tutte
le foto. A questo punto non ci
resta che visualizzare la barra
di paginazione in fondo alla pagina, e per farlo ci spostiamo a
osservare la fine del codice. Il
pezzo responsabile dell’elenco
è il seguente:
<% for j = 1 to rs.PageCount %>
<a href="<%=request.
ServerVariables("PATH_INFO")
%>?pag=<%=j%>"><%=j%></a>
<% next %>
Anche in questo caso è presente un ciclo for next, solo
che questa volta non scorriamo tra le foto di una pagina, ma
tra tutte le pagine di foto, utilizzando il metodo PageCount
dell’oggetto recordset (che come è facile intuire restituisce il
numero di pagine nel quale è
stato suddiviso l’elenco).
A questo punto è realizzato
un collegamento ipertestuale
(un link HTML), sfruttando un
metodo dell’oggetto request.
Lo scopo di request.ServerVariables(“PATH_INFO”) è quello
di estrarre il nome della pagina
ASP correntemente in esecuzione. Immaginate di aver crea5
67/97
6
to una pagina “miapagina.asp”
e di eseguirla tramite IIS (Internet Information Services): il metodo ServerVariabiles restituirà in questo caso “miapagina.asp”.
Potrebbe a prima vista sembrare una mossa poco utile, in
realtà così facendo non dovete
intervenire nel codice se un
domani decidete di rinominare
la vostra pagina ASP. Per questo motivo le 3 linee di codice
riportate poco sopra possono
essere copiate e incollate in
qualsiasi pagina necessiti della
paginazione senza doverle
adattare per i diversi scopi.
Il link viene a questo punto
completato dal parametro indicante il numero di pagina che,
come abbiamo visto precedentemente, viene usato dal recordset per posizionarsi. Per
un elenco composto di 4 pagine il risultato del ciclo sarà il
7
4a lezione
seguente:
<a href="miapagina.asp?
pag=1">1</a>
<a href="miapagina.asp?
pag=2">2</a>
<a href="miapagina.asp?
pag=3">3</a>
<a href="miapagina.asp?
pag=4">4</a>
Come sempre, al termine
della pagina rilasciamo le eventuali risorse impiegate, cioè il
recordset e la connessione.
Partendo dall’esempio appena realizzato, introduciamo ora
qualche miglioria alla paginazione presente a fondo pagina.
Se navigate abitualmente in internet, vi sarà capitato spesso
di imbattervi in un elenco di risultati diviso in più pagine.
Una caratteristica che normalmente possiede la paginazione è di non presentare un
collegamento alla pagina precedente. Per capirci, se osservate la pagina di figura 5, noterete che la paginazione contiene dei link a tutte le pagine,
fuorché la prima, che è quella
corrente.
Spostandoci alla seconda
pagina (figura 6), vediamo che
anche quest’ultima non presenta link. La ragione è duplice:
da un lato è inutile presentare
un link alla pagina corrente (visto che già ci siamo), dall’altro
guardando la paginazione è facile capire in quale pagina ci
troviamo a navigare. Per questo motivo il numero che si riferisce alla pagina corrente è
solitamente evidenziato, cosa
che del resto abbiamo fatto anche noi in questo esempio utilizzando il grassetto. La modifica necessaria per ottenere
questa caratteristica è davvero
semplice, ma migliora l’esperienza dell’utente. Se osserviamo il listato 2, notiamo che la
parte finale, dedicata alla paginazione, è stata arricchita in
questo modo:
<% for j = 1 to rs.PageCount %>
<% if j = pagNum then %>
<strong><%=j%></strong>
<% else %>
<a href="<%=request.
ServerVariables("PATH_INFO")
%>?pag=<%=j%>"><%=j%>
</a>
<% end if %>
<% next %>
strTipo%>">«</a>
<% End If %>
Il codice visualizza le frecce
verso sinistra (che in HTML
possono essere rappresentate
utilizzando l’entità «),
ma non sempre: solo quando
non ci troviamo sulla prima pagina. Il numero di pagina a cui
andare è ricavato molto semplicemente sottraendo 1 alla
pagina corrente.
In modo del tutto speculare,
dopo la paginazione abbiamo
introdotto queste istruzioni:
<% If pagNum < rs.PageCount
Then %>
<a href="<%=request.
ServerVariables("PATH_INFO")
%>?pag=<%=pagNum+1%>">
»</a>
<% End If %>
Il codice è del tutto simile all’esempio precedente, con la
sola aggiunta di un’istruzione
condizionale if...then...else. Ad
ogni iterazione il codice verifica se il ciclo è arrivato alla pagina corrente. In questo caso
non viene costruito il link, ma
viene semplicemente visualizzato il numero dopo averlo
convertito in grassetto.
Una seconda caratteristica
che è normale incontrare navigando in Internet è composta
dai pulsanti avanti e indietro,
utilizzati per spostarsi agevolmente alla pagina successiva e
a quella precedente (li abbiamo
rappresentati in figura 7 come
delle doppie frecce). Il codice
completo lo trovate nel listato
3, ma soffermiamoci sulla parte
relativa alla paginazione. Poco
prima del ciclo for...next possiamo notare questo codice:
Il significato è il medesimo,
solo che questa volta le frecce
verso destra sono introdotte
solo quando non ci troviamo
sull’ultima pagina. Ma il listato
appena presentato dispone anche di un’ulteriore caratteristica, come potete osservare se
eseguite la pagina con un
browser. Come potete osservare, i link che compongono
l’elenco delle foto sono alternativamente di due colori.
Per rendere possibile questa caratteristica, è necessario
analizzare il codice all’interno
del ciclo for...next che genera
l’elenco. Le righe che ci interessano sono:
<% If pagNum > 1 Then %>
<a href="<%=request.
ServerVariables
("PATH_INFO")%>?pag=
<%=pagNum -1%><%=
if i mod 2 = 0 then
strColor="#3333CC"
else
strColor="#FF0033"
end if
È facile intuire che l’espressione condizionale assegna alle
variabili strColor uno a scelta
tra 2 colori, ma quello che ci rimane da capire è come realizzare l’alternanza.
Abbiamo utilizzato l’operatore mod (modulo) che, posto
tra due numeri, restituisce il resto della divisione tra il primo e
il secondo. Cerchiamo di spiegarci con un esempio.
Se la variabile i vale 4, l’operazione diventa 4 mod 2. La divisione di 4 per 2 restituisce 2,
con resto 0. Quindi 4 mod 2 = 0.
Se la variabile i vale 5, la divisione restituisce 2 con resto 1,
quindi il modulo è 1.
Più in generale, il resto della
divisione tra un numero e 2 è 0
quando questo numero è pari,
altrimenti è 1. Ecco allora spiegato il significato della condizione. Potremmo interpretarla
come segue: se la variabile i è
pari, allora assegna strColor a
“#3333CC”, altrimenti (se cioè è
dispari) diventa “#FF0033”.
La variabile quindi assume
una volta il primo valore, la
volta successiva il secondo valore, proprio quello che ci saremmo aspettati.
Ma dove viene cambiato effettivamente il valore del link, e
in che modo? Responsabile del
cambiamento è la seguente linea:
<a style="color:<%=strColor%>"...
Per realizzare questo effetto
abbiamo impiegato una semplice sintassi dei CSS (Cascading Style Sheet) che ci consente di variare velocemente il colore della voce in elenco sfruttando il valore della variabile
strColor.
2 Inserire una nuova fotografia
razie a quello che abbiamo visto finora siamo in
grado senza troppi problemi di visualizzare l’elenco di
foto di Mario Rossi, anche suddividendo i risultati in più pagine. Mario ha però un’altra importante esigenza: caricare e
gestire le foto che scatterà nei
prossimi mesi.
Una prima soluzione a questa necessità potrebbe essere
G
68/97
quella di aggiornare direttamente il database Access (come abbiamo fatto la scorsa
puntata quando siamo andati a
inserire alcuni record), ma questo vuol dire portare ogni volta
tutto il database nella cartella
del server Web. La soluzione
che proponiamo, e che viene
spesso adottata da chi lavora
sul Web per aggiornare i dati,
consiste nel realizzare alcune
pagine ASP ad hoc che si
preoccupino di comunicare le
operazioni di inserimento, modifica e cancellazione direttamente al database.
La maschera di inserimento
Un esempio di maschera per
l’inserimento, che impareremo
a costruire insieme, è presentata in figura 8. In realtà Mario
non è in grado di gestire com-
pletamente l’intero processo
attraverso queste schermate. I
file JPG delle foto devono essere comunque portati sul server
“a mano”, utilizzando un programma per il trasferimento
dei file che sfrutti il protocollo
FTP (File Transfer Protocol). Nel
nostro caso non si tratta di un
limite: Mario deve semplicemente portare per prima cosa
le foto sul server, e successiva- 4a lezione
mente utilizzare le schermate
che gli mettiamo a disposizione per inserire il record nelle
tabelle, completandolo dalla
descrizione, dalla data, e da
tutte le altre informazioni che
compaiono nella scheda. Esistono in realtà componenti di
terze parti che permettono di
inviare file (documenti, immagini, video) direttamente da
una pagina ASP.
Non ne parliamo in questo
corso perché introdurremo
delle complessità che non ci
permetterebbero di concentrarci sulla sintassi SQL necessaria a completare le operazioni. Se siete interessati a questa
problematica potete ad esempio far visita all’indirizzo
www.aspupload.com, sito di
una società che sviluppa un
componente a pagamento per
gestire l’invio di file da una pagina ASP.
Inserire una nuova foto
Vediamo come aiutare Mario
ad inserire una nuova foto nel
database on line. Per prima cosa portate i file di questa lezione (che trovate nel CD ROM allegato) nella directory principale del vostro server Web,
eventualmente cancellando oppure rinominando eventuali
pagine realizzate nelle scorse
lezioni. Successivamente, come abbiamo detto, è necessario copiare le foto nella cartella
del server Web utilizzando per
esempio un programma FTP
(oppure, se state provando in
locale, è sufficiente copiare i file da una cartella a quella del
Web server). A questo punto
indirizzare il vostro browser al
file gestione_inserisci.asp (figura 9). È una pagina del tutto
simile alla lista realizzata nell’esempio precedente, che è
però dotata di un link per inserire una nuova foto. Non ci serve entrare nel dettaglio del codice sorgente, che riportiamo
nel listato 4, per cui possiamo
cliccare sul link, così da portarci nella maschera di inserimento che abbiamo visto poco
fa. In questo caso abbiamo introdotto alcune importanti novità, per cui soffermiamoci ad
analizzare nel dettaglio il codice sorgente (listato 5).
Come è lecito aspettarsi,
quasi tutto il codice della pagina è contenuto all’interno di un
form, il cui attributo action
porta alla pagina inseriscimodifica_risposta.asp.
Questa è la pagina che utilizzeremo per inserire effettivamente i dati all’interno della
tabella, e che vedremo tra poco. La parte più interessante
della pagina è quella utilizzata
per creare i due combo box per
la selezione della provincia e
dello stato. Se vi ricordate i nostri discorsi rispetto alla normalizzazione delle tabelle, che
8
69/97
9
abbiamo introdotto la scorsa
puntata, saprete che abbiamo
deciso di suddividere la tabella
foto così da separarla dai dati
della provincia e dello stato. La
tabella foto contiene unicamente un riferimento (detto
chiave esterna) alla provincia e
allo stato. L’unica informazione
che è necessario inserire nella
tabella foto è quindi il codice
della provincia e il codice dello
stato, e questa è esattamente
l’operazione che andiamo a fare in questa parte del sorgente:
<select name="provincia">
<%
sql = "SELECT * FROM Provincia
ORDER BY Provincia DESC"
rs.Open sql, conn,
adOpenForwardOnly,
10
4a lezione
adLockReadOnly
do until rs.Eof
%>
<option value="<%=rs
("IdProvincia")%>"><%=rs
("Provincia")%></option>
<% rs.movenext
loop
rs.Close()
%>
</select>
Abbiamo creato un recordset che preleva l’elenco delle
province dalla rispettiva tabella, e realizzato un controllo
HTML di tipo select. A questo
punto scorriamo il recordset e
per ogni provincia trovata aggiungiamo una voce all’elenco.
Prestate attenzione al fatto che
la descrizione viene presentata
all’utente sulla pagina, mentre
il codice della provincia (IdProvincia) viene associato all’attributo value del tag option.
Questa operazione è necessaria perché il valore da scrivere
nella tabella foto è, come dicevamo prima, il codice della provincia, mentre la descrizione è
utile solo ai fini della visualizzazione. Per rendervi conto del
risultato di questo pezzo di codice date un’occhiata al sorgente della pagina inviata al
browser. Anche per la selezione dello stato utilizziamo la
stessa tecnica, che non commentiamo ulteriormente. L’impiego di un controllo di questo
tipo è utile quando i valori da
selezionare sono in numero limitato (intorno ai 100) ed evita
all’utente di commettere qualche errore nel corso della compilazione.
Sempre in tema di semplicità
e interfaccia notate come abbiamo realizzato il campo data.
Piuttosto che utilizzare un unico campo e lasciare all’utente
la libertà di separare l’anno dal
mese e dal giorno abbiamo
scelto di utilizzare 3 campi: in
questo modo è evidente come
debbano essere compilati. Vedremo tra poco che le cautele
non terminano qui, ma che è
anche necessario verificare
che l’utente inserisca dei valori coerenti per il giorno, il mese
e l’anno. Navigando in internet
è a volte possibile trovare alcuni form in cui anche per la
data sono stati impiegati dei
combo box, come per le province e gli stati. Questa soluzione è in realtà poco efficace
per l’utente, che impiega sicuramente più tempo a scegliere
70/97
le voci dell’elenco piuttosto
che digitarle nei 3 campi, per
cui ne sconsigliamo l’adozione.
Compilate a questo punto i
dati della foto (inserendo come
data quella odierna), sullo stile
di come abbiamo fatto noi in figura 10, e premete il pulsante
Inserisci. La risposta non lascia
spazio ai dubbi: Foto inserita
correttamente. Per rendervi
conto che il record è stato effettivamente inserito provate
ad aprire con il browser la lista
delle foto, e vedrete quella appena inserita comparire in testa (compaiono per prime le foto più recenti).
La pagina responsabile dell’effettivo inserimento nella tabella è inseriscifoto_risposta.asp, che passiamo adesso
subito ad analizzare (listato 6).
A inizio della pagina vengono
estratti i valori della foto che
sono stati passati dal form. L’unica particolarità di queste righe è nella creazione della data, che viene composta partendo dal giorno, dal mese e dall’anno. Creiamo e apriamo la
solita connessione e a questo
punto definiamo la stringa SQL
che ci permette di inserire i dati.
SQL, come abbiamo avuto
modo di approfondire la scorsa
puntata, è il linguaggio utilizzato per interrogare una base di
dati, ma anche per inserire,
modificare e cancellare record.
Finora abbiamo avuto modo di
apprezzare solo la prima di
queste caratteristiche, facendoci restituire una lista di foto
oppure il dettaglio. Vediamo
ora qual è la sintassi da usare
per inserire un record (riportiamo in maiuscolo le parole
chiave):
INSERT INTO nome_tabella
(campo1, campo2, campon)
VALUES (valore1, valore2, valoren)
È un’istruzione alquanto
semplice. Specifichiamo come
prima cosa il nome della tabella in cui inserire i valori. A questo punto, tra parentesi, indichiamo il nome dei campi da
inserire; è importante che in
questa lista compaiano tutti i
campi la cui compilazione è obbligatoria, pena un errore in fase di esecuzione. A questa lista
segue la parola chiave VALUES
e infine l’elenco, sempre tra parentesi, dei valori che vogliamo
inserire. Precisiamo subito
che, come è facile intuire, il primo valore (valore1) si riferisce
al primo campo (campo1), e
così via.
Nel nostro caso specifico il
codice che abbiamo scritto è il
seguente:
sql = "INSERT INTO Foto ( Nome,
Titolo, Data, Luogo, IdProvincia,
IdStato ) VALUES (" & _
"'" & strNome & "', " & _
"'" & strTitolo & "', " & _
"'" & strData & "', " & _
"'" & strLuogo & "', " & _
"'" & strProvincia & "', " & _
"'" & strStato & "' " & _
")"
La sintassi è la medesima,
complicata solo dal fatto che
stiamo costruendo una stringa
concatenando valori diversi.
Per rendere il codice più leggibile, e per evitare di scrivere
una lunga riga con l’intera concatenazione, abbiamo preferito
terminare ogni riga con “& _”.
Così facendo è possibile andare a capo senza generare errori
in fase di esecuzione: non appena il compilatore Visual Basic Script incontra questi 2 caratteri capisce che l’istruzione
continua sulla riga successiva.
L’esecuzione
dell’istruzione SQL
Arrivati a questo punto, dopo aver creato una stringa con
l’istruzione SQL, è sufficiente
eseguirla. In questo caso non
abbiamo necessariamente bisogno di un recordset, poiché
l’unica e indivisibile operazione che ci interessa portare a
termine è l’inserimento. Possiamo allora utilizzare un comodo metodo dell’oggetto
Connection: Execute. Come potete vedere nell’ultima parte
del codice, la sintassi è semplicissima, poiché basta richiamare il metodo insieme alla
stringa con il codice SQL da
eseguire. I giochi sono fatti, il
record è stato inserito e possiamo avvisare l’utente della
conclusione dell’operazione.
Come migliorare la pagina
Realizzare una pagina di inserimento non ha richiesto
molto sforzo, ma questo tipo di
pagine (insieme a quelle che
consentono la modifica) devono essere realizzate con alcuni
accorgimenti che evitino all’utente di inserire inavvertitamente dati non corretti. In questo esempio specifico i punti di
intervento per migliorare la pagina sono diversi. Per prima
cosa è necessario verificare
che l’utente non tenti di inserire una foto con un nome già utilizzato. Se vi ricordate come
abbiamo costruito la tabella,
infatti, il campo nome è una
chiave primaria, e caratteristica di una chiave primaria è l’univocità per tutti i record della 11
4a lezione
tabella. Se l’utente tenta di in-
serire due volte lo stesso nome, quindi, è bene che venga
avvertito e l’operazione interrotta.
Un altro punto critico è l’inserimento della data. L’utente
potrebbe inserire lettere al posto dei numeri, o potrebbe ad
esempio invertire i mesi con i
giorni. È buona abitudine, prima di procedere con l’inserimento, verificare che il formato
della data sia corretto.
Infine, anche se è stato preso
ogni accorgimento affinché l’utente inserisca solo dati coerenti, qualcosa può sempre andare per il verso sbagliato. Ci
potrebbe essere un problema
di rete, o il database potrebbe
soffrire di qualche problema di
lentezza.
In tutti i casi, dopo avere
eseguito il metodo Execute, è
bene verificare qual è stato l’esito dell’operazione. Tutte queste modifiche entrano allora a
far parte di una nuova pagina,
che chiameremo inseriscifoto_risposta_2.asp, che presentiamo nel listato 7 e che cominciamo senza indugi a studiare.
Costruiamo per prima cosa
un recordset che ci aiuti nel verificare la presenza di una foto
con lo stesso nome di quella
che vogliamo inserire. Per farlo
utilizziamo una stringa SQL di
tipo SELECT e che utilizza la
funzione di aggregazione
count(), che restituisce il numero di record.
La clausola WHERE viene costruita utilizzando il nome della foto che vorremo inserire. Il
significato dell’istruzione è:
“restituisci il numero di foto
contenute nella tabella foto
con un nome uguale a quella
che si vorrebbe inserire, e chiama questo valore ‘totale’”. È
esattamente quello che vogliamo. A questo punto è sufficiente una semplice condizione per
verificare se il totale è maggiore di zero, nel qual caso esiste
già una foto in tabella con quel
nome. È la situazione che si verifica in figura 11.
L’istruzione response.end all’interno della condizione termina immediatamente l’esecuzione della pagina ASP. Si tratta
di una soluzione che abbiamo
adottato per ridurre la complessità della pagina, ma buona
regola sarebbe ripresentare la
schermata compilata dall’utente e dargli la possibilità di modificare il nome della foto senza che sia costretto a reinserire
tutti i valori.
La seconda condizione presente nella pagina verifica invece se la data inserita è in un
formato valido. L’operazione è
molto semplice in quando esiste una vera e propria istruzione pensata allo scopo: IsDate.
L’istruzione restituisce vero se
riesce a risalire a una data dalla stringa passata, falso negli altri casi.
Abbiamo fatto seguire questo controllo da un’altra cautela che è bene adottare quando si inseriscono i dati in una
tabella utilizzando direttamente il linguaggio SQL. Prima
non ci siamo soffermati su una
particolarità della stringa SQL
che andiamo a inserire, ma se
guardate con attenzione il modo con cui costruiamo la INSERT, noterete che ogni valore
è stato racchiuso da apici singoli.
Questa operazione è necessaria ogni volta che i valori da
inserire sono di tipo stringa. Un
esempio di questo tipo è dato
dalla seguente riga di codice:
INSERT INTO Foto (Nome,Titolo)
VALUES (‘DSC1234’,’Tramonto’)
Ma cosa succede se l’utente
inserisce un apice come titolo
della foto? La riga diventerà
qualche cosa del tipo:
INSERT INTO Foto (Nome,Titolo)
VALUES (‘DSC1234’,’L’alba’)
La presenza di un apice non
è indolore: durante l’esecuzione del codice si verifica un errore perché il sistema non è in
grado di distinguere tra apici
intesi come delimitatori rispetto a quelli inseriti nel testo. Un
modo in realtà esiste e consiste
nel “raddoppiare” ogni apice
presente nel valore, ottenendo
quindi questa stringa:
INSERT INTO Foto (Nome,Titolo)
VALUES (‘DSC1234’,’L’’alba’)
La modifica al nostro codice
non è complessa grazie all’impiego di un’altra importante
istruzione messa a disposizione da Visual Basic Script: replace.
La funzione replace riceve
in input 3 argomenti (in realtà
anche degli altri, ma per il nostro esercizio ne sono sufficienti solo 3): la stringa su cui
intervenire, la stringa da sostituire, e quella che sostituisce.
Ecco allora che l’istruzione
strNome =
replace(strNome,"'","''")
non fa altro che prendere il
nome della foto, sostituire
eventuali apici singoli in doppi,
e assegnare alla stessa variabile il risultato dell’operazione.
Nel nostro esempio questa sostituzione, oltre che nel nome
della foto, va estesa al titolo
della foto e al luogo di scatto.
L’ultima parte del codice della pagina si preoccupa invece
di eventuali problemi verificatesi durante l’esecuzione dell’inserimento. Per evitare che il
codice vada in condizione di
errore abbiamo fatto precedere il metodo Execute dall’istruzione on error resume next. Se
vi ricordate quanto detto nella
seconda puntata, questa istruzione impedisce l’arresto dell’esecuzione della pagina quando si verifica un errore.
A questo punto, subito dopo
l’Execute, viene richiamata una
funzione ConnError a cui è passato l’intero oggetto Connection. ConnError non è una funzione VBScript, ma è in realtà
una funzione che abbiamo
scritto noi stessi, e che potete
trovare in fondo alla pagina.
L’oggetto Connection è dotato
di una collezione di errori (con
l’oggetto Errors) che noi iteriamo, contiamo ed eventualmente stampiamo sulla pagina. La
funzione restituisce il numero
di errori riscontrati e se il totale è maggiore di zero l’utente è
avvisato del problema che si è
verificato. Ricordate di prestare sempre molta attenzione
quando date all’utente del vostro sito la possibilità di modificare e inserire record nelle tabelle. Il numero di errori che
può commettere, anche se in
buona fede, è infatti elevato:
dovrete arricchire il vostro codice di numerosi controlli e attenzioni.
3 Modificare le foto nell’elenco
ario Rossi è soddisfatto:
ha la possibilità di gestire gli inserimenti delle
proprio foto in modo semplice
e intuitivo. A questo punto avverte però la necessità di apportare modifiche ai dati inseriti precedentemente. È una situazione abbastanza comune:
potrebbe voler aggiungere
informazioni a foto già caricate
o semplicemente correggere
M
71/97
qualche errore di inserimento.
Per dare a Mario questa possibilità, interveniamo per prima
cosa sul codice della pagina di
gestione, quella che contiene
l’elenco di foto su cui intervenire. La figura 12 illustra il pannello di controllo: come potete
osservare accanto a ogni voce
compare la possibilità di modificare la foto. Un’alternativa
sarebbe stata quella di creare
una maschera di ricerca ad
hoc, ma la soluzione che proponiamo è più generale (la useremo anche per la cancellazione) e semplice (riportiamo il
codice nel listato 8). L’unica
parte interessante dell’intera
pagina è proprio il link:
[<a href="modificafoto.asp?
nome=<%=rs("nome")%>">
modifica</a>]
Viene caricata la pagina modificafoto.asp e le è passato il
nome (cioè l’identificativo univoco, essendo chiave primaria) della foto da aggiornare.
Se provate a selezionare la
modifica di una foto si aprirà
una pagina contenente, come
ci saremmo aspettati, un form
non tutti i dati della foto (figura
13), anche se in realtà noterete
che non è prevista la modifica
4a lezione
12
del nome. In effetti dovreste
valutare attentamente se concedere ai vostri utenti la modifica della chiave primaria di
una tabella.
Cosa succede se l’utente
tenta di modificare il nome della foto con quello di una foto
già presente nella tabella?
Quale delle due foto dobbiamo mantenere e quale rinominare?
Solitamente, ma questa non
è una regola (la soluzione dipende dal tipo di dati che state
gestendo), la chiave primaria
non è modificabile. Se l’utente
desidera cambiarla, elimina la
foto dalla tabella e reinserisce
nuovamente i dati, e questa è
la soluzione che adottiamo nel
nostro caso.
Il codice di modificafoto.asp
(listato 9) è del tutto simile a
quello di inseriscifoto.asp, con
la sola eccezione che i campi
sono già compilati con i dati
della foto.
Come vi ricorderete, la pagina è richiamata passando il nome della foto.
A questo punto creiamo una
connessione e un recordset
che restituisca un record contenente tutti i dati della foto da
utilizzare per riempire i campi.
Per i tag di tipo “text” la modifica è molto semplice, e consiste nell’utilizzare l’attributo value. Osserviamo ad esempio il
72/97
campo titolo:
<input type="text" size="20"
name="titolo" maxlenght="255"
value="<%=rs("titolo")%>">
La riga non ha bisogno di
troppi commenti: nella casella
che contiene il testo è estratto
il valore del campo titolo. Il tag
per il campo luogo si comporta nello stesso modo, mentre
per la data la situazione è leggermente diversa, poiché si
tratta di dividere l’informazione su 3 campi. In questo caso
ci vengono in aiuto le funzioni
Day, Month e Year che come è
facile immaginare restituiscono il giorno, il mese e l’anno di
una data passata come parametro.
If rs2("IdProvincia") =
rs("IdProvincia") Then
strSuffisso = " selected"
Else
strSuffisso = ""
End If
Rs2 è il recordset che contiene l’elenco di tutte le province, mentre rs è il recordset
che si riferisce alla foto attualmente in modifica. Il controllo
è molto semplice: se la provincia che stiamo visualizzando
dall’elenco è la stessa della foto, associamo alla variabile strSuffisso il valore “selected”, altrimenti lasciamo la variabile
senza valore.
A questo punto usiamo questa stringa per completare la
voce dell’elenco in HTML. Se in
una combo box utilizzare l’attributo selected, questa voce
apparirà selezionata nell’elenco, ed è proprio quello che vogliamo. La stessa cosa si verifica, come potete immaginare,
anche per la selezione dello
stato.
Notate anche che nella pagina compare un campo nascosto, il nome della foto. Abbiamo inserito questo valore per
poter passare il nome della foto alla prossima pagina, che
userà il valore per sapere quale foto aggiornare tra tutti i record presenti nella tabella.
Non c’è altro di interessante
in questa pagina, per cui passiamo a vedere cosa contiene
la pagina di risposta, che è anche la pagina che si preoccupa
dell’aggiornamento: modificafoto_risposta.asp (listato
10).
La pagina contiene già tutti
gli accorgimenti che abbiamo
introdotto in fase di inserimento di una foto, ovvero le
cautele in caso di errore, la gestione dell’accento singolo e il
controllo sul formato della data. Quella che cambia è sostanzialmente la sintassi del
comando SQL, che per un aggiornamento ha una forma del
tipo:
UPDATE nome_tabella SET
campo1 = valore1, campo2 =
valore2, campon = valoren WHERE
condizione
Il significato è immediato:
“aggiorna il campo1 della tabella nome_tabella con il valore1, ecc”. Prestate sempre attenzione a specificare la clausola WHERE. Nel nostro caso,
infatti, la sola foto che vogliamo aggiornare è quella con il
nome specificato, ma un comando di UPDATE può agire su
un qualunque numero di record di una tabella (anche tutti, se non specificate alcuna
clausola WHERE).
Per eseguire questa istruzione è sempre possibile utilizzare l’utile metodo Execute
della connessione, senza dover aprire recordset.
13
I controlli di tipo combo box
Passiamo adesso a qualcosa
di più complicato. Quando si
tratta di visualizzare la provincia e lo stato siamo di fronte a
controlli di tipo combo box,
che visualizzano una lista di
tutte le selezioni possibili.
L’esigenza in questo caso è
di aprire un recordset di province, estrarle e visualizzarle
tutte, ma anche evidenziare e
selezionare quella associata alla foto.
Per farlo inseriamo una condizione all’interno del ciclo seguente:
4a lezione
4 Cancellare una fotografia
’ ultima fase che ci rimane
da affrontare per chiudere
il percorso sull’aggiornamento del catalogo riguarda
la cancellazione. Dobbiamo
cioè scoprire come eliminare
una fotografia dall’elenco.
Come nel caso della modifica, anche in questo caso aggiungiamo una voce a destra
del nome della foto, nell’elenco, evidenziando questa possibilità (figura 14).
La rimozione di una foto dal
database è un’operazione che
non richiede il passaggio a una
schermata in cui inserire o modificare dei valori: è un’azione
diretta.
Per questo motivo non è necessario produrre una pagina
eliminafoto.asp (come è stato
per inseriscifoto.asp e modificafoto.asp), ma possiamo direttamente passare alla costruzione di eliminafoto_risposta.asp.
La cancellazione di una foto
è però un’operazione a rischio:
se l’utente preme inavvertitamente il link elimina, la foto viene tolta dalla tabella senza che
sia possibile annullare l’operazione.
Per questo genere di azioni è
importante introdurre una
qualche forma di avvertimento
da parte del browser per chiedere all’utente quali sono le
sue effettive intenzioni (qualcosa di simile a quello che
compare in figura 15).
L’utente che ha inavvertitamente premuto il pulsante di
cancellazione ha la possibilità
di annullare l’operazione, mentre chi è deciso a cancellare la
foto può semplicemente confermare.
Questo tipo di controllo non
ha nulla a che fare con ASP o
con il codice VBScript (che viene eseguito a lato server), ma è
realizzato dal lato del client (è
cioè il browser stesso che lo
esegue) utilizzando codice Javascript.
Il codice è tutto all’interno
del link per la cancellazione:
L
[<a onclick="javascript:return
confirm('Cancellare la foto
selezionata ?')"
href="eliminafoto_risposta.asp?
nome=<%=rs("nome")%>">
elimina</a>]
73/97
Il codice precedente apre
una finestra di richiesta (confirm) quando l’utente clicca
sul link (evento onclick). A
questo punto il browser apre
la pagina con il link solo in caso di risposta affermativa alla
domanda, altrimenti non è caricata nessuna pagina, ma la
visualizzazione rimane a quella corrente.
Avremmo anche potuto realizzare un controllo lato server, con una schermata HTML
contentente la scritta di conferma all’interno di un form,
ma l’utente avrebbe dovuto
compiere due richieste e non
solo una al server Web, rendendo l’operazione (per quanto non sia una routine) abbastanza lenta.
14
La sintassi del codice
per la cancellazione
Non ci resta a questo punto
che guardare il codice che si
occupa della cancellazione
(presente nel listato 11).
Come potete immaginare
l’unica cosa che cambia rispetto agli esempi precedenti
è la sintassi del comando SQL
che permette di eliminare un
record dalla tabella. Questo ha
una forma del tipo:
DELETE FROM nome_tabella
WHERE condizione
Non c’è bisogno di specificare alcun nome di campo:
quando si cancella un record
si cancellano i valori di tutti i
campi, è quindi inutile specificarli.
Come per l’UPDATE, prestate attenzione a specificare una
clausola WHERE che comprenda i record che volete
cancellare, e solo quelli. La
cancellazione può essere effettuata da un minimo di un record, a un massimo che corrisponde a tutta la tabella.
Mario Rossi ha a questo
punto tutto quello che gli serve: può inserire una nuova foto, modificarla ed eventualmente cancellarla. Non solo:
ha un sistema di visualizzazione presente nel suo sito che
organizza le foto per ordine di
data e presenta una simpatica
navigazione per scorrere le pagina avanti e indietro.
A questo punto non gli resta
che scattare tante foto da mettere presto on line!
Conclusione
Con questa puntata termina
il corso di 4 puntate dedicate
al mondo ASP.
Siamo passati da una fase di
introduzione della sintassi del
linguaggio, e siamo arrivati a
comunicare con i database,
spingendoci fino a inserire e
modificare dati nelle tabelle.
Disponete adesso delle basi
per sbizzarrirvi nella realizzazione del vostro sito personale, e perché no, anche professionale.
Le applicazioni da realizzare non mancano di certo: potete realizzare una agenda da
consultare, un elenco dei film
e album preferiti, e magari un
guestbook per i visitatori del
vostro sito: tutte applicazioni
che sfruttano quanto appreso
in queste 4 puntate. A questo
punto l’unico limite a quello
che potete fare con ASP è dato
unicamente dalla vostra fantasia...buon lavoro!
I listati citati nell’articolo sono
nel CD Guida 2 nella sezione
“Corsi Open Master”
15
Cliccate qui per accedere alla versione elettronica dei listati.
LISTATO 1
ELENCOFOTO2.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Le foto di Mario Rossi</title>
</head>
<body>
<h1>Le mie foto preferite</h1>
Hai selezionato le foto che parlano di <%=request.QueryString("rfoto")%><br>
<%
Const adOpenStatic = 3
Const adLockReadOnly = 1
Const adOpenForwardOnly = 0
Dim
Dim
Dim
Dim
Dim
Dim
contatore
sql1,sql2
conn, rs
pagNum
pagSize
i,j
pagSize = 2
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
sql1 = "SELECT count(nome) AS contatore FROM Foto WHERE Titolo like '%" &
request.QueryString("rfoto") & "%'"
sql2 = "SELECT * FROM Foto WHERE Titolo like '%" & request.QueryString("rfoto")
& "%' ORDER BY Data DESC "
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql1, conn, adOpenForwardOnly, adLockReadOnly
contatore = rs("contatore")
rs.Close()
'Estrae il numero di pagina
pagNum = cint(request.QueryString("pag"))
If pagNum = 0 Then pagNum = 1
'Imposta la dimensione della pagina (il numero massimo di elementi da far
comparire per ogni pagina)
rs.PageSize = pagSize
rs.Open sql2, conn, adOpenStatic, adLockReadOnly
74/97
%>
Sono presenti <%=contatore%> foto che soddisfano i criteri di ricerca<br><br>
<%
rs.AbsolutePage = pagNum
for i = 1 to pagSize
if not rs.EOF Then
%>
<li><a href="dettagliofoto.asp?nome=<%=rs("Nome")%>"><%=rs("Titolo")%>, scattata
a <%=rs("Luogo")%></a></li>
<%
rs.movenext
Else
Exit For
End If
next
%>
<br><hr><br>
<div align="left">
<% for j = 1 to rs.PageCount %>
<a href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=j%>"><%=j%></a>
<% next %>
</div>
<%
rs.close
set rs = nothing
conn.close
set conn = nothing
%>
</ul>
</body>
</html>
75/97
LISTATO 2
ELENCOFOTO3.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Le foto di Mario Rossi</title>
</head>
<body>
<h1>Le mie foto preferite</h1>
Hai selezionato le foto che parlano di <%=request.QueryString("rfoto")%><br>
<%
Const adOpenStatic = 3
Const adLockReadOnly = 1
Const adOpenForwardOnly = 0
Dim
Dim
Dim
Dim
Dim
Dim
contatore
sql1,sql2
conn, rs
pagNum
pagSize
i,j
pagSize = 2
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
sql1 = "SELECT count(nome) AS contatore FROM Foto WHERE Titolo like '%" &
request.QueryString("rfoto") & "%'"
sql2 = "SELECT * FROM Foto WHERE Titolo like '%" & request.QueryString("rfoto")
& "%' ORDER BY Data DESC "
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql1, conn, adOpenForwardOnly, adLockReadOnly
contatore = rs("contatore")
rs.Close()
'Estrae il numero di pagina
pagNum = cint(request.QueryString("pag"))
If pagNum = 0 Then pagNum = 1
'Imposta la dimensione della pagina (il numero massimo di elementi da far
comparire per ogni pagina)
rs.PageSize = pagSize
rs.Open sql2, conn, adOpenStatic, adLockReadOnly
%>
76/97
Sono presenti <%=contatore%> foto che soddisfano i criteri di ricerca<br><br>
<%
rs.AbsolutePage = pagNum
for i = 1 to pagSize
if not rs.EOF Then
%>
<li><a href="dettagliofoto.asp?nome=<%=rs("Nome")%>"><%=rs("Titolo")%>, scattata
a <%=rs("Luogo")%></a></li>
<%
rs.movenext
Else
Exit For
End If
next
%>
<br><hr><br>
<div align="left">
<% for j = 1 to rs.PageCount %>
<% if j = pagNum then %>
<strong><%=j%></strong>
<% else %>
<a
href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=j%>"><%=j%></a>
<% end if %>
<% next %>
</div>
<%
rs.close
set rs = nothing
conn.close
set conn = nothing
%>
</ul>
</body>
</html>
77/97
LISTATO 3 – ELENCOFOTO4.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Le foto di Mario Rossi</title>
</head>
<body>
<h1>Le mie foto preferite</h1>
Hai selezionato le foto che parlano di <%=request.QueryString("rfoto")%><br>
<%
Const adOpenStatic = 3
Const adLockReadOnly = 1
Const adOpenForwardOnly = 0
Dim
Dim
Dim
Dim
Dim
Dim
contatore
sql1,sql2
conn, rs
pagNum
pagSize
i,j
pagSize = 2
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
sql1 = "SELECT count(nome) AS contatore FROM Foto WHERE Titolo like '%" &
request.QueryString("rfoto") & "%'"
sql2 = "SELECT * FROM Foto WHERE Titolo like '%" & request.QueryString("rfoto")
& "%' ORDER BY Data DESC "
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql1, conn, adOpenForwardOnly, adLockReadOnly
contatore = rs("contatore")
rs.Close()
'Estrae il numero di pagina
pagNum = cint(request.QueryString("pag"))
If pagNum = 0 Then pagNum = 1
'Imposta la dimensione della pagina (il numero massimo di elementi da far
comparire per ogni pagina)
rs.PageSize = pagSize
rs.Open sql2, conn, adOpenStatic, adLockReadOnly
%>
Sono presenti <%=contatore%> foto che soddisfano i criteri di ricerca<br><br>
78/97
<%
rs.AbsolutePage = pagNum
for i = 1 to pagSize
if not rs.EOF Then
if i mod 2 = 0 then
strColor="#3333CC"
else
strColor="#FF0033"
end if
%>
<li><a style="color:<%=strColor%>"
href="dettagliofoto.asp?nome=<%=rs("Nome")%>"><%=rs("Titolo")%>, scattata a
<%=rs("Luogo")%></a></li>
<%
rs.movenext
Else
Exit For
End If
next
%>
<br><hr><br>
<div align="left">
<%
If pagNum > 1 Then %>
<a href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=pagNum 1%><%=strTipo%>">«</a>
<%
End If %>
<% for j = 1 to rs.PageCount %>
<% if j = pagNum then %>
<strong><%=j%></strong>
<% else %>
<a
href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=j%><%=strTipo%>"><%=j%></
a>
<% end if %>
<% next %>
<%
If pagNum < rs.PageCount Then %>
<a
href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=pagNum+1%>">»</a>
<%
End If %>
</div>
79/97
<%
rs.close
set rs = nothing
conn.close
set conn = nothing
%>
</ul>
</body>
</html>
80/97
LISTATO 4
GESTIONEINSERISCI.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gestione foto di Mario Rossi</title>
</head>
<body>
<h1>Gestione foto</h1>
<%
Const adOpenForwardOnly = 0
Const adLockReadOnly = 1
Dim
Dim
Dim
Dim
Dim
Dim
contatore
sql1,sql2
conn, rs
pagNum
pagSize
i,j
pagSize = 2
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
sql1 = "SELECT count(nome) AS contatore FROM Foto"
sql2 = "SELECT * FROM Foto ORDER BY Data DESC"
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql1, conn, adOpenForwardOnly, adLockReadOnly
contatore = rs("contatore")
rs.Close()
'Estrae il numero di pagina
pagNum = cint(request.QueryString("pag"))
If pagNum = 0 Then pagNum = 1
'Imposta la dimensione della pagina (il numero massimo di elementi da far
comparire per ogni pagina)
rs.PageSize = pagSize
rs.Open sql2, conn, 3, adLockReadOnly
%>
Foto presenti nella base di dati: <%=contatore%><br><br>
Inserisci una <a href="inseriscifoto.asp">nuova foto</a>
<%
81/97
rs.AbsolutePage = pagNum
for i = 1 to pagSize
if not rs.EOF Then
if i mod 2 = 0 then
strColor="#3333CC"
else
strColor="#FF0033"
end if
%>
<li>
<a style="color:<%=strColor%>"
href="dettagliofoto.asp?nome=<%=rs("Nome")%>"><%=rs("Titolo")%>, scattata a
<%=rs("Luogo")%></a>
</li>
<%
rs.movenext
Else
Exit For
End If
next
%>
<br><hr><br>
<div align="left">
<%
If pagNum > 1 Then
%>
<a href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=pagNum 1%><%=strTipo%>">«</a>
<%
End If
%>
<% for j = 1 to rs.PageCount %>
<% if j = pagNum then %>
<%=j%>
<% else %>
<a
href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=j%><%=strTipo%>"><%=j%></
a>
<% end if %>
<% next %>
<%
If pagNum < rs.PageCount Then
%>
82/97
<a
href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=pagNum+1%><%=strTipo%>">&
raquo;</a>
<%
End If
%>
</div>
<%
rs.close
set rs = nothing
conn.close
set conn = nothing
%>
</ul>
</body>
</html>
83/97
LISTATO 5
INSERISCIFOTO.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gestione foto di Mario Rossi</title>
</head>
<body>
<h1>Inserimento nuova foto</h1>
<%
Const adOpenForwardOnly = 0
Const adLockReadOnly = 1
Dim
Dim
Dim
Dim
contatore
sql1,sql2
conn, rs
i,j
Set conn = Server.CreateObject("ADODB.Connection")
Set rs = Server.CreateObject("ADODB.Recordset")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
%>
<form action="inseriscifoto_risposta.asp" method="post" cellpadding="2"
cellspacing="2">
<table border="0">
<tr>
<td>Nome</td>
<td><input type="text" size="20" name="nome" maxlenght=""></td>
</tr>
<tr>
<td>Titolo</td>
<td><input type="text" size="20" name="titolo" maxlenght=""></td>
</tr>
<tr>
<td>Data</td>
<td><input type="text" size="2" name="datagg" maxlenght="2">/<input
type="text" size="2" name="datamm" maxlenght="2">/<input type="text" size="4"
name="datayyyy" maxlenght="4"></td>
</tr>
<tr>
<td>Luogo</td>
<td><input type="text" size="20" name="luogo" maxlenght=""></td>
</tr>
<tr>
<td>Provincia</td>
<td>
<select name="provincia">
<%
84/97
sql = "SELECT * FROM Provincia ORDER BY Provincia DESC "
rs.Open sql, conn, adOpenForwardOnly, adLockReadOnly
do until rs.Eof
%>
<option
value="<%=rs("IdProvincia")%>"><%=rs("Provincia")%></option>
<%
rs.movenext
loop
rs.Close()
%>
</select>
</td>
</tr>
<tr>
<td>Stato</td>
<td>
<select name="stato">
<%
sql = "SELECT * FROM Stato ORDER BY Stato DESC "
rs.Open sql, conn, adOpenForwardOnly, adLockReadOnly
do until rs.Eof
%>
<option value="<%=rs("IdStato")%>"><%=rs("Stato")%></option>
<%
rs.movenext
loop
rs.Close()
%>
</select>
</td>
</tr>
<tr>
<td align="right" colspan="2"><input type="submit" name="invia"
value="Inserisci"></td>
</tr>
</table>
</form>
</body>
</html>
<%
set rs = nothing
conn.close
set conn = nothing
%>
85/97
LISTATO 6
INSERISCIFOTO_RISPOSTA.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gestione foto di Mario Rossi</title>
</head>
<body>
<h1>Inserimento nuova foto</h1>
<%
Dim contatore
Dim sql
Dim strNome, strTitolo, strData, strLuogo, strProvincia, strStato
strNome = request.Form("nome")
strTitolo = request.Form("titolo")
strData = request.Form("datagg") & "/" & request.Form("datamm") & "/" &
request.Form("datayyyy")
strLuogo = request.Form("luogo")
strProvincia = request.Form("provincia")
strStato = request.Form("stato")
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
sql = "INSERT INTO Foto ( Nome, Titolo, Data, Luogo, IdProvincia, IdStato )
VALUES (" & _
"'" & strNome & "', " & _
"'" & strTitolo & "', " & _
"'" & strData & "', " & _
"'" & strLuogo & "', " & _
"'" & strProvincia & "', " & _
"'" & strStato & "' " & _
")"
response.write sql
conn.Execute sql
conn.close
set conn = nothing
%>
Foto inserita correttamente
86/97
LISTATO 7
INSERISCIFOTO_RISPOSTA_2.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gestione foto di Mario Rossi</title>
</head>
<body>
<h1>Inserimento nuova foto</h1>
<%
Const adOpenForwardOnly = 0
Const adLockReadOnly = 1
Dim
Dim
Dim
Dim
contatore
sql1,sql2
conn, rs
i,j
Dim strNome, strTitolo, strData, strLuogo, strProvincia, strStato
strNome = request.Form("nome")
strTitolo = request.Form("titolo")
strData = request.Form("datagg") & "/" & request.Form("datamm") & "/" &
request.Form("datayyyy")
strLuogo = request.Form("luogo")
strProvincia = request.Form("provincia")
strStato = request.Form("stato")
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
sql = "SELECT count(*) AS totale FROM Foto WHERE nome = '" &
request.Form("nome") & "'"
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql, conn, adOpenForwardOnly, adLockReadOnly
'Qualche controllo
If rs("totale") > 0 Then
'Esiste una foto già inserita con lo stesso ID
response.write "Questo nome di foto esiste già nella tabella, devi
sceglierne un altro<br>"
response.write "Ritorna alla<a href=""inseriscifoto.asp"">pagina di
inserimento</a>"
response.end
End If
If Not IsDate(strData) Then
'Data in formato non valido
response.write "La data inserita (" & strData & ") non è valida<br>"
response.write "Ritorna alla<a href=""inseriscifoto.asp"">pagina di
inserimento</a>"
87/97
response.end
End If
'Rinforzo l'accento per evitare problemi in inserimento
strNome
= replace(strNome,"'","''")
strTitolo = replace(strTitolo,"'","''")
strLuogo = replace(strLuogo,"'","''")
sql = "INSERT INTO Foto ( Nome, Titolo, Data, Luogo, IdProvincia, IdStato )
VALUES (" & _
"'" & strNome & "', " & _
"'" & strTitolo & "', " & _
"'" & strData & "', " & _
"'" & strLuogo & "', " & _
"'" & strProvincia & "', " & _
"'" & strStato & "' " & _
")"
on error resume next
conn.Execute sql
If ConnError(conn) >
response.write
dati.<br>"
response.write
inserimento</a>"
Else
response.write
response.write
foto</a>"
End If
0 Then
"Si è verificato un problema con l'inserimento dei
"Ritorna alla <a href=""inseriscifoto.asp"">pagina di
"I dati della foto sono stati inseriti correttamente<br>"
"Ritorna all'<a href=""gestione.asp"">elenco delle
on error goto 0
set rs = nothing
conn.close
set conn = nothing
Function ConnError(conn)
Dim i
i = 0
For Each errorObject In conn.Errors
i = i + 1
Response.Write "ERRORE: " & errorObject.Description & "<br><br>"
Next
ConnError = i
End Function
%>
88/97
LISTATO 8
GESTIONE_MODIFICA.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gestione foto di Mario Rossi</title>
</head>
<body>
<h1>Gestione foto</h1>
<%
Const adOpenForwardOnly = 0
Const adLockReadOnly = 1
Dim
Dim
Dim
Dim
Dim
Dim
contatore
sql1,sql2
conn, rs
pagNum
pagSize
i,j
pagSize = 2
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
sql1 = "SELECT count(nome) AS contatore FROM Foto"
sql2 = "SELECT * FROM Foto ORDER BY Data DESC"
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open sql1, conn, adOpenForwardOnly, adLockReadOnly
contatore = rs("contatore")
rs.Close()
'Estrae il numero di pagina
pagNum = cint(request.QueryString("pag"))
If pagNum = 0 Then pagNum = 1
'Imposta la dimensione della pagina (il numero massimo di elementi da far
comparire per ogni pagina)
rs.PageSize = pagSize
rs.Open sql2, conn, 3, adLockReadOnly
%>
Foto presenti nella base di dati: <%=contatore%><br><br>
Inserisci una <a href="inseriscifoto.asp">nuova foto</a>
<%
89/97
rs.AbsolutePage = pagNum
for i = 1 to pagSize
if not rs.EOF Then
if i mod 2 = 0 then
strColor="#3333CC"
else
strColor="#FF0033"
end if
%>
<li>
<a style="color:<%=strColor%>"
href="dettagliofoto.asp?nome=<%=rs("Nome")%>"><%=rs("Titolo")%>, scattata a
<%=rs("Luogo")%></a>
[<a href="modificafoto.asp?nome=<%=rs("nome")%>">modifica</a>]
</li>
<%
rs.movenext
Else
Exit For
End If
next
%>
<br><hr><br>
<div align="left">
<%
If pagNum > 1 Then
%>
<a href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=pagNum 1%><%=strTipo%>">«</a>
<%
End If
%>
<% for j = 1 to rs.PageCount %>
<% if j = pagNum then %>
<%=j%>
<% else %>
<a
href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=j%><%=strTipo%>"><%=j%></
a>
<% end if %>
<% next %>
<%
If pagNum < rs.PageCount Then
90/97
%>
<a
href="<%=request.ServerVariables("PATH_INFO")%>?pag=<%=pagNum+1%><%=strTipo%>">&
raquo;</a>
<%
End If
%>
</div>
<%
rs.close
set rs = nothing
conn.close
set conn = nothing
%>
</ul>
</body>
</html>
91/97
LISTATO 9
MODIFICAFOTO.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gestione foto di Mario Rossi</title>
</head>
<body>
<h1>Modifica foto esistente</h1>
<%
Const adOpenForwardOnly = 0
Const adLockReadOnly = 1
Dim
Dim
Dim
Dim
Dim
contatore
sql
conn, rs, rs2
i,j
strSuffisso
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
sql = "SELECT * FROM Foto WHERE nome = '" & request.QueryString("nome") & "'"
Set rs = Server.CreateObject("ADODB.RecordSet")
Set rs2 = Server.CreateObject("ADODB.RecordSet")
rs.Open sql, conn, adOpenForwardOnly, adLockReadOnly
%>
<form action="modificafoto_risposta.asp" method="post" cellpadding="2"
cellspacing="2">
<table border="0">
<tr>
<td>Nome</td>
<td><%=rs("nome")%><input type="hidden" name="nome"
value="<%=rs("nome")%>"></td>
</tr>
<tr>
<td>Titolo</td>
<td><input type="text" size="20" name="titolo" maxlenght="255"
value="<%=rs("titolo")%>"></td>
</tr>
<tr>
<td>Data</td>
<td><input type="text" size="2" name="datagg" maxlenght="2"
value="<%=Day(rs("data"))%>">/
<input type="text" size="2" name="datamm" maxlenght="2"
value="<%=Month(rs("data"))%>">/
92/97
<input type="text" size="4" name="datayyyy" maxlenght="4"
value="<%=Year(rs("data"))%>"></td>
</tr>
<tr>
<td>Luogo</td>
<td><input type="text" size="20" name="luogo" maxlenght="255"
value="<%=rs("luogo")%>"></td>
</tr>
<tr>
<td>Provincia</td>
<td>
<select name="provincia">
<%
sql = "SELECT * FROM Provincia ORDER BY Provincia DESC "
rs2.Open sql, conn, adOpenForwardOnly, adLockReadOnly
do until rs2.Eof
If rs2("IdProvincia") = rs("IdProvincia") Then
strSuffisso = " selected"
Else
strSuffisso = ""
End If
%>
<option
value="<%=rs2("IdProvincia")%>"<%=strSuffisso%>><%=rs2("Provincia")%></option>
<%
rs2.movenext
loop
rs2.Close()
%>
</select>
</td>
</tr>
<tr>
<td>Stato</td>
<td>
<select name="stato">
<%
sql = "SELECT * FROM Stato ORDER BY Stato DESC "
rs2.Open sql, conn, adOpenForwardOnly, adLockReadOnly
do until rs2.Eof
If rs2("IdStato") = rs("IdStato") Then
strSuffisso = " selected"
Else
strSuffisso = ""
End If
%>
<option
value="<%=rs2("IdStato")%>"<%=strSuffisso%>><%=rs2("Stato")%></option>
<%
rs2.movenext
loop
rs2.Close()
%>
</select>
93/97
</td>
</tr>
<tr>
<td align="right" colspan="2"><input type="submit" name="invia"
value="Modifica"></td>
</tr>
</table>
</form>
</body>
</html>
<%
rs.close
set rs = nothing
set rs2 = nothing
conn.close
set conn = nothing
%>
94/97
LISTATO 10
MODIFICAFOTO_RISPOSTA.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gestione foto di Mario Rossi</title>
</head>
<body>
<h1>Modifica di una foto</h1>
<%
Const adOpenForwardOnly = 0
Const adLockReadOnly = 1
Dim
Dim
Dim
Dim
contatore
sql1,sql2
conn, rs
i,j
Dim strNome, strTitolo, strData, strLuogo, strProvincia, strStato
strNome = request.Form("nome")
strTitolo = request.Form("titolo")
strData = request.Form("datagg") & "/" & request.Form("datamm") & "/" &
request.Form("datayyyy")
strLuogo = request.Form("luogo")
strProvincia = request.Form("provincia")
strStato = request.Form("stato")
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
If Not IsDate(strData) Then
'Data in formato non valido
response.write "La data inserita (" & strData & ") non è valida<br>"
response.write "Ritorna alla<a href=""gestione.asp"">pagina di
gestione</a>"
response.end
End If
'Rinforzo l'accento per evitare problemi in inserimento
strTitolo = replace(strTitolo,"'","''")
strLuogo = replace(strLuogo,"'","''")
sql = "UPDATE Foto SET " & _
" Foto.Data = '" & strData & "', " & _
" Foto.Titolo = '" & strTitolo & "'," & _
" Foto.Luogo = '" & strLuogo & "', " & _
" Foto.IdProvincia = '" & strProvincia & "', " & _
" Foto.IdStato = '" & strStato & "'" & _
" WHERE Foto.Nome = '" & strNome & "'"
on error resume next
95/97
conn.Execute sql
If ConnError(conn) >
response.write
response.write
gestione</a>"
Else
response.write
response.write
gestione</a>"
End If
0 Then
"Si è verificato un problema con la modifica dei dati.<br>"
"Ritorna alla <a href=""gestione.asp"">pagina di
"I dati della foto sono stati modificati correttamente<br>"
"Ritorna alla <a href=""gestione.asp"">pagina di
on error goto 0
set rs = nothing
conn.close
set conn = nothing
Function ConnError(conn)
Dim i
i = 0
For Each errorObject In conn.Errors
i = i + 1
Response.Write "ERRORE: " & errorObject.Description & "<br><br>"
Next
ConnError = i
End Function
%>
96/97
LISTATO 11
ELIMINAFOTO_RISPOSTA.ASP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gestione foto di Mario Rossi</title>
</head>
<body>
<h1>Elimina foto</h1>
<%
Dim sql
Dim conn
Dim i
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" &
server.MapPath("/mdb-database/foto2.mdb")
sql = "DELETE FROM Foto WHERE nome = '" & request.QueryString("nome") & "'"
on error resume next
conn.Execute sql
If ConnError(conn) >
response.write
foto.<br>"
response.write
foto</a>"
Else
response.write
response.write
foto</a>"
End If
0 Then
"Si è verificato un problema con l'eliminazione della
"Ritorna all'<a href=""gestione.asp"">elenco delle
"La foto è stata eliminata correttamente<br>"
"Ritorna all'<a href=""gestione.asp"">elenco delle
on error goto 0
set conn = nothing
Function ConnError(conn)
Dim i
i = 0
For Each errorObject In conn.Errors
i = i + 1
Response.Write "ERRORE: " & errorObject.Description & "<br><br>"
Next
ConnError = i
End Function
%>
97/97