(tratto dal sito:http://freeasp.html.it/guide/lezioni.asp?idguida=1 - di Giorgio Gobbo) - WWW.HTML.IT

CORSO DI ASP

1.       SP, che cosa è? A cosa serve?

Breve introduzione al linguaggio ASP.

2.       I primi passi

Cominciamo dall'inizio con qualche semplice esempio

3.       Scaviamo un pò le fondamenta

I primi oggetti, metodi e proprietà.

4.       Dai, facciamo qualcosa un pò più divertente ;o)

Il primo esempio concreto.

5.       Il Request oggetto continua

Le collezioni Form e Querystring.

6.       L'architettura dell' ASP object model

La struttura del file global.asa.

7.       Vbscript e le lingue che usiamo per parlare con il browser

Primi concetti del linguaggio Visual Basic Script.

8.       Usare Funzioni & Procedure

Primi passi verso la programmazione

9.       E adesso la vera ragione per cui adoperiamo tecnologie come ASP

Cominciamo a capire il motivo per cui utilizzare ASP

10.    Database access with ADO

La prima connessione ad un database

11.    Facciamo la conoscenza con il Connection e il Recorset

L'oggetto Recordset: cosa è e come gestirlo

12.    Conoscenza col Connection e Recordset non basta

Ulteriori informazioni sul Recordset

13.    Non ho ancora finito. Lezione pratica.

Inserire informazioni in un database tramite form.

14.    Come presentare l'Output

Suggerimenti su come impostare l'output delle informazioni.

15.    Come lavorare dal letto

Automatizzare al massimo le nostre applicazioni.

16.    Il pannello di controllo

Creare un pannello di controllo per l'applicazione

17.    Come mantenere i nostri dati

Dare la possibilità di modificare le informazioni da pannello.

18.    Le News non bastano

Personalizzare con email il tutto.

19.    E poi possiamo partire per l'Australia

Gestire i feedback dell'applicazione.

20.    Vogliamo degli altri in Ufficio?

Gestire più utenti nel pannello di controllo.

21.    Allora diamogli le chiavi e facciamoli lavorare

Dare l'accesso agli altri utenti.

22.    Conclusione

Conclusioni e suggerimenti.

 

Lo sai cosa è un protocollo no?

Beh, nel caso che il termine sia nuovo, un protocollo è un gruppo di regole che ci permettono di comunicare l'uno con l'altro. Per esempio, l'italiano è un protocollo, lo stringere la mano quando ci si incontra, adoperare il coltello e la forchetta, fermarsi quando il semaforo è rosso (non un buon esempio per gli italiani) sono tutti protocolli. Quando due eskimesi si incontrano si strofinano il naso, i russi si baciano 3 volte, gli inglesi una, gli italiani due, ecc. E' così che ci capiamo.

L'unica cosa importante è che tutti coloro che sono coinvolti nella comunicazione condividano le stesse regole.

 

L'HTTP (HyperText Transfer Protocol), la lingua franca dell'internet, è un protocollo. Quando due computer conoscono le regole dell'HTTP possono comunicare tranquillamente.

La ragione per cui è così popolare ed ha ricevuto così tanto successo, più che altro, è perché è un protocollo molto semplice. Ogni computer riesce a parlare HTTP!

Sfortunatamente questa sua grande forza, come sempre nella vita, è anche la sua più grande debolezza. 

 

Il HTTP protocollo funziona così: tu mi chiedi una pagina web e io te la mando. Punto, basta. Non so chi sei, no so dove stai e non me ne importa niente. Basta che mi dai un Internet Protocol (IP) verso cui spedire il pacchetto e io lo riesco a far arrivare a destinazione.

 

Sfortunatamente un protocollo così semplice non ci permette una grande sofisticazione nel processo comunicativo. È un po' come vivere senza la memoria. Un po' come un pesce rosso che gira dentro al suo vaso: "Hello! Guarda qui! Che bel sasso!"

 

È in questo contesto che vengono utilizzate tecnologie come Microsoft Internet Information Server (IIS), Macromedia ColdFusion Server, Apache Server ecc.

Impiegando un po' di risorse sul server ci permettono di comunicare più intelligentemente.

In un senso, introducono la memoria nei processi di comunicazione HTTP.

 

IIS (il server) per esempio, quando riceve una richiesta da te (il cliente) per un pagina mette da parte un po' di spazio nella sua memoria e ci scrive il tuo nome, indirizzo, la pagina e un mucchio di altre cose (che vedrai nella prossime lezioni) riguardo a chi sei e cosa hai chiesto. Quando richiedi un'altra risorsa il server controlla la tua area di memoria riconoscendoti subito.

 

Come programmatore, usando Active Server Pages (ASP) sul server (IIS), io posso guardare in quest'area di memoria e, per esempio, trovare il tuo nome e stamparlo in cima alla pagina prima di mandartela. 

ASP è la tecnologia che è a nostra disposizione per manipolare le informazioni che IIS raccoglie e mantiene.

 

In conclusione possiamo dire che tecnologie come IIS e ASP espandono il protocollo HTTP con l'introduzione della continuità e ci permettono di maneggiare la conversazione fra il server e il cliente in una maniere più ricca

 

I primi passi



 

Prima che tu possa cominciare a sperimentare le tue applicazioni con questa tecnologia hai bisogno di un server e della DLL di ASP. Ci sono diversi siti che spiegano come si fa ad installare l'ambiente ASP.
Questo sito spiega come si fa ad installare il Personal Web Server per Window98 ed è uno dei migliori

http://www.soft-land.org/faq/asppws.html

A questo punto, penso sia ragionevole assumere che tu sei gia un discreto programmatore in HTML (la lingua di HTTP), altrimenti non saresti qui a volere imparare di più ;o)

Allora, cominciamo subito. 
Il seguente file, buongiorno.htm, scrive "Buongiorno a tutti" sul tuo schermo quando lo chiami dal tuo browser.

 

<html><head><title>Buongiorno</title></head>
<body>
Buongiorno a tutti
</body>
</html>



Se volessimo adoperare ASP per fare la stessa cosa, cosa dobbiamo fare? Beh, guarda qui:

 

<html><head><title>Buongiorno</title></head>
<body>
<%
response.write "Buongiorno a tutti" %>
</body>
</html>



Salva il file come buongiorno.asp e richiamalo dal browser. Come vedi i due file ottengono lo stesso risultato.

Analizziamo la sintassi di ASP:
<% e %> sono I delimitatori che ASP riconosce come propri. Tutto quello che è dentro a questi delimitatori è codice ASP.
Response è l'oggetto di ASP che risponde al client, mentre write (scrivi) è una delle cose che l'oggetto sa fare. 
Parleremo di oggetti in più approfonditamente nella prossima lezione ;o) 

Adesso modifichiamo questo programmino in modo da farne qualcosa di più interessante

 

<html><head><title>Buongiorno a tutti</title></head>
<body>
<% 
Dim cresci
For cresci=1 to 5 
    response.write "<font size=+" & cresci & ">Buongiorno a tutti</font><br>" 
Next
%>
</body>
</html>



Una volta che riesci a far funzionare lo script sul tuo browser, dai un'occhiata al codice sorgente ;o) (Visualizza -> HTML)

Questo è il codice che vedrai visualizzato:

 

<html><head><title> Buongiorno a tutti </title></head>
<body>
<font size= +1> Buongiorno a tutti </font><br>
<font size= +2> Buongiorno a tutti </font><br>
<font size= +3> Buongiorno a tutti </font><br>
<font size= +4> Buongiorno a tutti </font><br>
<font size= +5> Buongiorno a tutti </font><br>
</body>
</html>



Allora, che cosa fa esattamente questo ASP? 
ASP è un interprete. Quando chiediamo il file buongiorno.asp all'IIS, questo riconosce l'estensione .asp e invia il file al motore di ASP (asp.dll).

Il motore legge dal primo carattere all'ultimo costruendo una stringa normale in HTML e, quando trova uno dei suoi delimitatori (<%) dice "Oh, questo è il mio!" e esegue l'azione appropriata. Nel nostro caso ha trovato un semplice loop. Lo esegue e continua a costruire la stringa in HTML. Quando trova il delimitatore che chiude (%>) attacca la sua stringa a quella precedente e così continua fino alla fine del file. Quando ha finito, il motore manda la stringa in HTML a IIS che la invia al browser dell'utente (un po' semplicistico ma vero ;o).

Ne segue che ASP e HTML possono essere mescolati in ogni maniera. Finché stiamo attenti a mantenere i delimitatore, funziona sempre.
Per esempio buongiorno.asp potrebbe essere scritto così:

 

<html><head><title>Buongiorno a tutti </title></head>
<body>

<%
'dichiare la variabile
Dim cresci
For cresci=1 to 5 
%>

<font size=+<%= cresci %>>Buongiorno a tutti</font><br> 

<%
Next
%>

</body>
</html>



Come vedi, qui abbiamo inserito la variabile "cresci" nel HTML
L'unica cosa da notare è che per ottenere il suo valore, la sintassi è <%= 
Ah! un'altra cosa. I commenti in ASP usano ', non dimenticarti, sono molto importanti ;o)

 

Scaviamo un pò le fondamenta



 

Abbiamo detto prima che il Response è un oggetto. Ma cosa intendiamo per oggetto?
In termini tecnici un oggetto è "un coso" e il modello di questo "coso" e il gruppo di regole che ne determina le funzionalità. 
Non è proprio così sciocco come sembra, vediamo un semplice esempio in linguaggio umano. 

Se dovessimo descrivere una bicicletta a una persona che non ne ha mai vista una, quale credi sia la maniera migliore per descriverla? Potremmo cominciare a descrivere le cose che la bicicletta deve essere in grado di fare oppure i metodi della bicicletta. Per esempio:
Metodi: pedalare, suonare il campanello, frenare, ecc.

Se un oggetto deve diventare una bicicletta, è indispensabile che riesca a fare queste cose. Questi sono i "metodi" comuni a tutte le biciclette.

Ma non basta, ci sono anche un mucchio di biciclette diverse in giro e per descriverle tutte bisogna che definiamo anche qualche proprietà:
Proprietà: il colore, l'altezza del telaio, la misura delle ruote, ecc.

Allora. Una volta che abbiamo definito tutti i Metodi e le Proprietà dell'oggetto, il nostro nuovo amico dovrebbe essere in grado di rappresentarsi una bicicletta abbastanza reale.

Per aiutarlo ancora un po' di più c'è un'altra cosa che sarebbe molto utile definire: gli eventi o le azioni che possiamo fare con l'oggetto, per esempio:
Eventi: quando salgo, quando scendo, quando casco, ecc.

In una tecnologia come DHTML un esempio di un oggetto è una window. Metodi che possiamo adoperare sono aprire o chiudere. Proprietà di questo oggetto sono Top, Bottom, Left, Right, ecc.
Un evento è il OnClick quando il mouse ci manda un segnale. 

Lo stesso vale per l'oggetto Response che abbiamo adoperato prima. Anche questo ha Metodi e Proprietà. Adoperandoli come vogliamo siamo in grado di costruire molti Response, oggetti che, nei loro limiti, possono fare molte cose diverse.

L'oggetto Response ha i seguenti "Metodi":

AddHeader, AppendToLog, BinaryWrite, Clear, End, Flush, Redirect, Write


E queste "Proprietà":

Buffer, CacheControl, Charset, ContentType, Expires, ExpiresAbsolute, IsClientConnected, PICS, Status


E tanto per complicare le cose il Response ha anche una "Collezione":

Cookies


La sintassi come abbiamo gia visto è semplice:

Response.Clear
Response.Redirect "lab/buongiorno.asp"
Response.Buffer = True
Response.ContentType = "image/JPG"
Response.Expires = 10
strColore = Response.Cookies.Item("colore_preferito")


Ma basta per ora.
Nella prossima lezione vedremo come questi oggetti si mettono insieme per costruire delle applicazioni utili e efficienti.


 

 

Dai, facciamo qualcosa un pò più divertente ;o)




 

Al giorno d'oggi lavorare con queste tecnologie e un po' come giocare con il Lego. 
Metto 2 mattoni rossi da 2 + 2 mattoni verdi da 2, ci metto sopra un bel mattoncino blue da 6 e: "hey presto, ho fatto un ponte!".

Vediamo cosa si può fare con i pezzi di ASP, l'oggetto Response + l'oggetto Request.

Usando il metodo Write del Response siamo in grado di scrivere sullo schermo. Usando il Request siamo in grado di leggere dallo schermo.

Per riferimento vi mostro il modello dell'oggetto Request:
Proprieta : TotalBytes
Collections : ClientCertificate, Cookies, Form, QueryString, ServerVariables
Metodi : BinaryRead

Come col Lego, con questi due oggetti siamo in grado di costruire un ponte fra una pagina e l'altra.

Cominciamo col costruire una pagina che raccoglie l'input da una form e restituisce una risposta appropriata.
Chiamiamola il file chiedimi.asp

<html><head><title>Chiedimi</title></head>
<body>
<%
Response.Write "<form action='rispondimi.asp' method='post'><br>"
Response.Write "come ti chiami?"
Response.Write "<input type='text' name='nome'><br>"
Response.Write "di che citta' sei?"
Response.Write "<input type='text' name='citta'><br>"
Response.Write "<input type='submit' value='dimmelo'>" 
Response.Write "</form>"
%>
</body>
</html>


Vedi subito cosa succede qui, no? Naturalmente avremmo potuto scrivere questo senza ASP, direttamente in HTML ma volevo solo farti vedere cosa si può fare con il Response.

Adesso costruiamo una pagina per la risposta chiamiamola rispondimi.asp
Lo so che il Request lo abbiamo appena guardato ma, sono sicuro che capirai, dopo lo guarderemo più in dettaglio.

<html><head><title>Rispondimi</title></head>
<body>
<%
nome = Request.Form("nome")
citta = Request.Form("citta")
Response.write "Ciao " & nome & ",<br> Oooh, " & citta & "…, mi piacerebbe venire…<br>"
%>
</body>
</html>

Semplice no?
L'oggetto Request funziona con un gruppo di collezioni di dati. 
In questo caso l'input dalla pagina precedente è dentro alla collezione Form. Poiché noi sappiamo già i nomi dei campi li possiamo chiamare direttamente ma se non li sapessimo, potremmo trovarli così:

<html><head><title>Rispondimi</title></head>
<body>
<%
'per ogni dato nella collezione scrivi dato e valore del dato
For each dato in Request.Form
Response.Write dato & " = " & Request.Form(dato) & "<br>"
Next
%>
</body>
</html>


Questo modo ha il vantaggio di accedere il nome del controllo insieme con il valore. Per esempio se sono io che rispondo, il programma restituisce:

Nome = Giorgio
Citta = Surfers Paradise

Il ponte è fatto no? 
È facile passare valori da un pagina all'altra con ASP? 

Non è comunque l'unico modo per passare variabili da una pagina a un'altra. Dopo tutto non possiamo mettere form dappertutto e non sempre le variabili che vogliamo passare hanno a che fare con i nostri utenti. Spesso abbiamo bisogno di mandare delle flags per avvertirci su che corso prendere in dipendenza da un valore o un altro. 
Per esempio se volessimo combinare i due file chiedimi.asp e rispondimi.asp in uno solo, potremmo farlo? E se la risposta è sì, come facciamo?

Segue domanda_rispondi.asp

<html><head><title>Domanda e Rispondi</title></head>
<body>

<%
clickato = Request.Querystring("clickato")
'se cliccato ha un valore, il cliente ha cliccato il bottone della form
If clickato then
nome = Request.Form("nome")
citta = Request.Form("citta")
Response.write "Ciao " & nome & ",<br> Oooh, " & citta & "..., mi piacerebbe venire...<br>"
Else
'altrimenti è appena entrato in questa pagina 
Response.Write "<form action='domanda_rispondi.asp?clickato=true' method='post'>"
Response.Write "come ti chiami?"
Response.Write "<input type='text' name='nome'><br>"
Response.Write "di che citta' sei?"
Response.Write "<input type='text' name='citta'><br>"
Response.Write "<input type='submit' value='dimmelo'>" 
Response.Write "</form>"
end if
%>

</body>
</html>


Non c'è una grande differenza nel modo con cui abbiamo operato, ma guarda alla linea:

<form action='domanda_rispondi.asp?clickato=true' method='post'>


Qui prima di tutto rimandiamo il file in sé stesso passandogli un valore clickato=true. In questo caso il valore di clickato è contenuto nella collezione QueryString dell'oggetto Request.
Quindi lo possiamo recuperare semplicemente con:

clickato = Request.Querystring("clickato")


In questa maniera il valore è passato insieme all'URL (infatti lo vedi nell'URL nel browser):
http://localhost/domanda_rispondi.asp?clickato=true

 

Il Request oggetto continua




 

Le collezioni Form e QueryString sono certamente le due più utili dell'oggetto Request e sono quelle che adopererai di più. Ma c'è anche un'altra collezione molto utile che si può adoperare con un po' di attenzione.
Prova questo:

For each nome in Request.ServerVariables
Response.Write nome & "=" & Request.ServerVariables(nome) & "<br>"
next


I valori di tutte queste variabili sono contenute nell'header di un a richiesta HTTP e sono tutti accessibili (però stai attento poiché sono dipendenti dal browser dell'utente quindi non sono sempre tutti accessibili) .

Per esempio qui potremmo:

strFirma = Request.ServerVariables("HTTP_USER_AGENT")


Poi analizzando questa stringa potremmo trovare che tipo di browser ha fatto una richiesta alle nostre pagine. Così se è Netscape, restituiamo una pagina per Netscape se no restituiamo pagine disegnate per Internet Explorer.

<%
strFirma = Request.ServerVariables("HTTP_USER_AGENT")
If Instr(strFirma,"MSIE") then
   Response.write "<br>Hey, questo l'ha fatto Microsoft!<br>"
Elseif Instr(strFirma,"Mozilla") then
   Response.write "<br>Hey, questo l'ha fatto Netscape!<br>"
End if
%>


In caso che tu non lo sappia, la funzione Instr cerca un match nella stringa di input:

Instr(stringa1,stringa2)


Come dire "Dimmi se la stringa2 è dentro a stringa1"

Questa collezione è molto utile per esempio quando cominciamo a rendere automatico il passaggio da una pagina all'altra. Questo è un pochettino più complicato al momento, ma funziona ottimamente per trovare quale è la pagina che effettua una chiamata. Di conseguenza potremmo automatizzare il titolo o il colore o qualunque cosa vogliamo.

strDaDoveVengo = Request.Servervariables("HTTP_REFERER")
UltimoSlash = InStrRev(strDaDoveVengo,"/")
strChiama = Mid((strDaDoveVengo),(UltimoSlash + 1), len(strDaDoveVengo)- UltimoSlash)
Response.Write "Chi mi vuole? : " & strChiama & "<br>"


Ricordati che queste variabili dipendono dalla configurazione della tua macchina per cui non sempre sono disponibili.

Ecco una semplice applicazione che adopera le variabili per tracciare chi è venuto sul nostro sito, che pagina ha visto e che lingua parla. Il tutto lo scriviamo in un file ospite.txt. Studiala e se è un po' troppo complicata lascia perdere per adesso. Fra un paio di lezioni la capirai benissimo.

Prima di tutto devi creare un file vuoto di nome ospite.txt, fallo con Notepad (Blocco Note).

<%
Dim lapagina, ilcliente, lalingua
Dim filepath, logfile
Const OpenFileForAppending = 8


'raccogli le informazioni che vuoi scrivere
lapagina = Request.ServerVariables("PATH_INFO")
ilcliente = Request.ServerVariables("REMOTE_ADDR")
lalingua = Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")

'crea un FileSystem oggetto
Set fs = CreateObject("Scripting.FileSystemObject")

'trova il path del file
filePath = Server.mapPath ("ospite.txt")
'costruisci la stringa da scrivere
' chr(44) è una virgola,
' VBcrlf è un carriage return+line feed
strOspite = lapagina & chr(44) & ilcliente & chr(44) & lalingua & chr(44) & Now() & VBcrlf

'aprila per scrivere

if fs.fileExists(filepath) then
   Set LogFile = fs.OpenTextFile(filepath, OpenFileForAppending)
else
   Set LogFile = fs.CreateTextFile(filepath, false)
end if

'scrivi
logfile.WriteLine strOspite

'chiudi
logfile.Close
set logfile = nothing
set fs = nothing
response.clear
response.redirect "ospite.txt"
%>

 

L'architettura dell' ASP object model


 

Prima che continuamo a saltare troppo di palo in frasca, facciamo un passo indietro e guardiamo a come un'applicazione scritta con ASP funziona nella sua completezza.

Quando accediamo per la prima volta ad un file asp, IIS guarda nella directory root per vedere se trova un file chiamata global.asa (Active Server Application).
È questo file che ci permette di controllare due degli oggetti più importanti di ASP: l'Application e il Session.

Se ricordi, al principio di questo tutorial abbiamo parlato del fatto che il protocollo HTTP è senza memoria. L'oggetto Request ci ha aiutato un po' a mantenere la memoria ma solo da una pagina all'altra. Si potrebbe dire che l'oggetto Request è un po' la memoria corta. Beh, l'Application e il Session sono la memoria lunga. Per essere ancora più precisi, nell'universo di IIS, il Session è la memoria lunga che rimane in vita finchè rimane in vita la tua connessione, mentre l'Application è il codice genetico che rimane in vita per tutti, finchè l'universo di IIS continua. 

Come vedi, in questa metafora tu hai un potere enorme e in realtà sei tu che decidi come questo universo funziona o non funziona.

Il Global.asa ha 4 events principali. Eccone uno standard

<script LANGUAGE="VBScript" RUNAT="Server">

Sub Application_OnStart
End Sub

Sub Application_OnEnd
End Sub

Sub Session_OnStart
End Sub

Sub Session_OnEnd
End Sub

</script>


Per esempio se definiamo una variabile di scopo Application così:

<%
Sub Application_OnStart
Set application("connection_string") = "DSN=lamiadb;uid=sa;pwd="
Set Application("immagini_path") = "C:\MyWebRoot\Mywebsite\ASPtutorial\immagini\"
End Sub
%>



In qualunque delle mie pagine, posso scrivere

<%
connection_string = Application("connection_string") 
'per ottenere la mia stringa di connessione all database
immagini_path = Application(("immagini_path") 
'per ottenere il directory dove sono le mie immagini
%>


e queste variabili rimangono valide finché noi stessi uccidiamo l'applicazione o fermiamo IIS.

PROTEZIONE PAGINE WEB (modello semplificato)

Un altro esempio. Nel global.asa (inserito nella cartella da proteggere) durante Session OnStart event, definiamo:

<script LANGUAGE="VBScript" RUNAT="Server">
Sub Session_OnStart
   Session("login") = False
   Session("user") ="admin"
   Session("passwd") = "ciao"
End Sub
</script>
 

Creiamo la pagina di Login (logon.asp)

<HTML>
<BODY>
<%
if session("Login") then
   response.write "Accesso autorizzato"
else
%>
<FORM ACTION=Accesso.asp METHOD=POST>
Utente<INPUT TYPE=TEXT NAME=USER><BR>
Password<INPUT TYPE=PASSWORD NAME=PWD><BR>
<INPUT TYPE=SUBMIT VALUE="Accedi">
</FORM>
<%
end if
%>
</BODY>
</HTML>
 

La pagina di accesso.asp sottomessa avrà questo contenuto:

<HTML>
<BODY>
<%
   user=request.form("USER")
   passwd=request.form("PWD")
   if passwd=session("passwd") and user=session("user") then
      session("Login")=true
   else
      session("Login")=false
      response.redirect "logon.asp"
   end if
%>
<h1>benvenuti nell'area riservata:</h1>
</BODY>
</HTML>
 

Tutte le pagine da proteggerre avranno come parte iniziale queste istruzioni asp:

<HTML>
<BODY>
<%
if session("Login")=false then
   response.write "Accesso non autorizzato"

   response.redirect "logon.asp"
end if

%>
...

testo ed argomenti riservati ...

...

</BODY>
</HTML>


Naturalmente questo presume che tu abbia un meccanismo per permettere che il cliente effettui il login nel tuo sito e che il tuo codice cambi lo stato della variabile (Set Session ("login") = True) quando il login è avvenuto correttamente.

Nell'oggetto Session la durata delle variabili è valida fino a quando non chiudi il tuo browser, oppure, se non hai attività, IIS chiude di solito la sessione dopo 30 minuti.

Un esempio pratico che puoi applicare subito.

In alternativa usando l'attributo METHOD=GET lo stesso script diventa:

La pagina di Logon (loginGET.asp)

<HTML>
<BODY>
<%
if session("Login") then
   response.write "Accesso autorizzato"
else
%>
<FORM ACTION=AccessoGET.asp METHOD=GET>
Utente<INPUT TYPE=TEXT NAME=USER><BR>
Password<INPUT TYPE=PASSWORD NAME=PWD><BR>
<INPUT TYPE=SUBMIT VALUE="Accedi">
</FORM>
<%
end if
%>
</BODY>
</HTML>

La pagina di accesso  (AccessoGET.asp)

<HTML>
<BODY>
<%
user=request.QuerySTring("USER")
passwd=request.QuerySTring("PWD")
if passwd=session("passwd") and user=session("user") then
   session("Login")=true
else
   session("Login")=false
   response.redirect "logonGET.asp"
end if
%>
<h1>benvenuti nell'area riservata:</h1>
</BODY>
</HTML>

Il meccanismo di protezione delle vostre pagine resta invariato.
 

Per caricare una pagina predefinita quando entro in un sito uso l'oggetto Response:

Sub Session_OnStart
   Response.Redirect "C:\MyWebRoot\MyWebSite\buongiorno.asp"
end sub


Appena la Session comincia, cioè quando qualcuno entra nel sito attraverso il suo bookmark, IIS spara l'azione Session_OnStart che ti ridirige esattamente dove vuoi tu.

C'è chi dice che l'internet mette sempre più potere nelle mani dei clienti ma non certo con noi programmatori. Abbiamo sempre tutto sotto controllo ;o)

 

Vbscript e le lingue che usiamo per parlare con il browser




 

Le pagine ASP sono una combinazione di script in ActiveX e di tag HTML. IIS usa questi scripts, per darci la funzionalità nelle nostre applicazioni.
IIS ha due motori interni per interpretare questi scripts: 

· VBScript che è un subset di Visual Basic for Application (VBA) 
· Jscript un versione di JavaScript da Microsoft

Javascript, un subset del linguaggio C, è un prodotto di Netscape e di Sun Microsystem ed è interpretato dal suo motore.

Quali di queste lingue adoperare è una tua scelta e dipende naturalmente dalla familiarità che hai con questi linguaggi. In pratica però adoperiamo un po' di una e un po' dell'altra.

Per esempio, qui adoperiamo Vbscript per scrivere server side script e adoperiamo Javascript per scrivere client side script. La ragione è che Netscape non capisce VBScript e quindi tutti i nostri utenti Netscape non vedrebbero quando siamo svegli.

Siccome questo è un tutorial su ASP, non VBScript, cerchiamo di non perdere troppo tempo. Ci sono ottimi manuali per VBScript anche online. Per citarne uno, all'indirizzo riportato qui sotto trovi l'help di Microsoft che puoi scaricare e installare liberamente sul tuo computer.

http://msdn.microsoft.com/scripting
32-bit VBScript Documentation Download (VBSDOC.exe 473KB) for Windows 95 and Windows NT.

Guardiamo solo velocemente quello di cui abbiamo bisogno. Come tutte le lingue VBScript impiega delle strutture di controllo per creare la logica nelle nostre applicazioni. Ci sono due tipi principali di strutture:

· Decisioni, che definiscono su che ramo logico andare in base al risultato di un test
· Loops, che processano ciclicamente fino a che una specifica condizione non è raggiunta.

Decisioni:

<%
If (sei non sei alto più di 2 metri) then
Passa sotto
End if
%>



Questa è la decisione più comune di tutte e c'è poco da spiegare. 
"Se passi la condizione allora facciamo qualcosa" 

La struttura che segue è un allargamento della precedente
"Se passi la condizione allora facciamo qualcosa altrimenti facciamone qualche altra""

<%
If (finché il tempo è buono) then
Rimango in spiaggia
Else
Me ne vado a casa
end if
%>


La prossima struttura invece è adoperata per scegliere fra decisioni multiple:

<%
Select case colore 
Case "rosso"
Sono un comunista
Case "verde"
Sono un conservazionista
Case"blue"
Sono un sognatore
Case else
Sono un cretino ;o)
end select
%>


Questa struttura è molto efficiente e in più produce del codice che si legge bene.

Loop 
Come abbiamo detto queste sono strutture cicliche che continuano a riprodursi fino a che una condizione predeterminante è raggiunta.

Questo lo abbiamo già visto nella prima lezione

<%
For scalino=1 fino a 50
Vai su e conta
Next
%>


Logico no? Comunque, usando il For loop dobbiamo sapere quanti gradini ci sono prima di cominciare altrimenti rimaniamo a metà della scala!

La seguente struttura ci permette invece di arrivare in cima alla scala in tutte le maniere

<%
Do While (intanto che ci sono scalini) 
Vai su e conta
Loop
%>


Quando arriviamo in cima e non ci sono più scalini il Loop esce. 
Ti ricordi ospite.asp che abbiamo scritto nella lezione 5? 
Allora prova questa struttura contenuta nella pagina LeggiFile.asp:

<html><head><title>Lettura File di LOG</title></head>
<body>

<%
Dim LaPagina, IlCliente, LaLingua, LOrario
Dim FilePath, LogFile, PosizioneVirgola
Const OpenFileForReading = 1
Const OpenFileForWriting = 2
Const OpenFileForAppending = 8

'crea un FileSystem oggetto
Set fs = CreateObject("Scripting.FileSystemObject")
filePath = Server.mapPath ("ospite.txt")

if fs.fileExists(filepath) then
%>
<TABLE BORDER=1>
<TR><TH>Pagina WEB</TH><TH>Indirizzo IP</TH><TH>Lingua</TH><TH>Data e Ora</TH></TR>
<%
   Separatore=chr(44) ' chr(44) è una virgola
   Set LogFile = fs.OpenTextFile(filepath, OpenFileForReading)
   Do While NOT logfile.AtEndOfStream

      StrOspite=logfile.ReadLine 'legge una riga

      PosizioneVirgola=Instr(StrOspite,Separatore)
      LaPagina = Left(StrOspite,PosizioneVirgola-1)

      strOspite=mid(strOspite,PosizioneVirgola+len(Separatore))
      PosizioneVirgola=Instr(StrOspite,Separatore)
      IlCliente=Left(StrOspite,PosizioneVirgola-1)

      strOspite=mid(strOspite,PosizioneVirgola+len(Separatore))
      PosizioneVirgola=Instr(StrOspite,Separatore)
      LaLingua=Left(StrOspite,PosizioneVirgola-1)

      LOrario=mid(StrOspite,PosizioneVirgola+len(Separatore))
%>
  <TR><TD><%=LaPagina%></TD><TD><%=IlCliente%></TD><TD><%=LaLingua%></TD><TD><%=LOrario%></TD></TR>
<%
   Loop
   response.write "</TABLE>"+vbcrlf ' VBcrlf è un carriage return+line feed
   logfile.Close
   set logfile = nothing
   set fs = nothing
else
   response.write "<H1>Il file " & FilePath & " non esiste!</h1>"
end if
%>
</body>
</html>

Risultato: visualizza il file di log OSPITE.TXT in una pagina HTML inserendo i 4 dati (pagina visitata, IP, Lingua, Data e ora) in una tabella di 4 colonne. 
Un'alternativa + versatile alla pagina ASP precedente potrebbe essere la seguente pagina oeggifileFor.asp:

<html><head><title>Lettura File di LOG</title></head>
<body>

<%
Dim i, NrRiga, NrSeparatori, StrOspite
Dim FilePath, LogFile, PosizioneVirgola
Const OpenFileForReading = 1
Const OpenFileForWriting = 2
Const OpenFileForAppending = 8


'crea un FileSystem oggetto
Set fs = CreateObject("Scripting.FileSystemObject")

NomeFile=request.QueryString("NomeFile")
if NomeFile="" then
   response.write "<B>Sintassi Errata:</B> scrivi --&gt;<TT>leggifileFOR.asp?NomeFile='NomeFile'</TT>"
   response.end
end if
FilePath = Server.mapPath (NomeFile)

if fs.fileExists(FilePath) then
%>
<TABLE BORDER=1>
<TR><TH>Pagina WEB</TH><TH>Indirizzo IP</TH><TH>Lingua</TH><TH>Data e Ora</TH></TR>
<%  
   Separatore=chr(44) ' chr(44) è una virgola
   Set LogFile = fs.OpenTextFile(filepath, OpenFileForReading)
   NrRiga=0
   Do While NOT logfile.AtEndOfStream

      StrOspite=logfile.ReadLine 'legge una riga
      NrRiga=NrRiga+1
      NrSeparatori=(Len(StrOspite)-Len(replace(StrOspite,Separatore,"")) )/len(Separatore)
      if NrSeparatori=3 then
         StrOspite=StrOspite+Separatore
         response.write "<TR>"+vbcrlf
         For i=1 to NrSeparatori+1
            PosizioneVirgola=Instr(StrOspite,Separatore)
            Voce=Left(StrOspite,PosizioneVirgola-1)
            if (NrRiga mod 2 = 0) then colore="silver" : else colore="white"
            response.write "<TD BGCOLOR="+colore+">" + Voce +"</TD>"+vbcrlf
            StrOspite=mid(strOspite,PosizioneVirgola+len(Separatore))
         Next
         response.write "</TR>"+vbcrlf
      else
         response.clear
         response.write "<B>Tracciato non compatibile:</B> campi --&gt;<TT>Nome pagina, Indirizzo IP, Lingua, Data e ora</TT>"
         response.end
      end if

   Loop
   response.write "</TABLE>"+vbcrlf
   logfile.Close
   set logfile = nothing
   set fs = nothing
else
   response.write "<H1>Il file " & NomeFile & " non esiste!</H1>"
end if
%>
</body>
</html>

Le funzionalità aggiunte in questo script sono:
- passaggio parametrico del file da leggere e trasformare in HTML (http:/nomesito/leggifile.aspFOR.asp?NomeFile=ospite.txt)
- controllo del tracciato del file che deve essere composto da 4 colonne, ciascuna separata dalla virgola 

Come vedi questo programma legge tutto il tuo file ospite.txt. Così se domani sei in vacanza in Sardegna e vuoi vedere chi è venuto sul tuo server, facile: apri leggifile.asp e il gioco è fatto.

La funzione CreateObject può essere usata per creare istanze di una qualsiasi applicazione (che sia server di automazione ovvero composta da oggetti activeX) presente sul vostro computer. Ad esempio per visualizzare il contenuto del file di excel sample.xls possiamo utilizzare il seguente script:

<%
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = false

Set objWorkbook = objExcel.Workbooks.Open("c:\sample.xls")
r= 2
Do Until objExcel.Cells(r,1).Value = ""
   s=cstr(objExcel.Cells(r, 1).Value)+" - "
   s=s+objExcel.Cells(r, 2).Value+" "
   s=s+objExcel.Cells(r, 3).Value+" "
   s=s+"("+objExcel.Cells(r, 4).Value+")"
   response.write s & "<BR>"
   r = r + 1
Loop
objExcel.Quit
%>

 

Usare Funzioni & Procedure




 

La creazione di Funzioni e Procedure nel nostro programma è una tecnica programmatica utile per diverse ragioni. Prima di tutto rende il programma più leggibile partizionando dei blocchi di logica che compiono dei lavori definitivi e in più, poiché spesso la stessa cosa deve essere fatta in molti posti diversi, ci permette di riutilizzare del codice.

Per esempio, ti ricordi il programma che abbiamo scritto nella lezione 4, quando abbiamo combinato in un unico file l'input di una form col suo output nella presentazione? 

<html><head><title>Chiedi e Rispondi</title></head>
<body>

<%
clickato = Request.Querystring("clickato")
If clickato=1 then
   nome = Request.Form("nome")
   citta = Request.Form("citta")
   Response.write "Ciao " & nome & ",<br> Oooh, " & citta & "…, mi piacerebbe venire…<br>"
Else
   Response.Write "<form action=chiedi_rispondi.asp?clickato=1 method=post>"
   Response.Write "Nome: <input type=text name=nome><BR> "
   Response.Write "Citta: <input type=text name=citta><BR>"
   Response.Write "<input type=submit value='dimmelo'> "
   Response.Write "</form>"
end if
%>

</body>
</html>


Questo programma, essendo così corto, è certamente leggibile; ma se le righe invece di essere poche fossero diverse centinaia? Con una form molto lunga e con una presentazione complessa basata su un numero di parametri passati da pagine precedenti? Tipo una situazione di e-commerce dove raccogliamo dati di carte di credito?

Guarda un po' com'è bello usando procedure:

<%
Option Explicit
Dim clickato, form
Dim nome, citta
Dim saluti
'--------------------------------------------------------
'Purpose:Dimostra gli oggetti Response e Request
'Date: 10 March 2001
'Commenti: 
'--------------------------------------------------------
call Main()

Sub Main()
'--------------------------------------------------------
'Purpose:contiene l'intera logica dell' applicazione
'Date: 10 March 2001
'Commenti: 
'--------------------------------------------------------
FaiLaTesta() 

clickato = Request.QueryString("clickato")

If NOT clickato then

MostraLaForma()

Else

LeggiLaForma(form)

DaiLaRisposta()

End if

FaiLaCoda()

End Sub

Sub FaiLaTesta()
'--------------------------------------------------------
'Purpose:Scrive HTML header
'Date: 10 March 2001
'Commenti: 
'--------------------------------------------------------
Response.write "<html><head><title>Chiedi e Rispondi</title></head><body>"
End Sub

Sub MostraLaForma()
'--------------------------------------------------------
'Purpose:mostra la form al cliente
'Date: 10 March 2001
'Commenti: 
'-------------------------------------------------------- 
Response.Write "<form action='showproc.asp?clickato=truè method='post'><br>"
Response.Write "come ti chiami?"
Response.Write "<input type='text' name='nomè><br>"
Response.Write "di che citta' sei?"
Response.Write "<input type='text' name='citta'><br>"
Response.Write "<input type='submit' value='dimmelo'>" 
Response.Write "</form>"

End Sub

Sub LeggiLaForma(form)
'--------------------------------------------------------
'Purpose: Legge i dati e mantiene le variabili
'Date: 10 March 2001
'Commenti: 
'--------------------------------------------------------
nome = Request.Form("nome")
citta = Request.Form("citta")

End Sub

Sub DaiLaRisposta()
'--------------------------------------------------------
'Purpose: Produce output
'Date: 10 March 2001
'Commenti: 
'--------------------------------------------------------
Response.write "Ciao " & nome & ",<br> Oooh, " & citta & "…, mi piacerebbe venire…<br>"
End Sub

Sub FaiLaCoda()
'--------------------------------------------------------
'Purpose:scrive HTML Footer
'Date: 10 March 2001
'Commenti: 
'--------------------------------------------------------
Response.write "</body></html>"
End Sub
%>


Certo che a vederlo in questo contesto sembra un po' strafatto ma immagina che la prossima volta che dobbiamo costruire un file simile ne abbiamo già una metà già scritta. Comunque svilupperemo l'argomento durante il corso di queste lezioni e vedrai che questo metodo è molto utile. Nel programma precedente non ci sono Funzioni ma solo Procedure. Così mettiamone una e vediamo qual è la differenza.

<%
Function ParteDelGiorno()
'--------------------------------------------------------
'Purpose: calcola la parte del giorno per salutare 
'Date: 10 March 2001
'Commenti: 
'--------------------------------------------------------
Dim cheora

cheora = Hour(Now)

Select case cheora
case 8,9,10,11,12
cheora = "Buongiorno"
case 13,14,15,16,17
cheora = "Buon pomeriggio"
case 18,19,20,21,22,23,24
cheora = "Buonanotte" 
case else
cheora = "Spegni il computer e vai a letto"
End Select

ParteDelGiorno = cheora

End Function
%>


Come vedi questa Funzione è certamente riutilizzabile anche se un po' semplice (ma bisogna pur cominciare da qualche parte o no? ;o).

Aggiungi queste due linee nel codice fra:

<%
If NOT clickato then

saluti = ParteDelGiorno()
Response.Write saluti

MostraLaForma()
%>


Come vedi, poiché la funzione ci restituisce un valore, bisogna dargli una variabile per raccogliere l'informazione. Oppure volendo avremmo potuto scriverla direttamene con:

<% Response.write ParteDelGiorno() %>


Allora, in sostanza, abbiamo messo un po' di ordine nel nostro programma. 
Anche se ti sembra un po' troppa strutturato per quello che fa, so di sicuro che mi ringrazierai se per caso ritorni a questo programma fra qualche mese ;o)

E adesso la vera ragione per cui adoperiamo tecnologie come ASP




 

Fino ad ora tutta l'enfasi nello sviluppo dei siti web è stata "messa in vetrina". Abbiamo fatto delle vetrine stupende che sono costate una fortuna, ma dentro al negozio? Molto poco. Spesso un cliente ha l'impressione che non ci sia nessunno e spesso il cliente ha ragione! Come facciamo a rimediare?

In questo caso tecnologie come ASP ci aiutano proprio. Per esempio tutti sanno che un sito deve avere un mezzo con cui il cliente può comunicare con noi. La maniera più semplice è un "mailto:" collegato al tuo email. 

Sfortunatamente questo metodo fallisce molto spesso poiché presuppone che il programma di posta elettronica dell'utente sia configurato correttamente e spesso non lo è.

Il secondo metodo è una form mantenuta dall'ISP presso cui risiede il nostro sito. Gli Script dietro a questa form di solito mandano un e-mail al cliente. Il metodo migliore però è costruire la tua form da solo e controllare le informazioni che vuoi sapere dai tuoi clienti e la risposta che gli vuoi dare. 

A questo punto, cominciamo a costruire un'applicazione che ci servirà quando avremo finito le nostre lezioni: costruiamo una Form che ci permette di raccogliere informazioni dai nostri clienti, restituendo loro un messaggio di ringraziamento e mandando a noi una email. Il primo pezzo lo sai già fare da solo.

Cominciamo a fare un file chiamato feedback.asp e vediamo dove ci porta.

<HTML>
<HEAD>
<TITLE>Feedback Form</TITLE>
</head>
</HEAD>

<BODY>
<FORM ACTION="manda_feedback.asp" METHOD="post">
<div align="center">
<table border="0" width="85%" celpadding="2" cellspacing="2">
<tr>
<td>
<h1>Grazie per....<hr align="LEFT" size="1" width="100%" color="navy"></h1>
</td>
</tr>
<tr>
<td>Se avete....</td>
</tr>
<td align="center"><br><br>
<table width="60%" border="0" celpadding="2" cellspacing="2">
<tr>
<td>Nome</td>
<td><INPUT NAME="nome" TYPE="TEXT" size=24 MAXLENGTH=50></td>
</tr>
<tr>
<td>email</td>
<td valign="top">
<INPUT NAME="email" TYPE="TEXT" ALIGN=left size=24 MAXLENGTH=50>
</td>
</tr>
<tr>
<tr>
<td valign="top">Commenti</td>
<td><TEXTAREA NAME="commenti" ROWS=7 COLS=40></TEXTAREA></td>
</tr>
<tr>
<td valign="top"><b>&nbsp;</b></td>
<td>
<table width="100%" border="0" celpadding="2" cellspacing="2">
<tr>
<td>
<INPUT TYPE=checkbox NAME="notifyme" VALUE="yes" UNCHECKED>
</td>
<td>Vi interessa ricevere....</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<table width="50%" border="0" celpadding="6" cellspacing="2">
<tr> 
<td><INPUT TYPE="submit" NAME="parla" VALUE="parla con noi"></td>
<td align="right">
<INPUT TYPE="reset" NAME="nograzie" VALUE="no grazie">
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</FORM>

</BODY>
</HTML>


Feedback.asp ha 2 text boxes, 1 textarea per i commenti e un checkbox nel caso i nostri clienti vogliano ricevere una newsletter regolarmente o pubblicità o qualcosa che ce li leghi a noi un po'. In inglese si chiama stickyness (come il miele, appiccicoso)

La form chiama in azione manda_feedback.asp con il metodo Post. Questo file raccoglie l'input del cliente e lo invia a noi per email. In più presenta al cliente una pagina ringraziando per i suoi commenti.

Volendo, se sei avventuroso, potresti adoperare lo stesso metodo di prima e costruire l'applicazione nello stesso file. Come vuoi tu, ormai sei già un esperto ;o)

Allora costruiamo questa manda_feedback.asp.
Per mandare una email dobbiamo adoperare il NewMail oggetto dalla CDONTS library di Micorsoft.

Il modo in cui adoperiamo questo oggetto è simile agli altri e molto semplice.

<%
Option Explicit
'--------------------------------------------------------
'Purpose: processes the feedback mail
'Date: 10 March 2001
'Commenti: 
'--------------------------------------------------------
Dim form, nome

%>
<Html>
<head>
<title>Manda Feedback</title>
</head>
<body>
<%

call Main()

Sub Main()
'--------------------------------------------------------
'Purpose: la logica dell'applicazione
'Date: 10 March 2001
'Commenti: 
'--------------------------------------------------------
'se la lungezza è 0 non c'e niente nell email
If Len(Request.Form("email")) = 0 then
no_email()
else 
manda_posta(form)
ecco_fatto(nome)
end if
End sub


Sub no_email()
'--------------------------------------------------------
'Purpose: manda un messaggio se email è vuoto
'Date: 10 March 2001
'Commenti: potevamo usare javascript per forzare il cliente
'ma questi sono esempi di ASP
'--------------------------------------------------------
'allora diciamo al cliente che senza una email non possiamo rispondergli
response.write "<div align='center'>"
response.write "<table border='0' width='80%' cellspadding='4' cellspacing='4'>" 
response.write "<tr><td>niente email...?</td></tr>"
response.write "<tr><td>per favore, torna indiedro e... </td></tr>"
response.write "<tr><td align='middlè>"
response.write "<a href='Javascript:history.go(-1)'>Prova di nuovo</a>"
response.write "</td></tr></table></div>"
End Sub

Sub manda_posta(form)
'--------------------------------------------------------
'Purpose: manda la email
'Date: 10 March 2001
'Commenti: 
'-------------------------------------------------------- 
Dim email, commenti
Dim objMail, mandamiquesto

'facciamo la vendemmia dell'input
nome = Request.Form("nome")
email = Request.Form("email")
commenti = Request.Form("commenti")

mandamiquesto = nome & "VBcrlf" & email & "Vbcrlf" & commenti 
'costruiamo un NewMail oggetto
Set objMail = Server.CreateObject("CDONTS.NewMail")
'adesso che abbiamo accesso a tuttle le sue proprieta, usiamole
'prendiamo il nome dal Form di input
objMail.From = nome
'mandiamola a me, va…
objMail.To = "giorgiogobbo@hotmail.com"
'mettiamoci un riga per il titolo
objMail.Subject = "Feedback dal sito"
'e nel corpo ci mettiamo la stringa che abbiamo costruito
objMail.Body = mandamiquesto
'al momento è poco importante, direi
objMail.importance = 0
'e via che va
objMail.Send

'e adesso puliamo prima di andarcene
Set objMail = Nothing
end sub

Sub ecco_fatto(nome)
'--------------------------------------------------------
'Purpose: manda un ringraziamento
'Date: 10 March 2001
'Commenti: 
'-------------------------------------------------------- 
response.write "<div align='center'>"
response.write "<table border='0' width='80%' cellspadding='4' cellspacing='4'>" 
response.write "<tr><td>Grazie " & nome & " per il...</td></tr>"
response.write "<tr><td align='middlè>"
response.write "<a href='Javascript:history.go(-2)'>Continua</a>"
response.write "</td></tr></table></div>"
End sub

%>

</body>
</html>



Ed ecco qui che abbiamo la nostra form funzionante. L'oggetto NewMail è abbastanza semplice no?

Se volessimo delle copie carbone il NewMail ci permetterebbe di specificare anche: 

<%
ObjMail.CC
ObjMail.BCC
%>


O potremmo formattare la email in HTML con la proprietà:

<% ObjMail.BodyFormat = CdoBodyFormatHTML %>


Ma adopereremo questo oggetto di nuovo nelle prossime lezioni e impareremo di più.

Database access with ADO




 

Se il nostro sito diventa popolare dovremmo ricevere un mucchio di email e presto ci accorgeremo che programmi come Outlook o Eudora non sono adeguati a conservare questo dati. Ma grazie a Dio, ci sono le banche dati. In un sito moderno, le banche dati sono come il cuore in un essere umano: indispensabili. Costruiamone una subito. 

Io ne ho fatta una in Microsoft Access. L'ho chiamata CRM.mdb poiché vogliamo costruire un sistema di Customer Relationship Management (CRM, gestore dei rapporti con i clienti) che ci permetta di comunicare con i nostri clienti in una maniera più efficiente. Dentro crm.mdb ho messo una tabella chiamata:

tbl_feedback

Nome campo

Tipo campo

Id Autonumber

primary key

Nome

Text

Email

Text

Commenti

Memo


E poi ho inserito un paio di records in modo da fare un test dell'intera procedura.

A questo punto lasciami chiarire la scelta di Access come database. Io di solito uso MS SQL ma ho pensato che Access sia un pò più accessibile come costo. Però il tipo di database che adoperi per questi esercizi non è molto rilevante. Il code che scriveremo funziona per quasi tutte le banche dati commerciabili, quindi scegli quella con cui sei più comodo.

Prima che andiamo troppo avanti però, devo dirti che Access non è una soluzione industriale, non è il tipo di applicazione che vorrei adoperare su un web server per un sito commerciale.

Allora cominciamo a fare cose serie. Fino a poco tempo fa, costruire un sito dinamico con un database era un lavoro solo per i "big boys" ma adesso con oggetti (o meglio super oggetti) come ActiveX Database Object (ADO) è diventato un gioco da ragazzi.

ADO è come un superset di un oggetto. È una collezione di oggetti che, tutte insieme, semplificano il lavoro di collegare e manipolare i dati che risiedono dentro il database. In più ADO è inserito dentro un'altra tecnologia di Microsoft, Object Linking & Embedding DataBase (OLE DB), il che rende le cose ancora più facili.

La prima cosa da fare per lavorare con un database è di creare una connection. Se vuoi dare acqua al giardino devi attaccare il tubo al rubinetto, è uguale.

Il metodo che adoperiamo per collegarci è sempre lo stesso indipendentemente dal tipo di database che utilizziamo, la sintassi però varia. Ci sono diverse maniere per collegarsi ma qui, per semplicità adoperiamo la Connection String.

Per esempio per collegarci con il nostro database dobbiamo inserire il seguente codice:

<%
Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:/dovehaimessoiltuo/crm.mdb
%>


Un consiglio gratuito: non salvare mai il database nella stessa directory dei tuoi file ASP. Mettilo sempre fuori dal tuo Web Root, in modo da renderla inaccessibile agli utenti.

Lo stesso code per MS SQL per esempio è

<%
Provider = SQLOLEDB; Data Source = ilnomedeltuoserver; Initial Catalog= nomedeldatabase; User Id=ilnome; Password=lapassword
%>


Comunque una volta che abbiamo inserito uno di questi due comandi per la nostra pagina ASP siamo collegati al database.

Non ci credi? Beh, prova un po' questo codice (chiama il file elencaStudenti.asp)

<html><head><title>Elenco studenti</title></head>
<body>
<%
Const VbDataLunga=1
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = E:/noBackup/DbEsempio.mdb")

set objRs = objConn.Execute("SELECT * from Studenti ORDER BY IDStudente DESC")

if NOT objRS.eof then
   objRs.MoveFirst
   Do while NOT objRs.EOF
      response.write "IdStudente = " & objRs("IdStudente") & "<br>"
      response.write "Nominativo = " & objRs("Nominativo") & "<br>"
      response.write "Nato il = " & FormatDateTime(objRs("NatoIl"),VbDataLunga) & "<br>"
      response.write "<hr size='1' color='midnightbluè width='40%' align='left'>"
      objRs.Movenext
   Loop
else
   response.write "<H1>Nessuno studente!</H1>"
end if

objRs.Close
Set objRs = Nothing
objConn.Close
Set objConn = Nothing
%>
</body>
</html>
 


Se non ha funzionato, leggi i messaggi che il Browser ti dà sulla pagina. Io qui uso IE5.5 e se per esempio metto l'indirizzo del database sbagliato mi dice: 

Error Type:
Microsoft JET Database Engine (0x80004005)
'C:\asptutorial\tut\crm.mdb' is not a valid path. Make sure that the path name is spelled correctly and that you are connected to the server on which the file resides.
/tut/check_connection.asp, line 4

Svelto, guardo subito alla linea 4 e vedo subito dove è il problema.

Se a questi punto il database non funziona non puoi continuare con le lezioni. Quindi concentrati e lavora. Quando sei riuscito a vedere il contenuto del tuo database, prosegui con la lezione 11 e vediamo un po' che cosa è che abbiamo fatto in realtà.

Per inserire un nuovo studente posso usare una pagina come questa che verra utilizzata scrivendo sulla barra dell'indirizzo un qualcosa del tipo:
http://nomesito/inseriscistudente.asp?Nome=Rossi Mario&NatoIl=27/01/2004#

<html><head><title>Nuovo Studente</title></head>
<body>
<%
Nome=request.QueryString("Nome")
NatoIl=request.QueryString("NatoIl")
If Nome="" or not isdate(NatoIl) then
   response.write "<B>Parametri non inseriti:</B> digita ad esempio --&gt;<TT>inserisci.asp?Nome=RossiMario&NatoIl=27/01/2004#</TT>"
else
   Set objConn = Server.CreateObject("ADODB.Connection")
   objConn.Open("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = E:/noBackup/DbEsempio.mdb")
   Giorno=Cstr(Month(CDate(NatoIl))) & "/" & Cstr(Day(CDate(NatoIl))) & "/" & Cstr(Year(CDate(NatoIl)))
   strsql = "INSERT INTO Studenti ( Nominativo, NatoIl ) Values('" & Nome & "',#" & Giorno & "#);"
   objConn.Execute strsql
   objConn.Close
   Set objConn = Nothing
end if
%>
</body>
</html>

 

Facciamo la conoscenza con il Connection e il Recorset




 

Congratulazioni ;o)
Adesso che hai passato questo ostacolo, non ce ne sono più. Di qui in poi, è tutta discesa. A dir la verità, è proprio incredibile come si fa presto al giorno d'oggi. Fino a poco tempo fa ci sarebbero volute delle settimane per fare una cosa simile. La metafora del Lego sta diventando più e più realtà.

Allora cos'è che abbiamo fatto esattamente? Cosa significa il codice che abbiamo usato?

Cominciamo dal principio:

Abbiamo già visto prima come si costruisce un oggetto con NewMail. Qui faremo lo stesso. Costruiamo un oggetto Connection che appartiene ad ADO e lo chiamiamo objConn.

Set objConn = Server.CreateObject("ADODB.Connection")


Poi usando il metodo Open del Connection Object ci colleghiamo al database:

objConn.Open("Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:/asptutorial/crm.mdb")


Adesso abbiano bisogno di un oggetto Recordset (anche questo di ADO) per metterci dentro tutti i nostri dati che vengono fuori quando interroghiamo il database.

Set objRs = Server.CreateObject("ADODB.Recordset")


E poi con il metodo Execute dell'oggetto Connection eseguiamo una query al database e depositiamo il risultato nel recordset che abbiamo costruito.

set objRs = objConn.Execute("SELECT * from tbl_feedback")


Ciò che faremo di qui in poi l'abbiamo già visto. Questo While Loop semplicement dice "fai finché non siamo arrivati alla fine del file" (EOF = End Of File) 

Do While NOT objRs.EOF


Scrivimi il nome, email e commenti del primo record:

response.write "nome = " & objRs("nome") & "<br>"
response.write "email = " & objRs("email") & "<br>"
response.write "commenti = " & objRs("commenti") & "<br>"
response.write "<hr size='1' color='midnightbluè width='40%' align='left'>"


e quando l'hai fatto spostati al prossimo record

objRs.Movenext


e rifallo

Loop


Poi si pulisce. 

<%
objRs.Close
Set objRs = Nothing
objConn.Close
Set objConn = Nothing
%>


Tutto qui. 

Naturalmente questa non è l'unica maniera di scrittura del codice e forse neanche la più efficiente, comunque avrai poi tempo di sperimentare per conto tuo. Questo metodo è semplice e valido.

Bisogna sottolineare che è molto importante chiudere il recordset e la connection. Vedremo i motivi un po' più avanti.

La regola più importante per accedere ad una database è uguale a quella nell'affrontare una rotonda stradale: entra più svelto che puoi ed esci appena possibile. Quindi la connection deve essere chiusa al più presto possibile in modo da far posto a un'altra macchina. È più che sicuro che nella nostra applicazione queste righe di code saranno ripetute molte volte anche spesso nella stessa pagina. Anche se fai 100 chiamate nella stessa pagina mai lasciare aperta la connection, chiudila sempre e crearne un'altra quando ne hai bisogno. Altrimenti se continui a girare intorno e intorno gli altri faranno fatica ad entrare.

Allora, vediamo se possiamo semplificare un po' il codice che abbiamo scritto per evitare di scrivere sempre tutto. 

Per esempio la string che usiamo per collegarci al database, poiché è sempre la stessa, non potremmo metterla nel global.asa? Ricordi? Se la mettiamo in quel file ce l'abbiamo sempre e se spostiamo il database da un'altra parte o se ne facciamo un'altra dobbiamo solo cambiare quella linea e tutto il resto funziona.

<%
Sub Application_OnStart()
strDbConn = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:/asptutorial/crm.mdb"
Set Application("dbconn") = strDbConn
End Sub
%>


Cosi che nelle nostre pagine ci colleghiamo così:

<% objConn.Open Application("dbconn") %>


O ancora meglio, potremmo scriver una procedura

<%
Sub Prendi_Recordset(objConn, objRs, strConn, strsql)
'--------------------------------------------------------
'Purpose: riceve un recordset dalla mia database
'Date: 28 March 2001
'Commenti: 
'--------------------------------------------------------
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRS = objConn.Execute (strsql)
End Sub
%>


Tutte le volte che devi accedere al database basta una riga sola

<%
call Prendi_recordset(objConn, objRS, strConn, strsql)
dove naturalmente strConn e strsql sono:
strsql ="SELECT * from tbl_feedback"
strConn = Application("dbconn")
%>


e così finiamo questo programma per bene. (Segue check_connection.asp)

<%
Option Explicit
'--------------------------------------------------------
'Purpose: controlla se la nostro database funzione
'Date: 28 March 2001
'Commenti:
'--------------------------------------------------------
Dim objConn, objRs

call Main()

Sub Main()
'--------------------------------------------------------
'Purpose: logica dell'applicazione
'Date: 28 March 2001
'Commenti:
'--------------------------------------------------------
Dim strConn, strsql
strConn = Application("dbconn")
strsql ="SELECT * from tbl_feedback"

call Prendi_Recordset(strConn, strsql)
call Guarda_Recordset(objRs)

'pulisci e chiudi
objRs.Close
Set objRs = Nothing
objConn.close
Set objConn = Nothing
End sub

Sub Guarda_Recordset(objRs)
'--------------------------------------------------------
'Purpose: mostra un recordset dalla mia database
'Date: 28 March 2001
'Commenti:
'--------------------------------------------------------
Do while NOT objRs.EOF
response.write "nome = " & objRs("nome") & "<br>"
response.write "email = " & objRs("email") & "<br>"
response.write "commenti = " & objRs("commenti") & "<br>"
response.write "<hr size='1' color='midnightbluè width='40%' align='left'>"
objRs.Movenext
Loop
End sub

Function Prendi_Recordset(strConn, strsql)
'--------------------------------------------------------
'Purpose: riceve un recordset da un query
'Date: 28 March 2001
'Commenti: 
'--------------------------------------------------------
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRs = objConn.Execute (strsql)
End Function
%>

 

Conoscenza col Connection e Recordset non basta




 

Nella lezione precedente siamo riusciti a estrarre un recordset dal nostro database. Bene, da qualche parte si deve pur cominciare. Se non l'avevi mai fatto sono sicuro che sei molto contento con te stesso ;o)

L'oggetto Recordset però è un po' più complicato di quello che abbiamo fatto fino adesso. Se ci hai fatto caso, nel programma check_connection.asp abbiamo dovuto mantenere la Connection con il database aperta finché non abbiamo finito col recordset. La ragione è che il metodo che abbiamo adoperato, essendo il più semplice, ci ha dato un Connected Recordset. C'è un'altra maniera, e più efficiente di estrarre un recordset che ci permette di chiudere la connection non appena i dati sono arrivati. Questo è il Disconnected Recordset.

Modifichiamo il nostro Prendi_Recordset così che possiamo chiudere la connection subito. Prima però abbiamo bisogno di includere un file che contiene i valori delle costanti di ADO. Il file si chiama adovbs.inc e si include nella pagina con questa sintassi:

<!--#include virtual="yourwebroot/dovelatrovo/adovbs.inc"-->


Lo so che non abbiamo parlato di Includes e forse è meglio se ne parliamo subito. 

Gli Includes sono un po' come le Funtions e le Procedures e si adoperano per incapsulare del codice in modo da poterlo riutilizzare in molte pagine. Il motore di ASP, quando vede una direttiva "include", cerca il file e inserisce il codice che trova in quel punto del file. Personalmente io adopero poco i file include perché rendono il codice più difficile da leggere e possono creare problemi se la struttura del directory del sito cambia. Di regola si fa una folder chiamata include e tutte le include si chiamano di li. Per convenzione sono chiamati con estensione .inc ma le puoi chiamare anche con .asp. Come tutto il resto possono contenere ASP, HTML o una mescolanza di tutto. 

Con un po' di giudizio sono molto utili e anche noi li adopereremo presto. Il più grande vantaggio è che se mettiamo un file include che, per esempio, contiene un numero di funzioni utili al principio di tutte le nostre pagine, quando cambiamo l'include non dobbiamo cambiare nessuna delle nostre pagine.

Ma riprendiamo con la nostra funzione che ci dà indietro un recordset disconnesso.

<%
Function Prendi_Recordset(strConn, strsql)
'--------------------------------------------------------
'Purpose: ritorna un disconnetted recordset
'Date: 28 March 2001
'Commenti: 
'--------------------------------------------------------
Dim objConn, objRS

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRS = Server.CreateObject("ADODB.Recordset")

objRS.CursorLocation = adUseClient
objRS.Open strsql, objConn, adOpenForwardOnly, adLockBatchOptimistic

Set objRS.ActiveConnection = Nothing
objConn.Close
Set objConn = Nothing

Prendi_RecordSet = objRS

End Function
%>


Ne segue che dalla nostra pagina la chiamiamo con:

<% Set objRS = Prendi_RecordSet(strConn, strsql) %>


La ragione per cui è preferibile chiudere le connessioni al database al più presto è che le connessioni richiedono al server risorse considerevoli. In più se non le chiudiamo esplicitamente rimangono aperte, con il risultato che le performance del Server deteriorano drasticamente. Non vogliamo, insomma, fare aspettare i nostri utenti più di quello che devono.

Spesso però dobbiamo fare delle query al database che non richiedono che il codice ci ritorni un recordset. Per esempio se volessimo inserire un nuovo record nella nostro database o se ne volessimo cambiare uno già in esistenza.
In questi casi è sufficiente collegarci e eseguire la query, così:

<%
dbConn = Application("dbconn")

strsql = "INSERT INTO tbl_feedback ( nome, email, commenti, ricevuto ) Values('amerigo vespucci','amerigo@nave.net','hello therè,Now());"

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open dbConn
objConn.Execute strsql
%>


Quando questi programmi non funzionanao subito come vorresti, usa il response.write per vedere cosa è che non va. Per esempio con:

<% Response.write strsql %>


Potresti vedere il code sql della tua query. Se lo tagliamo e lo incolliamo nella query window di Access vedi subito se funziona o no. Lo puoi mettere a posto da lì e quando ha funzionato in Access lo puoi incollare di nuovo nel tuo programma.

Anche in questi case sarebbe meglio fare una Function così che la possiamo usare dappertutto e in una maniera uniforme. 

<%
Sub fai_query(strConn, strsql)
'--------------------------------------------------------
'Purpose: fa una query con una string valida di SQL
'Date: 29 March 2001
'Commenti: 
'--------------------------------------------------------
Dim objConn

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn

objConn.Execute strSQL

objConn.Close
set objConn = Nothing

End Sub
%>


Quando la chiamiamo dal nostro programma, questo basta

Call fai_query( strConn, strsql)


A questo punto abbiamo un bell'esempio per l'uso di una include file. Se mettiamo queste Procedure e funzioni che abbiamo scritto per connetterci al database in un file unico e chiamandolo attrezzi_db.inc, possiamo adoperarle dappertutto nelle nostre pagine.

<!--#file virtual=lamiaWebRoot/include/attrezzi_db.inc -->


Il nostro programma diventa molto più facile da leggere, ci risparmiamo un mucchio di linee di codice e siamo sicuri che chiudiamo le Connections.

Non ho ancora finito. Lezione pratica.




 

Adesso che sai recuperare un record dal database e metterne dentro uno nuovo non ci rimane un gran che da fare. Per fare qualcosa di utile cerchiamo allora di costruire un'applicazione che ci permetta di inserire delle informazioni nel database attraverso una form e di mostrarle quando visualizziamo una pagina. Per esempio: se volessimo mostrare notizie di attualità sul nostro sito e cambiarle ogni giorno, non sarebbe meglio automatizzare il lavoro invece di scrivere HTML in continuazione? Io penso di sì!

Allora scriviamo il pseudocodice che descrive l'applicazione:

Input
Se la form è vuota 
Mostrala 
Se no
Entra I dati nel database

Output
Prendi il recordset dal database
Formattalo e mostralo all'utente

Subito costruiamo un'altra tabella per questa applicazione dove mettiamo i seguenti campi:

tbl_news

Nome campo

Tipo campo

Id

primary key

Titolo

Text

Sottotitolo

Memo

Testo

Memo

Data_vivo

date/time

Data_morto

date/time


Hai fatto? Via! La form la fai con gli occhi chiusi. Io, qui sotto, modifico quella che abbiamo già fatto per il feedback, è quasi uguale. Salva questa form e chiamala news.inc Io uso i file include (.inc) di rado, ma ora voglio farti vedere un po' tutte le maniere in cui si può lavorare.

<-- NEWS.INC-->
<-- input form per le news applicazione-->
<HTML>
<HEAD>
<TITLE>News Input</TITLE>
</head>
</HEAD>

<BODY>
'usiamo questa flag per controllare se la form è stata mandata
<FORM ACTION="news.asp?submitted=true" METHOD="post">
<div align="center">
<table border="0" width="95%" celpadding="2" cellspacing="2">
<tr>
<td><h1>Entra le news per oggi qui...
<hr align="LEFT" size="1" width="100%" color="navy"></h1>
</td>
</tr>
<td align="center"><br><br>
<table width="80%" border="0" celpadding="2" cellspacing="2">
<tr>
<td>Titolo</td>
<td><INPUT NAME="titolo" TYPE="TEXT" size="80" MAXLENGTH="80"></td>
</tr>
<tr>
<td>Sottotitolo</td>
<td valign="top">
<TEXTAREA NAME="sottotitolo" ROWS="3" COLS="60"></TEXTAREA>
</td>
</tr>
<tr>
<tr>
<td valign="top">News</td>
<td><TEXTAREA NAME="news" ROWS="10" COLS="60"></TEXTAREA></td>
</tr>
<tr>
<td nowrap>Data di entrata</td>
<td valign="top">
<INPUT NAME="vivo" TYPE="TEXT" Value="<%= Now() %>" size="24" MAXLENGTH="24">
</td>
</tr>
<tr>
<td nowrap>Data di scadenza</td>
<td valign="top">
<INPUT NAME="morto" TYPE="TEXT" size="24" MAXLENGTH="24">
</td>
</tr> 
<tr>
<td valign="top"><b>&nbsp;</b></td>
<td>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<table width="40%" border="0" celpadding="6" cellspacing="2">
<tr> 
<td align="right">
<INPUT TYPE="submit" NAME="submit" VALUE="Entra">
</td>
<td align="left">
<INPUT TYPE="reset" NAME="Reset" VALUE="Reset">
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</FORM>

</BODY>
</HTML>


L'unica cosa che ancora non hai visto qui è la maniera in cui inseriamo il valore dalla data di oggi. Mi sembra che ne abbiamo parlato nella prima lezione. Inutile farlo a mano, no?

<tr>
<td nowrap>Data di entrata</td>
<td valign="top">
<INPUT NAME="vivo" TYPE="TEXT" Value="<%= Now() %>" size="24" MAXLENGTH="24">
</td>
</tr>


Le date sono sempre un po' problematiche con le banche dati e nel maneggiarle di sicuro ti verrà qualche capello bianco. Infatti paesi diversi adoperano formati diversi. Per esempio negli USA la data è sempre riportata come mese/giorno/anno, mentre in Europa è giorno/mese/anno. A dirti la verità io odio le date ma, hey! Non si può farne a meno.

Adesso mettiamoci intorno il resto del programma adoperando quella library che abbiamo già fatto attrezzi_db.asp. Includendola abbiamo accesso alle nostre funzioni.

<%
Option Explicit
'--------------------------------------------------------
'Purpose: applicazione per le news
'Date: 30 March 2001
'Commenti: 
'--------------------------------------------------------
%>
<!-- la mia è nella stessa folder --> 
<!-- #include file="attrezzi_db.asp" -->
<%
Dim strConn, message
Dim titolo, sottotitolo, testo, vivo, morto

call Main()

Sub Main()
'--------------------------------------------------------
'Purpose: la logica dell'applicazione
'Date: 29 March 2001
'Commenti: 
'--------------------------------------------------------
Dim submitted, query, form
submitted = Request.QueryString("submitted")
If submitted then
call vendemmia(form)
query = costruisci_query(titolo,sottotitolo,testo,vivo,morto)
strConn = Application("dbconn") 
'questa è in attrezzi_db.inc, ti ricordi? quindi ce l'abbiamo
call fai_query(strConn, query)
call quale_risultato(message)
else 
%> 
<!-- mettiamo la form qui -->
<!-- #include file="news.inc"--> 
<% 
end if
end Sub

Sub vendemmia(form)
'--------------------------------------------------------
'Purpose: raccogli i dati dalla form
'Date: 29 March 2001
'Commenti: corregge il problema di &quot;
'--------------------------------------------------------
'questo Replace lo facciamo per il carattere "&quot;"
'altrimenti la Database si confonde
titolo = Replace(Request.Form("titolo"),"'","''")
sottotitolo = Replace(Request.Form("sottotitolo"),"'","''")
testo = Replace(Request.Form("news"),"'","''")
vivo = Request.Form("vivo")
morto = Request.Form("morto") 
end sub

Function costruisci_query(titolo,sottotitolo,news,vivo,morto)
'--------------------------------------------------------
'Purpose: costruisce la query
'Date: 29 March 2001
'Commenti: 
'--------------------------------------------------------
Dim strsql
strsql = "INSERT INTO tbl_news ( titolo, sottotitolo, testo, data_vivo, data_morto)" 
strsql = strsql & " Values('" 
strsql = strsql & titolo & "','"
strsql = strsql & sottotitolo & "','"
strsql = strsql & testo & "','"
strsql = strsql & vivo & "','"
strsql = strsql & morto & "')"
'se hai dei guai costruendo questa, metti un
'Response.Write strsql & "<br>"
'così la vedi e la puoi accomodare
costruisci_query = strsql
End Function

Sub quale_risultato(message)
'--------------------------------------------------------
'Purpose: cronaca il risultato della query e formatta una risposta
'Date: 29 March 2001
'Commenti: 
'-------------------------------------------------------- 
Select case message
case "ok"
response.write "Tutto è andato bene, <br> e grazie per il pesce." 
response.write "<br><br><div align='center'><a href='JavaScript:history.back()'>Click to go back</a></div>"
case "not ok"
response.write "È un grosso disastro!
<br> Chissa cosa è successo?"
response.write "Prova a scrivere la query e altre variabili per vedere se riesci a risolvere il problema." 
response.write "<br>Anche la professione del falegname è onorevole ;o)"
response.write "<br><br><div align='center'><a href='JavaScript:history.back()'>Click to go back</a></div>" 
case else
response.write "Se sei qui è metafisica pura" 
end select

end sub 
%>


Non è un gran che diverso da quello che abbiamo già fatto prima. Ma come sempre quando si comincia a scrivere il codice il pseudocodice si espande e così il nostro originale è diventato:

Input
Se la form NON è vuota 
includi il file attrezzi.asp
vendemmia la form
costruisci la query
esegui la query
chek per errori
Entra I dati nelil database
cronaca il risultato

Se no
Mostra la Form
finito


Costruire la query, cosa che ancora non avevamo fatto, è sempre un po' difficile ma richiede solo attenzione. Le prime volte è sempre meglio stamparla così si vede cosa non va. Più che altro stai attento alla sintassi mettendola in ordine come ho fatto io, o ancora di più se vuoi. Ordine is GOOD! 

Per esempio guarda come spesso si programma in ASP:

<%
strsql = "INSERT INTO tbl_news ( titolo, sottotitolo, _
testo, data_vivo, data_morto) Values ('"_ 
& titolo& "','" & sottotitolo & "' , ' " & testo &_
"','" &vivo& "','" & morto & "')"
%>


Come fai a vedere errori di sintassi qui? e questa è una query da bambini. Ancora meglio di quello che ho fatto io sarebbe:

<%
strsql = "INSERT INTO tbl_news"
strsql = strsql & "("
strsql = strsql & "titolo,"
strsql = strsql & "sottotitolo,"
strsql = strsql & "testo," 
strsql = strsql & "data_vivo, " 
strsql = strsql & "data_morto)" 
strsql = strsql & " Values('"
strsql = strsql & titolo 
strsql = strsql & "','"
strsql = strsql & sottotitolo
strsql = strsql & "','" 
strsql = strsql & testo
strsql = strsql & "','" 
strsql = strsql & vivo 
strsql = strsql & "','"
strsql = strsql & morto
strsql = strsql & "')"
%>


Vedi come è più facile trovare errori con un buon layout? Un altro cambiamento è avvenuto nella nostra fai_query(), la funzione che esegue la query. Quando si fanno delle query al database c'è sempre la possibilità che qualche cosa non funzioni e così è indispensabile controllare ogni errore. Guarda come abbiamo modificato il code di fai_query():


<%
On Error Resume Next

objConn.Execute strSQL

if err = 0 then
objConn.Close
set objConn = Nothing
message = "ok" 
else
message = "not ok" 
end if
%>


la linea On Error Resume Next forza il programma a continuare in caso di errore. Se non c'è un errore, l'oggetto Error rimane a zero e noi implementiamo un flag che dice "ok" ma se un errore è occorso allora mandiamo un messaggio al nostro utente per dirgli che qualcosa non ha funzionato. La nuova procedura quale_risultato(message) manda il messaggio che vogliamo noi invece di uno che vuole Microsoft.
Allora tutto quello che rimane è formattare l'Output ma lo faremo nella prossima lezione.

Come presentare l'Output




 

Questa lezione sarà di riposo. Vogliamo solo finire la nostra applicazione per le news e sappiamo già cosa dobbiamo fare. Vediamo allora come formattare l'output:

Output
Prendi il recordset dalil database
Format e mostrala al cliente


Se modifichiamo il nostro file check_connection.asp esso dovrebbe già fare tutto. Cambiamo la query e basta.

Ma adesso mi accorgo che questa lezione non è un riposo poiché abbiamo a che fare con delle date ;o(
Beh, tanto vale che risolviamo il problema.

Se vogliamo che il nostro programmino di News sia utile bisogna che facciamo vedere solo le News che si riferiscono alla data corrente quindi la nostra query deve tener conto forzatamente della data e dovrebbe diventare

select * from tbl_news where data_morto < oggi

In genere il formato della data dipende da come il server è stato configurato e non sempre noi abbiamo controllo del server. Diciamo che il tuo sito è su un server a Bologna e tutto funziona perfettamente. Domani invece lo muovi su un server a Seattle (USA) perché ti costa la metà, funzionerà tutto bene anche lì? 

Io credo di no. Il server americano di sicuro salva la data come mese/giorno/anno mentre a Bologna tu adoperavi giorno/mese/anno. Se, per esempio, si vuole inserire un comando del tipo:

se 
02/03/01 è diverso da 03/02/01 
allora cambia la data


a Bologna sarà vero ma a Seattle non lo sarà più anche se la data è la stessa. Come facciamo a risolvere questi problemi?

Non è poi così difficile è solo una seccatura. Prova un po' questo:

<%
Option Explicit
dim oggi,x

oggi = date()
response.write "oggi = " & oggi & "<br>"
x = split(oggi, "/")

response.write "x(0) = " & x(0) & "<br>"
response.write "x(1) = " & x(1) & "<br>"
response.write "x(2) = " & x(2) & "<br>"
%>


Con la funzione Split riusciamo a separare i tre campi della data. Una volta che li abbiamo così, possiamo rimetterli a posto come vogliamo noi

<%
data_Bologna = x(0) & "/" & x(1) & "/" & x(2)
data_Seattle = x(1) & "/" & x(0) & "/" & x(2)
%>


Allora adesso che abbiamo risolto il problema della data, torniamo al nostro output per il programma News.

Prendi il vecchio check_connection.asp è chiamalo news_out.asp. L'unica cosa da fare qui è cambiare:

Sub Guarda_Recordset(objRs)


così che si presenta un po' meglio.

Prima però mettiamo un altro campo nel database così che possiamo mandare i nostri clienti direttamente ad un'altra pagina dove la news viene mostrata per intero o ad un altro sito dove ci sono informazioni più approfondite.

Naturalmente bisogna anche cambiare l'input così che possiamo inserire questo URL nel database.
Ora la nostra tbl_news ha un campo chiamato url e questi comandi vanno nel nostro news.inc:

<tr>
<td nowrap>URL</td>
<td valign="top"><INPUT NAME="url" TYPE="TEXT" size="24" MAXLENGTH="100"></td>
</tr>


Allora adesso dobbiamo fare in modo che la pagina mostri il titolo e il sottotitolo di tutte le news che abbiamo con la data_morto > (maggiore) di oggi. Poi quando il cliente clicca sul titolo il testo deve apparire per intero.

Adesso la mia procedura è diventata:

<%
Sub Guarda_Recordset(objRs)
'--------------------------------------------------------
'Purpose: mostra un format recordset dalla mia database
'Date: 28 March 2001
'Commenti:
'--------------------------------------------------------
dim titolo, sottotitolo, test, url 

'vendemmia la form
titolo = objRs("titolo")
sottotitolo = objRs("sottotitolo")
url = objRs("url")

Do while NOT objRs.EOF
'tanto per cambiare possiamo usare HTML puro
%> 

<table width="80%" border="0" cellpadding="4" cellspacing="2">
<tr>
<td rowspan="2" width="5%" valign="top"><img src="news.gif" width="32" height="36" alt="" border="0"></td>
<td bgcolor="#8b4513" widrh="100%"><a href="<%=objRs("url")%>"><font size="+2" color="white"><%=titolo%></font></a></td> 
</tr>
<tr>
<td bgcolor="#b8860b"><font size="+1" color="white"><%=sottotitolo%></td>
</tr>
</table>

<%
objRs.Movenext
Loop

End sub
%>


Come vedi puoi formattare l'output come vuoi e come hai sempre fatto. 

L'unica linea che non abbiamo commentato è quella dell'URL

<a href="<%=objRs("url")%>"><%=titolo%></a>


Si potrebbe anche fare molto meglio passando l'id della news nella Request.Querystring così:

<a href="<%=objRs("url")%>?id=<%=objRs("id")%><%=titolo%></a>


se questa sintassi ti sembra un po' confusa prova invece:

response.write "<a href='" & url & "?id=" & id "'>" & titolo & "</a>"


tutte e due danno lo stesso risultato.
Ormai è tutto semplice no?

Come lavorare dal letto




 

Adesso che abbiamo imparato a usare un database dal Web e sappiamo costruire pagine che ci danno accesso a tutti i nostri dati non dobbiamo più essere in ufficio per lavorare. Volendo, possiamo rimanere a letto e con il portatile continuare a mantenere il sito in tutta tranquillità.

Però... prima bisogna creare un'area privata sul nostro sito altrimenti chiunque sapesse l'URL potrebbe modificare il nostro database attraverso le nostre pagine. Un grosso NO, NO. Il database è il nostro tesoro. Prima di rimanere a letto sarà meglio che creiamo una Login con una password in modo da essere al sicuro proprio come Ali Baba dentro la sua caverna. 

Cosa si fa? Di sicuro hai già una buona idea su come procedere. Io di solito faccio così:
Nel global.asa metto:

<%
Sub Session_OnStart
Session("login") = False
End Sub
%>


Ok, così quando vieni nella pagine la variabile mi dice che tu non sei autorizzato. Quindi in ognuna delle mie pagine che voglio mantenere private, in cima, prima che succeda niente, controllo per vedere se il mio cliente ha l'autorizzazione. 

<%
If Session("login") then
'fai tutto quello che la tua pagina deve fare
else
'Mi dispiace ma qui non ci puoi entrare
end if 
%>


Siccome tutte le mie pagine adoperano due include, una per la testa della pagina e una per la coda, di solito questa parte del codice risiede lì.

Allora con questo sistema non possono entrare ma sfortunatamente non possiamo entrare neanche noi ;o)
Quindi creiamo subito una tabella nel nostro database chiamandola tbl_login. Qui ci mettiamo:

tbl_login

Nome campo

Tipo campo

Id

primary key

Nome

Text

Cognome

Text

Login

Text

Password

Text


e adesso scriviamo il programma Login.asp.

Da ora in poi non strutturerò più il codice in quanto i programmi sono un po' troppo corti per farlo. Lo puoi far tu se vuoi, è una buona abitudine da prendere. 

Siccome abbiamo già messo la nostra variabile Login nella global.asa, quando entriamo nel sito per la prima volta è già inizializzata come:

login = false

La logica, come sempre, è

Se clickato 
fai quello che devi fare
se no
mostra la form


<%
Option Explicit
'--------------------------------------------------------
'Purpose: Login
'Date: 07 April 2001
'Commenti: 
'--------------------------------------------------------
Response.Buffer = True

Dim objConn, strConn, objRs, strsql
Dim submitted, login, password
%>

<html>
<head>
<title>Login</title>
</head>
<body bgcolor=powderblue>

<%
submitted = Request.Querystring("submitted")

If Submitted then

strConn = Application("dbconn")

login = Request.Form("login")
password = Request.Form("password")

strsql = "Select id, login, password FROM tbl_login "
strsql = strsql & "WHERE login ='" & login & "' AND password = '" & password & "'"

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
set objRs = objConn.Execute(strsql)

If objRs.EOF then
'Non è valido, mandalo indietro
response.redirect "login.asp"
Else
'è valido, fallo entrare
session("login") = True
objRs.close
Set objRs = Nothing
response.redirect "ufficio.asp"
end if
else
'mostra la form
%>

<div align="center">
<form action="login.asp?submitted=true" method="post">
<table align="center" cellspacing="0" cellpadding="5" border="1" bordercolor="midnightblue" bgcolor="ivory" width="400">
<tr>
<th><font color=firebrick size=+2><b>Solo chi voglio io!</b></font></th>
</tr> 
<tr>
<td align="center" bgcolor="azure">
<%
if session("login") and Submitted then
response.redirect "login.asp" 
else
response.write "<br><br> Per favore, inserisci login/password. <br><br>"
end if
%>
<table>
<tr>
<td class=event>Login:</td>
<td><input type="text" name="Login" size="10" maxlength="30"></td>
</tr>
<tr>
<td class=event>Password:</td>
<td><input type="password" name="Password" size="10" maxlength="12"></td>
</tr>
</table>
<br>
<input type="submit" value="Submit">
<input type="reset" value="Cancel" Onclick="Javascript:history.go(-1)">
</td>
</tr>
</table>
</form> 
</div>

</body>
</html>

<%
end if

Response.end
Response.Clear
%>

I dati della form sono entrati in una query al database e se il recordset è vuoto vuol dire che non abbiamo trovato una valida combinazione di login/password quindi rimandiamo al login.asp per riprovare. 

Qui potresti contare fino a 3 per esempio e poi far scomparire il login.
Se il recordset contiene dati, vuol dire che la combinazione esiste e quindi:

<% Session("login") = true %>


che ci permette di entrare dentro al nostro sito in un area che controlliamo solo noi. 

Se tu volessi adoperare questa tecnica per fare entrare i tuoi clienti in un area privata sarebbe comodo mantenere informazioni sul tuo utente. Informazioni che ti possono servire per comunicare con esso durante il tempo che spende con te nel tuo sito. Siccome abbiamo guardato al suo record tanto vale che teniamo le informazioni. Cose come:

<%
Session("id") = objRs("id")
Session("nome") = objRs("nome")
%>

 

Il pannello di controllo




 

La pagina Login.asp che abbiamo appena costruito è un po' come la chiave dell'ufficio. Virtuale, naturalmente, e raggiungibile direttamente dal letto. Il nostro ufficio però è piuttosto vuoto e sarà meglio che cominciamo a riempirlo con le cose di cui abbiamo bisogno per lavorare.

Il file a cui ci manda il login.asp si chiama ufficio.asp per una ragione.

Questo qui sotto, per esempio, è uno dei miei. Di solito ne costruisco uno per ogni sito ma adesso che ci penso dovrei costruirmene uno solo che funziona per tutti i siti. Ah!, si impara sempre in questo lavoro...

eCalcx Home
Latest Stats
Daily
Weekly
Monthly
Menu Administration
Add new Tool
Change Tool Status
View/Edit /Delete Tool
Add admin
Add New Ad
Maintain Ad Campaign
View Ad Reports
Mailing
Maintain Maling list
Send email to list
Add subscriber
Subscribe/Unsubscribe from list
Feedback
CRM tool
Distribute 
Analysis
Archive
Manage remote staff
Links
Edit/Delete links
Approve links
Workshop
Manage remote developers

Ognuna di queste entrate è un piccolo programma che mi permette di lavorare a letto.
Beh, non proprio dal letto ma certo che non ho bisogno di essere in ufficio per mantenere questo sito.

Cominciamo allora a costruire il nostro ufficio.asp
Il file è una semplice tabella dove possiamo continuare a metterci entrate ogni volta che costruiamo qualcosa di nuovo. Al momento ho paura che le news sono l'unica cosa che possiamo fare, ma di sicuro tu stai già pensando a un mucchio di altre cose.

<% 
If session("login") then
%>
<html>
<head>
<title>Ufficio</title>
</head>
<body>
<div align="center">
<table width="60%" border="0" cellspacing="4" cellpadding="4" align="center">
<tr>
<th colspan=2>
<font size=+2 color="firebrick">Ufficio Virtuale o Letto?</font>
<hr size="1" color="firebrick" width="80%" align="center">
</th>
</tr>
<tr>
<td width="40"><img src="news1.gif" width="35" height="35" alt="" border="0"></td>
<td width="100%">
<a href="news.asp"><font color="teal">Inserisci una nuova News</font></a>
</td>
</tr>
<tr>
<td></td>
</tr>
</table>
</div>
</body>
</html>
<%
else
response.write "Mi dispiace ma questo è il mio ufficio e tu non hai la chiave..."
end if
%>


Come vedi tutto quello che facciamo qui è controllare che la chiave ci sia altrimenti mandiamo un messaggio e rifiutiamo l'ingresso. Prova a incollare http://dovehaimessoquesta/ufficio.asp nell'area di indirizzo del browser e vedrai che non ti fa entrare.
Ora che hai aperto il tuo ufficio virtuale cominciamo a sistemarlo per bene.

Come mantenere i nostri dati




 

Torniamo al programma News.asp. Ok, ci permette di inserire una nuova notizia ma cos'altro?
Bisognerebbe anche averne uno che ci permette di modificarla. Diciamo che siamo a letto e guardando il sito vediamo che abbiamo fatto un errore in un News, come lo accomodiamo?
Vediamo di modificare questa News e farla un po' più utile. Bisognerebbe essere in grado di

aggiungere una nuova - lo facciamo già
cambiare una esistente
cancellare una esistente


Tutto qui? Tu forse ne sai più di me adesso ma io, al momento, non riesco a pensare ad altro.

Facciamolo in una maniera semplice. Creiamo un'altra entrata nel nostro ufficio:

<a href="mantieni_news.asp"><font color="teal">Mantieni le News</font></a>


e una fila chiamata mantieni_news.asp:

<%
Option Explicit
'--------------------------------------------------------
'Purpose: mostra le news per cambiarle
'Date: 7 Aprile 2001
'Commenti: 
'--------------------------------------------------------
%>
<!--#include file="adovbs.inc"-->
<%
Dim objConn, strConn, objRs, strsql

'abbiamo le chiavi?
If Session("login") then

strConn = Application("dbconn")
strsql = "Select * from tbl_news order by data_morto Asc"

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRs = Server.CreateObject("ADODB.Recordset")

set objRs = objConn.Execute(strsql)
'controla per errori da solo

response.write "<div align=center>" 
response.write "<table border='1' width='80%' cellpadding='4' cellspacing='4' bgcolor='bisquè>"
response.write "<tr><th colspan='4' align='center'><font size='+2' color='firebrick'>Mantieni le News</font></th</tr>"
'ricordati di passare l'id del record nella querystring
Do while Not objRs.EOF
%> 
<tr>
<td width="5%"><font color='teal'><%= objRs("id") %></font></td>
<td width="75%"><font color='teal'><%= objRs("titolo") %></font></td>
<td width="10%"><a href="cambia_news.asp?id=<%= objRs("id") %>">cambia</a></td>
<td width="10%"><a href="cancella_news.asp?id=<%= objRs("id") %>">cancella</td>
</tr> 
<%
objRs.MoveNext
Loop
Response.write "</table></div>"
else
'quando hai tempo, metti queste linee in un .inc e formattale con un bel messaggio
'poi la puoi mettere dappertutto nell'ufficio
response.write "Mi dispiace ma questo è il mio ufficio e tu non hai la chiave..."
end if
%>


Con questa file vediamo tutte le nostre news, un titolo alla volta. Poi ad ogni titolo mettiamo un option per cambiare o cancellare quella specifica entrata. 
Quando clicchiamo su "cambia" chiamiamo un'altra fila cambia_news.asp che ci permette di farlo.
Come? così:

<%
Option Explicit
Dim strConn, objConn, objRs, strsql, submitted
Dim id, titolo, sottotitolo, testo, vivo, morto,url

'abbiamo le chiavi per l'ufficio?
If Session("login") then

strConn = Application("dbconn")
submitted = Request.QueryString("submitted")

'si, ma è clickata la Form?
If submitted then
'si, è clickata quindi cambiamo i dati

id = Request.QueryString("id")

'raccogliamo I dati dall nostra form
titolo = Request.Form("titolo")
sottotitolo = Request.Form("sottotitolo")
testo = Request.Form("testo")
vivo = Request.Form("vivo")
morto = Request.Form("morto")
url = Request.Form("url")

'costruiamo la query 
strsql = "Update tbl_news "
strsql = strsql & " SET ("
strsql = strsql & "titolo = '" & titolo & "',"
strsql = strsql & "sottotitolo = '" & sottotitolo & "',"
strsql = strsql & "testo = '" & testo & "',"
strsql = strsql & "data_vivo = #" & vivo & "#,"
strsql = strsql & "data_morto = #" & morto & "#,"
strsql = strsql & "url = '" & url & "') "
strsql = strsql & "Where id = " & id

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRs = Server.CreateObject("ADODB.Recordset")


set objRs = objConn.Execute(strsql)
'guarda per errori da solo, come abbiamo già fatto 

objConn.Close
Set objConn = Nothing

else 
'ancora non abbiamo clickato niente e vogliamo solo vedere
id = Request.QueryString("id")

strsql = "Select * from tbl_news where id = " & id

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRs = Serve
r.CreateObject("ADODB.Recordset")

set objRs = objConn.Execute(strsql)

'vendemmia il recorset
titolo = objRs("titolo")
sottotitolo = objRs("sottotitolo")
testo = objRs("testo")
morto = objRs("data_morto")
vivo = objRs("data_vivo")
url = objRs("url")
%>
'mostra la forma con I valori che sono nelil database
<FORM ACTION="cambia_news.asp?submitted=true&id=<%= id %>" METHOD="post">
<div align="center">
<table border="0" width="95%" celpadding="2" cellspacing="2">
<tr>
<td><h1>Cambia quello che vuoi...<hr align="LEFT" size="1" width="100%" color="navy"></h1></td>
</tr>
<td align="center"><br><br>
<table width="80%" border="0" celpadding="2" cellspacing="2">
<tr>
<td>Titolo</td>
<td><INPUT NAME="titolo" TYPE="TEXT" Value="<%= titolo %>" size="80" MAXLENGTH="80"></td>
</tr>
<tr>
<td>Sottotitolo</td>
<td valign="top"><TEXTAREA NAME="sottotitolo" ROWS="3" COLS="60"><%= sottotitolo %></TEXTAREA></td>
</tr>
<tr>
<tr>
<td valign="top">News</td>
<td valign="top"><TEXTAREA NAME="testo" ROWS="10" COLS="60"><%= testo %></TEXTAREA></td>
</tr>
<tr>
<td nowrap>Data di entrata</td>
<td valign="top"><INPUT NAME="vivo" TYPE="TEXT" Value="<%= vivo %>" size="24" MAXLENGTH="24"></td>
</tr>
<tr>
<td nowrap>Data di scadenza</td>
<td valign="top"><INPUT NAME="morto" TYPE="TEXT" Value="<%= morto %>" size="24" MAXLENGTH="24"></td>
</tr> 
<tr>
<td nowrap>URL</td>
<td valign="top"><INPUT NAME="url" TYPE="TEXT" Value="<%= url %>" size="24" MAXLENGTH="100"></td>
</tr> 
<tr>
<td valign="top"><b>&nbsp;</b></td>
<td>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<table width="40%" border="0" celpadding="6" cellspacing="2">
<tr> 
<td align="right"><INPUT TYPE="submit" NAME="submit" VALUE="Entra"></td>
<td align="left"><INPUT TYPE="reset" NAME="Reset" VALUE="Reset"></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</FORM>
<%
end if

end if
%>



Tutto qui. Adesso possiamo cambiare quello che vogliamo, quando vogliamo e da dove vogliamo.
Nella stessa maniera puoi implementare il bottone che cancella, con un file cancella_new.asp. Questa è ancora più semplice. Tutto quello che devi fare è attivare una Delete query quando il bottone è cliccato.

Qui abbiamo usato una soluzione molto semplice ma si potrebbe/dovrebbe fare un po' più elegante e con meno file. Queste sono questioni di preferenza. Avremmo potuto usare lo stesso file con un Select statement. La logica diventa un po' più complicata ma di sicuro lo sapresti fare adesso.

Finisci questa applicazione da solo e vedrai che la troverai utile. Una volta che hai imparato a fare:

Insert
Select
Update 

hai imparato a fare tutto ;o) Il resto è questione di pazienza, di stile, di sintassi. Non si finisce mai di imparare. In più come ti ho detto, ci sono molte maniere per spellare un gatto, molto più efficienti di quello che ti ho fatto vedere. Di sicuro troverai le tue.

Le News non bastano




 

Adesso che hai visto come si fa presto a lavorare senza dover essere in ufficio comincia a pianificare le tue prossime vacanze in Australia (è bello qui, sai?). Prima di partire sarà meglio che ci costruiamo un po' più di attrezzi per il nostro sito altrimenti chi paga il mangiare?

Per esempio adesso che abbiamo un servizio di news efficiente e da poter cambiare tutti i giorni certamente le visite al nostro sito cresceranno e con quelle anche la comunicazione con i nostri clienti crescerà di volume. I nostri clienti ci faranno più domande (il che naturalmente vuol dire più business ;o) ed è importantissimo che noi gli rispondiamo il più presto possibile. 

Se ti ricordi, nella lezione 9 abbiamo scritto una piccola applicazione che mostra una feedback form, e quando è inviata, ci manda un email. Troppo indietro? Beh, ormai fai prima a riscriverla. Però se la riscrivi tanto vale che la migliori allo stesso tempo. Cambiamola in modo che compia queste azioni:

Mostra la form
quando e submitted
mandaci una email
entra I dati nelil database 


Trova il code vecchio così che ne ricicliamo dei pezzi. È vero che adesso ne sappiamo molto di più ma forse avevamo già fatto qualcosa di utile anche allora. 

E infatti:

feedback.asp è la form, trovala e cambiamo solo la linea:

<FORM ACTION="manda_feedback.asp" METHOD="post">


apriamo un file nuovo e chiamiamolo feedback_extra.asp così poi lavoriamo tutto in un unico file. Io preferisco sempre meno file che più.

Allora la linea diventa:

<FORM ACTION="feedback_extra.asp?clickato=true" METHOD="post" onSubmit="return submitIt(this)">


Oh, in più stavolta facciamo la verifica dei dati nella form sul cliente. Usiamo una semplice funzione in Javascript che controlla se l'email è vuota. Se non hai familiarità con Javascript prova a mandare la form senza email e vedi subito cosa succede.

<script language="JavaScript">
<!--
function submitIt(theform) {
if (theform.email.value == "") {
alert("Per favore, entra il tuo email...") 
theform.email.focus()
return false
}

-->
</script>


Se il cliente non inserisce l'email facciamo aprire una piccola dialog window in cui chiediamo il suo l'indirizzo. Poi, quando torniamo alla form, collochiamo il cursore sull'email text box, per rendere tutto più facile.
E sempre meglio essere gentili, no?

Feedback_extra.asp comincia così, come al solito.

<%
If clickato then
'facciamo tutto qui
else
%>
<!--#include file='feedback.asp'-->
<%
end if
%>


Il 'facciamo tutto qui' segue in dettagli:

<%
Option Explicit
'--------------------------------------------------------
'Purpose: Raccoglie il feedback dal sito e lo entra nella CRM database
'Date: 13 Aprile 2001
'Commenti:
'--------------------------------------------------------
%>
<html>
<head>
<title>Raccogliere il Feedback</title>

<script language="JavaScript">
<!--
function submitIt(theform) {
if (theform.email.value == "") {
alert("Per favore, entra il tuo email...") 
theform.email.focus()
return false
}

-->
</script>

</head>
<body>

<%
Dim form, clickato 
Dim nome, email, commenti

call Main()

Sub Main()
'--------------------------------------------------------
'Purpose: la logica dell'applicazione
'Date: 13 April 2001
'Commenti: 
'--------------------------------------------------------
clickato = Request.QueryString("clickato")

If clickato then
call vendemmia(form)
call metti_dentro(nome,email,commenti)
call manda_grazie(email)
call mostra_grazie()

else
%>
<!--#include file='feedback.asp'-->
<%
end if
End sub

'-------------------------------------------------------
Sub vendemmia(form)
'--------------------------------------------------------
'Purpose: raccoglie i dati della form
'Date: 10 March 2001
'Commenti: 
'-------------------------------------------------------- 

nome = Request.Form("nome")
email = Request.Form("email")
commenti = Request.Form("commenti")

end sub

'-------------------------------------------------------
Sub metti_dentro(a,b,c)
'--------------------------------------------------------
'Purpose: entra i dati nelil database
'Date: 10 March 2001
'Commenti: 
'-------------------------------------------------------- 
Dim strsql, objConn, strConn, objRs

strConn = Application("dbconn")

strsql = "INSERT INTO tbl_feedback ( nome, email, commenti)" 
strsql = strsql & " Values('" 
strsql = strsql & a & "','"
strsql = strsql & b & "','"
strsql = strsql & c & "')"

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
set objRs = objConn.Execute(strsql)

objConn.Close
set objConn = Nothing
end sub

'-------------------------------------------------------
Sub manda_grazie(achi)
'--------------------------------------------------------
'Purpose: manda la email
'Date: 10 March 2001
'Commenti: 
'-------------------------------------------------------- 
Dim objMail, messaggio

messaggio = "Molte grazie per il feedback" & VBcrlf
messaggio = messaggio & "Rispondo in 24 ore max..." 

Set objMail = Server.CreateObject("CDONTS.NewMail")
objMail.From = "ilmioemail@ilmioprovider.etc"
objMail.To = achi
objMail.Subject = "Molte grazie da ilnomedelmiosito"
objMail.Body = messaggio

objMail.importance = 0
objMail.Send
Set objMail = Nothing
end sub

Sub mostra_grazie()
'--------------------------------------------------------
'Purpose: apri una pagina per ringraziare
'Date: 13 Aprile 2001
'Commenti: 
'--------------------------------------------------------
response.write "<div align='center'>"
response.write "<table border='0' width='80%' cellspadding='4' cellspacing='4'>" 
response.write "<tr><td>Molte grazie per il tuo feedback....</td></tr>"
response.write "<tr><td align='middlè>"
response.write "<a href='Javascript:history.go(-2)'>Vai Indietro</a>"
response.write "</td></tr></table></div>"
End Sub

%>
</body>
</html>


Facile no? Adesso che abbiamo la nostra email in un database possiamo disegnarci e costruire una applicazione simile alla gestione delle news che ci permette di rispondere alla email con comodo e dal database. Questa applicazione deve:

· mostrarci il feedback "non risposto"
· permetterci di scrivere una risposta
· mandare la risposta all'utente
· inserire la nostra risposta nel database insieme al suo feedback

sarebbe anche bello se potesse mostrarci, se lo abbiamo, il feeedback precedente dallo stesso cliente. Per esempio, in caso che il feedback sia parte di una conversazione che ci siamo dimenticati, o se abbiamo più di una persona che risponde al feedback come lavoro quotidiano.

Proviamo?

E poi possiamo partire per l'Australia




 

Come sempre la logica viene per prima.
Qui siamo in ufficio così subito controlliamo se hai le chiavi.

si
Do 
Finché ce n'è
prendi tutto il feedback che ancora non ha avuto risposta
mostralo 
scegli quello a cui vuoi rispondere
dammi un area per la risposta
hai bisogno della conversazione precedente?
se si
mostrala in una nuova window
manda la risposta al cliente
entra la risposta nelil database
loop
no
messaggio "Fuori dal mio ufficio…!"

Guardando alla logica mi sembra che non possiamo proprio fare tutto senza fare un piccolo cambiamento al file della lezione precedente. Poiché vogliamo vedere solo il feedback cui non è stato risposto abbiamo bisogno di un campo nel database che ci indica lo stato di quel particolare feedback. Diciamo tre stati diversi, oppure come vuoi tu, ma almeno due sono necessari.

Quindi inseriamo un campo in tbl_feedback chiamato "status" e nel nostro codice inseriamo un controllo per questi tre stati. Vedi subito che puoi aggiungerne altri senza dover cambiare il database.

1. attivo
2. risposto
3. cancellato

La nostra Sub metti_dentro(a,b,c) in feedback_extra cambia così per tenere conto dello stato.
Naturalmente ho anche inserito il campo nella tbl_feedback in CRM.mdb:

<%
'-------------------------------------------------------
Sub metti_dentro(a,b,c)
'--------------------------------------------------------
'Purpose: inserisci i dati nel database
'Date: 10 March 2001
'Commenti: 
'-------------------------------------------------------- 
Dim strsql, objConn, strConn, objRs
Dim status 

strConn = Application("dbconn")
status = "attivo"

strsql = "INSERT INTO tbl_feedback ( nome, email, commenti, status)" 
strsql = strsql & " Values('" 
strsql = strsql & a & "','"
strsql = strsql & b & "','"
strsql = strsql & c & "','"
strsql = strsql & status & "')"

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
set objRs = objConn.Execute(strsql)

objConn.Close
set objConn = Nothing
end sub
%>


Adesso che abbiamo il campo status possiamo estrarre facilmente i nostri feedback non risposti con una query che abbia queste istruzioni:

select * from tbl_feedback where status='attivo' 
Allora via senza perder tempo. facciamo 
feedback_mostra che ce li lista tutti
feedback_rispondi - ci permette di rispondere quello che scegliamo
feedback_manda - che manda l'email e entra la risposta nelil database/

Ecco feedback_mostra.asp:

<%
come sempre usiamo per dichiarare tutte le variabile e per aiutarci nel trovare errori 
Option Explicit
'--------------------------------------------------------
'Purpose: mostra tutto il feedback non risposto (attivo)
'Date: 13 Aprile 2001
'Commenti:
'--------------------------------------------------------
%>
includiamo le costanti di ADO
<!--#include file="adovbs.inc"-->
<html>
<head>
<title>Mostra il Feedback attivo</title>
</head>
<body>
<%
Dim objConn, strconn, strsql, objRs
Dim id, nome, email, commenti, status, ricevuto 

If Session("login") then

strconn= Application("dbconn")


Nella nostra query, ordiniamo l'output così che la più vecchia viene fuori per prima, siccome non vogliamo fare aspettare I nostri clienti per troppo tempo. 

<% strsql = "Select * from tbl_feedback where status = 'attivo' order by ricevuto" 
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRs = Server.CreateObject("ADODB.Recordset")
set objRs = objConn.Execute(strsql)

Response.write "<table border='0' width='80%' cellpadding='2' cellspacing='2'>"
Do While NOT objRs.EOF
%>


Quando un oggetto è richiesto come in questo caso il Request, è sempre più efficiente estrarre il suo contenuto tutto in una volta. Nell'aprire un oggetto ci sono sempre dei costi e raccogliendo tutti i dati che ci servono in una volta li minimizziamo. 
Avremmo anche potuto fare:

<% Response.write "<td width='5%'><font color=red>" & objRs("id") & "</font></td>" %>

 
ma l'oggetto si sarebbe riaperto e chiuso per ogni linea di codice

 

<%
id = objRs("id")
nome = objRs("nome")
email = objRs("email")
commenti = objRs("commenti")
%>


E' per questo che io adopero funzioni come vendemmia(form) e raccolgo i dati dall'oggetto tutti in una volta. Questo concetto è valido per qualunque oggetto in ASP.

Questa è un funzione di VBScript per formattare una data in modo da non scrivere l'ora e i minuti ecc.

ricevuto = formatdatetime(objRs("ricevuto"),VBShortdate)
status = objRs("status")
Response.write "<tr bgcolor='#f5deb3'><td width='40'>"


Qui abbiamo messo una immagine come un ancora. Quando vi clicchiamo sopra chiamiamo la pagina per rispondere e passandogli l'id del feedback che abbiamo scelto

Response.write "<a href='feedback_rispondi.asp?id=id'>"
Response.write "<img src='folder.gif' width='32' height='30' alt='' border='0'>"
Response.write "</a></td>"

Response.write "<td width='5%'><font color=red>" & id & "</font></td>"
Response.write "<td width='40%'><font color=midnightblue>" & nome & "</font></td>"
Response.write "<td width='40%'><font color=midnightblue>" & email & "</font></td>"
Response.write "<td width='100%' align=right><font color=red>" & ricevuto & "</font></td>"
Response.write "</tr>"
Response.write "<tr bgcolor='#f8bf87'>"
Response.write "<td colspan='5'>"
Response.write "<font color='firebrick'><b>Commenti:</b></font><br>" & commenti & "</td></tr>"

objRs.MoveNext
Loop


per quando abbiamo finito o vogliamo interrompere il nostro lavoro

Response.write "<tr><td><a href='Javascript:history.back()>Torna indietro</a></td></tr>"
Response.write "</table>" 

else
call niente_chiave() 
end if

Sub niente_chiave()
'--------------------------------------------------------
'Purpose: mostra un messaggio ben format
'Date: 13 April 2001
'Commenti: 
'--------------------------------------------------------
Response.write "<table border='0' width='80%' cellpadding='2' cellspacing='2'>"
Response.write "<tr><td>"
Response.write "Mi dispiace ma questo è il mio ufficio.<br>"
Response.write "Costruisciti il tuo!<br>"
Response.write "</td></tr>"
Response.write "<tr><td><a href='Javascript:history.back()>Torna indietro</a></td></tr>"
Response.write "</table>" 

end sub
%>

</body>
</html>


Nessun problema finora? Allora avanti.
Adesso il file feedback_rispondi deve solo prendere l'Id che abbiamo passato nella collezione QueryString dell'oggetto Request e eseguire una query al database con quello. Poi deve mostrarci un'interfaccia che ci permetta di rispondere al nostro feedback. Per la nostra risposta possiamo entrare una textarea che ci permette di scrivere. Ecco tutto il programma

<%
Option Explicit
'Response.buffer = true
'--------------------------------------------------------
'Purpose: mostra un singolo feedback
'Date: 13 Aprile 2001
'Commenti:
'--------------------------------------------------------
%>

<html>
<head>
<title>Rispondi un Feedback</title>
</head>
<body>
<%
Dim objConn, strconn, strsql, objRs
Dim id, nome, email, commenti, ricevuto, risposta

If Session("login") then


Allora prendiamo subito l'id di cui abbiamo bisogno per trovare il feedback che vogliamo

id = Request.QueryString("id")
poi la connessione al database 
strconn= Application("dbconn")


e l'id lo adoperiamo qui:

strsql = "Select * from tbl_feedback where id = " & id 
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRs = Server.CreateObject("ADODB.Recordset")
set objRs = objConn.Execute(strsql)
%>


tutto fatto, ora formattiamo l'output così che lo vediamo e come vogliamo noi. Se tu vuoi puoi naturalmente usare del'HTML normale. Io mi sono abituato così' e sono ormai troppo vecchio per cambiare ;o)

Anche qui vedi, apriamo l'oggetto objRs una volta sola e lo vuotiamo di tutto

<%
id = objRs("id")
nome = objRs("nome")
email = objRs("email")
commenti = objRs("commenti")
ricevuto = formatdatetime(objRs("ricevuto"),VBShortdate)
%>


Ricordati che anche se rimaniamo nella stessa pagina il server la tratta come una pagina nuova. Quando il cliente clicca su Invia esegue una richiesta al server per questa pagina e il server la manda indietro. È solo la nostra logica che le fa fare cose diverse. Quindi dobbiamo passare l'id ancora per inviare la nostra risposta nel feedback giusto del database e in più abbiamo bisogno dell'email per mandargli la risposta:

Response.write "<form action='feedback_manda.asp?id='" & id & "&email=" & email & " method='post'>"

Response.write "<table border='1' width='95%' cellpadding='2' cellspacing='1' bgcolor='#f5deb3'>"
Response.write "<tr>"
Response.write "<td width='5%'><font color=red>" & id & "</font></td>"
Response.write "<td width='30%'><font color=midnightblue>" & nome & "</font></td>"
Response.write "<td width='30%'><font color=midnightblue>" & email & "</font></td>"
Response.write "<td width='100%' align=right><font color=red>" & ricevuto & "</font></td>"
Response.write "</tr>"
Response.write "<tr>"
Response.write "<td colspan='4'><font color=midnightblue>" & commenti & "</font></td>" 
Response.write "</tr>"
Response.write "<tr>"
Response.write "<td colspan='4' align='center'>"
Response.write "<table border='1' width='100%' cellpadding='2' cellspacing='1' bgcolor='#f8bf87'>"
Response.write "<tr><td><textarea cols='90' rows='20' name='risposta'></textarea></td></tr>"
Response.write "<tr><td><input type='submit' name='submit' value='Rispondi'>"
Response.write "<input type='Reset' name='submit' value='Cancella'></td></tr>"
Response.write "</td></tr></table>"
Response.write "</td></tr></table>"
Response.write "</form>"
else
call niente_chiave() 
end if
%>


E adesso tutto quello che ci è rimasto da fare è mettere la nostra riposta. 
Oh, mi sono dimenticato! Non abbiamo un campo risposta nella nostro database o sì? Non mi ricordo, vado a controllare.
Non c'è. Mettiamolo e, già che ci siamo, mettiamo anche un campo per la data in cui abbiamo inviato la nostra risposta. Poi quando abbiamo usato questo programma per un po' e abbiamo un mucchio di dati, possiamo fare delle analisi per vedere quanto siamo efficienti nel rispondere ai nostri clienti. Per esempio:

"trovami il numero dei feedback in cui la differenza ( ricevuto, mandato) > 24 ore" 

Ho messo due campi in tbl_feedback:
risposta - memo
mandata - date/time


allora la file feedback_manda.asp diventa così:

<%
Option Explicit


L'oggetto response deve essere dichiarato per primo se vogliamo usarlo nella pagina. Poche dichiarazioni come 

Option explicit
Language…

riescono a stargli davanti. Tutto ciò riguarda il fatto che l'oggetto response deve inserire delle informazioni nell'header HTTP, quindi se è già scritta lui non può farlo.
Comunque te ne accorgerai subito perché il motore di ASP ti restituirà un brutto errore.

Se vuoi vedere queste cose, semplicemente commenta la prossima linea e poi vedi cosa succede. La prossima volta che ti succede non ti devi rompere la testa inutilmente poiché quell'errore lo sai già

Response.buffer = true

'--------------------------------------------------------
'Purpose: manda il feedback che abbiamo riposto 
' entra la risposta e la data nelil database
' cambia lo status to 'risposto'
'Date: 13 Aprile 2001
'Commenti:
'--------------------------------------------------------
%>

<html>
<head>
<title>Manda una risposta</title>
</head>
<body>
<%
Dim objConn, strconn, strsql, objRs
Dim id, risposta, mandata, email

'If Session("login") then


prendiamo tutto il contenuto della querystring

id = Request.QueryString("id")
email = Request.QueryString("email")


e della form:

risposta = Request.Form("risposta")


il vecchio problema delle &quot; più che altro per MS SQL credo…

risposta = Replace(risposta,"'","''")


usiamo la funzione date per ottenere la data di oggi

mandata = Date()

strconn= Application("dbconn")
strsql = "Update tbl_feedback " 
strsql = strsql & " Set "
strsql = strsql & " risposta = '" & risposta & "'," 
strsql = strsql & " mandata = #" & mandata & "#,"


e naturalmente cambiamo lo status del feedback così che non torna più:

strsql = strsql & " status = 'risposto'" 
strsql = strsql & " where id = " & id 

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRs = Server.CreateObject("ADODB.Recordset")
set objRs = objConn.Execute(strsql)


questa lo presa da una lezioni di prima e l'ho leggermente modificata:

call manda_posta(email, risposta)


e adesso che abbiamo fatto tutto, il response.redirect ci rimanda al nostro file che ci mostra tutti i feedback e, se tutto ha funzionato al meglio, quello che abbiamo appena risposto non dovrebbe apparire più.

response.redirect "feedback_mostra.asp" 

else
call niente_chiave() 
end if

'--------------------------------------------------------
Sub manda_posta(email,risposta)
'--------------------------------------------------------
'Purpose: manda la email
'Date: 10 March 2001
'Commenti: 
'-------------------------------------------------------- 
Dim objMail

Set objMail = Server.CreateObject("CDONTS.NewMail")

objMail.From = "ilnostroindirizzo"
objMail.To = email
objMail.Subject = "Ilmiosito risponde"
objMail.Body = risposta

objMail.importance = 0
objMail.Send

Set objMail = Nothing
end sub
%>


Tutto qui. Non c'è male per un paio d'ore di lavoro, no? Adesso comincia a tenere il tuo portatile sul comodino così, quando ti svegli alla mattina, rispondi subito ai tuoi clienti che sono venuti durante la notte. Quindi, comincia pure a pianificare il tuo viaggio che ormai il sito te lo mantieni da dove vuoi. 

Ho messo anche un campo al feedback nel mio ufficio.asp e siccome ci comincio a lavorare dentro l'ho fatto anche un po' più bello ;o)

<% 
Option Explicit

If session("login") then
%>
<html>
<head>
<title>Ufficio</title>
</head>
<body>
<table width="95%" border="0" cellspacing="4" cellpadding="4">
<tr>

<th align="left" width="170"><img src="NFM.GIF" width="158" height="100" alt="" border="0"></th>
<th align="left" width="100%"><font size=+2 color="firebrick">Il Mio Ufficio Virtuale " o Letto? "</font>
<hr size="1" color="firebrick" width="100%"></th>
</tr>
<td></td>
<td>
<!-----------comincia News---------------------->
<table width="60%" border="0" cellspacing="1" cellpadding="0" bgcolor="red"><tr><td>
<!--tanto per fare un border rosso-->
<table width="100%" border="0" cellspacing="0" cellpadding="4" bgcolor="white">
<th align="left" bgcolor="red" colspan="2"><font color="white">News</font></th>
<tr>
<td width="40"><img src="news1.gif" width="35" height="35" alt="" border="0"></td>
<td width="100%"><a href="news.asp"><font color="red">Entra un nuovo articolo nelle News</font></a></td>
</tr>
<tr>
<td width="40"><img src="chemistry.gif" width="30" height="32" alt="" border="0"></td>
<td width="100%"><a href="mantieni_news.asp"><font color="red">Cambia o cancella un articolo nelle News</font></a></td>
</tr>
<tr>
<td></td>
</tr>
</table>

</td></tr></table>
<!-----------finisce News--------------> 

<!-----------comincia CRM---------------------->
<table width="60%" border="0" cellspacing="1" cellpadding="0" bgcolor="green"><tr><td>
<!--tanto per fare un border verde-->
<table width="100%" border="0" cellspacing="0" cellpadding="4" bgcolor="white">
<th align="left" bgcolor="green" colspan="2"><font color="white">CRM</font></th>
<tr>
<td width="40"><img src="news1.gif" width="35" height="35" alt="" border="0"></td>
<td width="100%"><a href="feedback_mostra.asp"><font color="green">Rispondi al feedback</font></a></td>
</tr>
<tr>
<td></td>
</tr>
</table>

</td></tr></table>
<!-----------finisce CRM--------------> 
</td>
</tr>
</table>
</body>
</html>
<%
else
response.redirect "login.asp"
end if
%>

Vogliamo degli altri in Ufficio?




 

Adesso abbiamo le News e il Feedback. Il concetto delle News lo possiamo applicare in molte maniere. Potremmo permettere, ad esempio, che i nostri utenti le inseriscano da soli. Diciamo che invece di news sono degli avvenimenti pubblici ed è nell'interesse del cliente mantenerli in regola. Credi di saperlo fare questo? 
Cosa bisogna fare?

1. costruire una form per l'applicazione del cliente
2. entrare I dati del cliente nelil database
3. generare la password e mandargliela per email 
4. provvedere il cliente con un attrezzo per mantenere le sue pagini (solo le sue)

Ecco la form che non presenta nessun problema

<%
'--------------------------------------------------------
'Purpose: Raccogli i dati del cliente
'Date: 7 Aprile 2001
'Commenti: 
'--------------------------------------------------------
%>
<html>
<head>
<title>Dati del cliente</title>


Qui adoperiamo Javascript per validare il contenuto della form. Fare queste cose sul browser è molto più logico che dover fare un altro salto sul server

<script language="JavaScript">
<!--
function submitIt(theform) {

if (theform.nome.value == "") {
alert("Per favore entra il tuo nome...") 
theform.nome.focus()
}
if (theform.cognome.value == "") { 
alert("Per favore entra il tuo cognome...") 
theform.cognome.focus() 
return false
}
if (theform.email.value == "") { 
alert("Per favore entra il tuo email...") 
theform.email.focus() 
return false


-->
</script>
</head>


e qui mettiamo semplicemente il focus sulla prima text box, ossia il nome

<body OnLoad="Javascript:document.frm_client.nome.focus();">
<div align="center">


Quando viene attivato l'evento OnSubmit chiamiamo la routine in Javascript che controllo se le text boxes che vogliamo noi sono state riempite o no.

<form ACTION="metti_aggiungi_cliente.asp" name="frm_cliente" method="post" OnSubmit="return submitIt(this)">
<table width="60%" border="0" cellpadding="6" cellspacing="0" bgcolor="darkorange">
<tr>
<th align=left><font color="white">Per favore entra i necessari dati:</font></th>
</tr>
<tr>
<td align=center>
<table width="100%" border="0" cellpadding="6" cellspacing="6" bgcolor="#ffcc99">
<tr>
<td align="right">Nome:</td>
<td><input type="text" name="nome" size=20></td>
</tr>
<tr>
<td align="right">Cognome:</td>
<td><input type="text" name="cognome" size=20></td>
</tr>
<tr> 
<td align="right">Your email:</td>
<td><INPUT TYPE="Text" name="email" size=40></td>
</tr>
</table>
</td>
</tr>
<tr> 
<td align="center"><INPUT TYPE="Submit" name="submit" value="Manda">
<input type="Reset" value="Cancella"></td>
</tr>
</table>
</form>
</div>

</body>
</html>


Ed ecco metti_aggiungi_cliente.asp che 
1) raccoglie i dati 
2) genera la password 
3) inserisce i dati nel database
4) manda un email al cliente

<%
Option Explicit
'------------------------------------------------------------------------
'Description : raccoglie i dati del cliente
'Comments : 
'Date Built : 7 Aprile 2001
'------------------------------------------------------------------------
Dim nome, cognome, email, password, data_ricevuto
Dim strConn, objConn, objRs, strsql
%>
<!--#include file="adovbs.inc"-->
<%
'costruisci password
password = genera_pwd()

'vendemmia la form
nome = Request.Form("nome")
cognome = Request.Form("cognome")
email = Request.Form("email")
data_ricevuto = Date()

'metti dentro al database
strConn = Application("dbconn")

strsql = "INSERT INTO tbl_login (nome, cognome, login1, password1, data_ricevuto, email)" 
strsql = strsql & " Values('" 
strsql = strsql & nome & "','"
strsql = strsql & cognome & "','"
strsql = strsql & nome & "','"
strsql = strsql & password & "',#"
strsql = strsql & data_ricevuto & "#,'"
strsql = strsql & email & "')"
%>


Non so se hai notato che ho dovuto cambiare il nome del login e password nella tbl_login. Li ho semplicemente cambiati con un 1. Il perché? Quando ho usato questa pagina mi ha data un errore nella query ma la sintassi era giusta. Cosi ho fatto un <% response.write strsql %> ho guardato alla query, l'ho inserita nel motore query di Access e mi ha funzionato alla perfezione. Deve avere a che fare con parole riservate. È sempre meglio usare notazioni giuste per le variabili. 


<%
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn

Set objRs = objConn.Execute(strsql)

objConn.close
set objConn = Nothing

'molte grazie...
Response.write "<div align=center>"
Response.write "<br><br><br><br><br><br>"
Response.write "<font size=+1 color=midnightblue face=verdana>" 
Response.write "Il tuo nome è stato aggiunto al nostro database.<br>"
Response.write "La password ti arrivera' in un minuto... via email. <br>"
Response.write "Grazie per l'aiuto."
Response.write "</font></div>"

'e via la posta
call manda_posta(nome,password,email)

'pulisci e chiudi
objRs.close
Set objRs = Nothing

'--------------------------------------------------------------------
Function genera_pwd()
'---------------------------------------------------------------------
' Description : Generates a password
' Date Created : 11-04-2001
' Comment : 
'---------------------------------------------------------------------
Dim i, x
Dim chars(36)
Dim pwd(8)

x = 0 
'a-z
for i = 97 to 122
chars(x) = chr(i)
x = x + 1
next
'0-9
for i = 48 to 57
chars(x) = chr(i)
x = x + 1
next
password = "" 
For i = 1 to 8
Randomize
password = password & chars(Int(UBound(chars) - LBound(chars) + 1) * Rnd + LBound(chars))
next
genera_pwd = password
end Function
'------------------------------------------------------

Sub manda_posta(nome,password,email)
'-------------------------------------------------------
'Purpose: manda la email
'Date: 10 March 2001
'Commenti: 
'-------------------------------------------------------- 

Dim objMail, messaggio

messaggio = "Grazie per ......"
messaggio = messaggio & VBcrlf & "login = " & nome 
messaggio = messaggio & VBcrlf & "password = " & password

Set objMail = Server.CreateObject("CDONTS.NewMail")

objMail.From = "latuaemail"
objMail.To = email
objMail.Subject = "Grazie per..."
objMail.Body = messaggio

objMail.importance = 0
objMail.Send

Set objMail = Nothing
end sub
%>


L'unica cosa da fare qui è costruire le pagine che permettono ai tuoi utenti di mantenere i loro dati.
Di sicuro questo ormai lo puoi fare anche da solo. In pratica è quasi uguale alle news. L'unica cosa è che devi organizzare le query con (where id = id) così che ogni cliente ha accesso alla sua area soltanto. Forse è sempre meglio se passi questo valore nell'oggetto Request.QueryString da una pagina all'altra.

 

Allora diamogli le chiavi e facciamoli lavorare




 

Tanto per finire questo tutorial e per essere sicuro che mi hai seguito fino a qui, facciamo anche questo piccolo programma. Cosa vogliamo fare? Adesso che abbiamo degli impiegati virtuali, dobbiamo dargli accesso al nostro ufficio virtuale.

Questo è facile, abbiamo già il nostro login e dobbiamo solo presentarlo all'utente. Poiché i suoi dati sono già inseriti dovrebbe essere in grado di eseguire il login senza problemi. 

Prima però bisognerebbe considerare questo problema. Non tutti i nostri impiegati virtuali sono uguali quindi bisogna che li classifichiamo in modo da dargli gli strumenti di cui hanno bisogno per lavorare. 

Mettiamo un nuovo campo in tbl_login e chiamiamolo permesso. Io l'ho reso numerico in modo da ottenere:

0 = permetti tutto
1 = permetti solo le news

Se vuoi lo puoi rendere anche testuale specialmente se dovessi aver bisogno più di 2 livelli.

Ora cambiamo il necessario in Login.asp:

<% strsql = "Select id, login, password FROM tbl_login" %>


questa linea deve cambiare. Adesso abbiamo bisogno di sapere non solo id, login, password ma anche che tipo di permesso ha l'utente. In più possiamo anche prendere tutti i dettagli in modo da poterlo chiamare per nome. Ad esempio:

<% strsql = " Select * FROM tbl_login" %>


poi login.asp cambia così:

<%
If objRs.EOF then
'Non è valido, mandalo indietro
response.redirect "login.asp"
Else
'è valido, fallo entrare
session("login") = True

'raccogli tuttle le variabili di cui abbiamo bisogno
id = objRs("id")
nome = objRs("nome")
cognome = objRs("cognome")
email = objRs("email")
permesso = objRs("permesso")

objRs.close
Set objRs = Nothing
response.redirect "ufficio.asp" 
end if
%>


A questo punto vediamo un paio di scelte che dipendono dal tipo di sito con cui lavoriamo.
Siccome vogliamo mantenere queste variabili durante tutto il tempo che il nostro impiegato rimane nel nostro ufficio virtuale, sarebbe molto comodo se rendessimo le sessioni variabili così che le possiamo chiamare da qualunque pagina:

<%
session("id") = id
session("nome") = nome
session("cognome") = cognome
session("email") = email
session("permesso") = permesso
%>


Se prendiamo questa strada, ci rendiamo la vita molto più semplice ma, poiché IIS mantiene uno spazio di memoria per ogni sessione che apre i costi per mantenere queste variabili crescono proporzionalmente con il numero di sessioni che apriamo o, per dirlo in un'altra maniera, il numero di utenti che adoperano il nostro sito.

Ne segue che se diventiamo vittime del nostro successo, che spesso capita con siti scritti bene e apprezzati dal pubblico, saremmo forzati a cambiare questo programma per tenere conto delle risorse sulla memoria del nostro server.

Questo problema si risolve facilmente usando la collezione QueryString dell'oggetto Request cambiando la linea seguente:

<% response.redirect "ufficio.asp?id=" & id & "&nome=" & nome & "&email=" & email & "&permesso=" & permesso & """  %>


così ci passiamo da pagina a pagina le variabili di cui abbiamo bisogno e le richiamiamo quando vogliamo. C'è un po' più da scrivere ma in questo modo non stressiamo la memoria del nostro IIS.

Allora ecco tutto il nostro login.asp coi cambiamenti che abbiamo fatto:

<%
Option Explicit
'--------------------------------------------------------
'Purpose: Login
'Date: 07 April 2001
'Commenti: 
'--------------------------------------------------------
Response.Buffer = True
%>
<!--#include file="adovbs.inc"-->
<%
Dim objConn, strConn, objRs, strsql
Dim submitted, login, password
Dim id, nome, cognome, email, permesso
%>
<html>
<head>
<title>Login</title>
</head>
<body bgcolor=powderblue>
<%
submitted = Request.Querystring("submitted")

If Submitted then

strConn = Application("dbconn")

login = Request.Form("login")
password = Request.Form("password")

strsql = "Select * FROM tbl_login "
strsql = strsql & "WHERE login1 ='" & login & "' AND password1 = '" & password & "'"

response.write strsql & "<br>"

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
set objRs = objConn.Execute(strsql)

If objRs.EOF then
'Non è valido, mandalo indietro
response.redirect "login.asp"
Else
'è valido, fallo entrare
session("login") = True
'raccogli tuttle le variabili di cui abbiamo bisogno
id = objRs("id")
nome = objRs("nome")
cognome = objRs("cognome")
email = objRs("email")
permesso = objRs("permesso")

objRs.close
Set objRs = Nothing
response.redirect "ufficio.asp?id=" & id & "&nome=" & nome & "&email=" & email & "&permesso=" & permesso
end if
else
'show the form
%>

<div align="center">
<form action="login.asp?submitted=true" method="post">
<table align="center" cellspacing="0" cellpadding="5" border="1" bordercolor="midnightblue" bgcolor="ivory" width="400">
<tr>
<th><font color=firebrick size=+2><b>Solo chi voglio io!</b></font></th>
</tr> 
<tr>
<td align="center" bgcolor="azure">
<%
if session("login") and Submitted then
response.redirect "login.asp" 
else
response.write "<br><br> Per favore, entra login/password. <br><br>"
end if
%>
<table>
<tr>
<td class=event>Login:</td>
<td><input type="text" name="Login" size="10" maxlength="30"></td>
</tr>
<tr>
<td class=event>Password:</td>
<td><input type="password" name="Password" size="10" maxlength="12"></td>
</tr>
</table>
<br>
<input type="submit" value="Submit">
<input type="reset" value="Cancel" Onclick="Javascript:history.go(-1)">
</td>
</tr>
</table>
</form> 
</div>

</body>
</html>

<%
end if

Response.end
Response.Clear
%>


Ed ecco anche il nuovo ufficio.asp che tiene conto del permesso dell'utente così che mostriamo gli attrezzi disponibili nel nostro ufficio in accordo col permesso del cliente. Per esempio nel mio database ho inserito un utente col permesso 1 e lo lascio lavorare con le news ma non con il feedback che non è il suo lavoro.

Ed ecco il nuovo ufficio.asp:

<% 
Option Explicit
'--------------------------------------------------------
'Purpose: Il nostro ufficio virtuale
'Date: 07 April 2001
'Commenti: aggiunto "permesso" per cliente 
'--------------------------------------------------------
response.buffer = True

'dichiariamo le variabili nuove
dim id, nome, cognome, email, permesso
%>


Qui cambiamo leggermente così che possiamo usare l'ufficio come porta di entrata. Per esempio, oltre a mettere un click sulla nostra pagina per lasciare accesso ai nostri clienti potremmo anche comunicargli: vieni direttamente a questo URL. Se non ha effettuato il login chiederemo di inserire i dati di autenticazione.

<%
If NOT session("login") then
response.redirect "login.asp"
else
'raccogliamo I dati sul cliente
id = Request.QueryString("id")
nome = Request.QueryString("nome")
cognome = Request.QueryString("cognome")
email = Request.QueryString("email")
permesso = Request.QueryString("permesso")
%>

<html>
<head>
<title>Ufficio</title>
</head>
<body>
<table width="95%" border="0" cellspacing="4" cellpadding="4">
<tr>

<th align="left" width="170"><img src="NFM.GIF" width="158" height="100" alt="" border="0"></th>
<th align="left" width="100%"><font size=+2 color="firebrick">Il Nostro Ufficio Virtuale</font>
<hr size="1" color="firebrick" width="100%"></th>
</tr>
<tr>
<td valign="top" bgcolor="#ffcc99"><font color="firebrick">
Ciao <%= nome %> ,<br>sei venuto a lavorare?<br>Se hai bisogno, chiama. 
</font></td>
<td>
<%
'e qui naturalmente non facciamo altro che controllare se l'utente ha proprio bisogno di questo strumento
if permesso <= 1 then
%> 
<!-----------comincia News---------------------->
<table width="60%" border="0" cellspacing="1" cellpadding="0" bgcolor="red"><tr><td>
<!--tanto per fare un border rosso-->
<table width="100%" border="0" cellspacing="0" cellpadding="4" bgcolor="white">
<th align="left" bgcolor="red" colspan="2"><font color="white">News</font></th>
<tr>
<td width="40">
<img src="news1.gif" width="35" height="35" alt="" border="0"></td>


naturalmente dobbiamo passare l'id alla news.asp in modo da sapere chi è che ha inserito questa news nel database e nel sito. In più bisogna mettere un campo in più nella tbl_news per sapere chi è responsabile per quel specifico pezzo. Io lo chiamo "responsabile":

<td width="100>
<a href="news.asp?id=<%=id%>&nome=<%=nome%>">
<font color="red">Entra un nuovo articolo nelle News</font></a></td>
</tr>
<tr>
<td width="40"><img src="chemistry.gif" width="30" height="32" alt="" border="0"></td>
<td width="100%">
<a href="mantieni_news.asp<%= id %>&nome=<%=nome%>">
<font color="red">Cambia o cancella un articolo nelle News</font></a></td>
</tr>
<tr>
<td></td>
</tr>
</table>

</td></tr></table>
<!-----------finisce News--------------> 
<%
end if
If permesso = 0 then
%>
<!-----------comincia CRM---------------------->
<table width="60%" border="0" cellspacing="1" cellpadding="0" bgcolor="green"><tr><td>
<!--tanto per fare un border verde-->
<table width="100%" border="0" cellspacing="0" cellpadding="4" bgcolor="white">
<th align="left" bgcolor="green" colspan="2"><font color="white">CRM</font></th>
<tr>
<td width="40"><img src="news1.gif" width="35" height="35" alt="" border="0"></td>
<td width="100%"><a href="feedback_mostra.asp"><font color="green">Rispondi al feedback</font></a></td>
</tr>
<tr>
<td></td>
</tr>
</table>

</td></tr></table>
<!-----------finisce CRM--------------> 
<%
end if
%>
</td>
</tr>
</table>
</body>
</html>
<%
end if
%>


Adesso tutto quello che c'è rimasto da fare è modificare le news in modo che ognuno è solo responsabile per i suoi pezzi. Penso che in sostanza dovrebbe tutto rimanere come prima con la piccola differenza che quando costruiamo le nostre query dobbiamo tenere conto dell'id dell'utente.

Cambiamo questa linea ed è tutto fatto:

<% strsql ="Select * from tbl_news where id = " & id & "," & "data_morto >= #" & oggi & "#" %>


adesso il cliente vede solo le sue notizie che è esattamente quello che volevamo fare.

Segue news.asp con diversi piccoli cambiamenti, ma di sicuro tu li vedi subito.

<%
Option Explicit
'--------------------------------------------------------
'Purpose: applicazione per le news
'Date: 30 March 2001
'Commenti: 
'--------------------------------------------------------
%>
<!-- la mia è nella stessa folder --> 
<!-- #include file="attrezzi_db.asp" -->
<%
Dim strConn, message
dichiare le nuove variabili id e nome
Dim titolo, sottotitolo, testo, vivo, morto, id, nome

call Main()

Sub Main()
'--------------------------------------------------------
'Purpose: la logica dell'applicazione
'Date: 29 March 2001
'Commenti: 
'--------------------------------------------------------
Dim submitted, query, form
submitted = Request.QueryString("submitted")
raccogli anche queste 
id = Request.QueryString("id")
nome = Request.QueryString("nome")

response.write id
If submitted then
call vendemmia(form)

'bisogna passargli anche l'id e spero che tutit sia ricordato di entrare il campo nell tbl_news

query = costruisci_query(titolo,sottotitolo,testo,vivo,morto,id)
strConn = Application("dbconn") 
'questa è in attrezzi_db.inc, ti ricordi? quindi ce l'abbiamo
call fai_query(strConn, query)
call quale_risultato(message)
else 
%> 
<!-- mettiamo la form qui -->


cambiato il nome. Poiché ho messo delle variabili nella vecchia news_inc ora bisogna chiamarla news_in.asp

<!-- #include file="news_in.asp"--> 
<% 
end if
end Sub

Sub vendemmia(form)
'--------------------------------------------------------
'Purpose: raccogli i dati dalla form
'Date: 29 March 2001
'Commenti: corregge il problema di &quot;
'--------------------------------------------------------
'questo Replace lo facciamo per il carattere "&quot;"
'altrimenti la Database si confonde
titolo = Replace(Request.Form("titolo"),"'","''")
sottotitolo = Replace(Request.Form("sottotitolo"),"'","''")
testo = Replace(Request.Form("testo"),"'","''")
vivo = Request.Form("vivo")

morto = Request.Form("morto") 
se non inseriamo una data di scadenza allora la facciamo durare solo un giorno 
if morto = "" then
morto = vivo
end if
end sub

'abbiamo una nuova variabile
Function costruisci_query(titolo,sottotitolo,news,vivo,morto,id)
'--------------------------------------------------------
'Purpose: costruisce la query
'Date: 29 March 2001
'Commenti: 
'--------------------------------------------------------
response.write "hellO=" & id
Dim strsql
strsql = "INSERT INTO tbl_news ( titolo, sottotitolo, testo, data_vivo, data_morto, responsabile)" 
strsql = strsql & " Values('" 
strsql = strsql & titolo & "','"
strsql = strsql & sottotitolo & "','"
strsql = strsql & testo & "',#"
strsql = strsql & vivo & "#,#"
strsql = strsql & morto & "#,'"
strsql = strsql & id & "')" 

'se hai dei guai costruendo questa, metti un
Response.Write strsql & "<br>"
'così la vedi e la puoi accomodare
costruisci_query = strsql
End Function

Sub quale_risultato(message)
'--------------------------------------------------------
'Purpose: cronaca il risultato dell query e format una risposta
'Date: 29 March 2001
'Commenti: 
'-------------------------------------------------------- 
Select case message
case "ok"
response.write "Tutto è andato bene, <br> e grazie per il pesce." 
response.write "<br><br><div align='center'><a href='JavaScript:history.back()'>Click to go back</a></div>"
case "not ok"
response.write "È un grosso disastro!
<br> Chissa cosa è successo?"
response.write "Prova a scrivere la query e altre variabili per vedere se riesci a risolvere il problema." 
response.write "<br>Anche la professione del falegname è onorevole ;o)"
response.write "<br><br><div align='center'><a href='JavaScript:history.back()'>Click to go back</a></div>" 
case else
response.write "Se sei qui è metafisica pura" 
end select

end sub 
%>


poi viene la form normale in cui ho solo messo il nome dell'utente. 
News_in.asp:

<HTML>
<HEAD>
<TITLE>News Input</TITLE>
</head>
</HEAD>

<BODY>
<FORM ACTION="news.asp?submitted=true&id=<%=id%>&nome=<%=nome%>" METHOD="post">
<div align="center">
<table border="0" width="95%" celpadding="2" cellspacing="2">
<tr>


<td><h1><%= nome %>, entra le news per oggi qui...<hr align="LEFT" size="1" width="100%" color="navy"></h1></td>
</tr>
<td align="center"><br><br>
<table width="80%" border="0" celpadding="2" cellspacing="2">
<tr>
<td>Titolo</td>
<td><INPUT NAME="titolo" TYPE="TEXT" size="80" MAXLENGTH="80"></td>
</tr>
<tr>
<td>Sottotitolo</td>
<td valign="top"><TEXTAREA NAME="sottotitolo" ROWS="3" COLS="60"></TEXTAREA></td>
</tr>
<tr>
<tr>
<td valign="top">News</td>
<td valign="top"><TEXTAREA NAME="testo" ROWS="10" COLS="60"></TEXTAREA></td>
</tr>
<tr>
<td nowrap>Data di entrata</td>
<td valign="top"><INPUT NAME="vivo" TYPE="TEXT" Value="<%= Now() %>" size="24" MAXLENGTH="24"></td>
</tr>
<tr>
<td nowrap>Data di scadenza</td>
<td valign="top"><INPUT NAME="morto" TYPE="TEXT" size="24" MAXLENGTH="24"></td>
</tr> 
<tr>
<td nowrap>URL</td>
<td valign="top"><INPUT NAME="url" TYPE="TEXT" size="24" MAXLENGTH="100"></td>
</tr> 
<tr>
<td valign="top"><b>&nbsp;</b></td>
<td>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<table width="40%" border="0" celpadding="6" cellspacing="2">
<tr> 
<td align="right"><INPUT TYPE="submit" NAME="submit" VALUE="Entra"></td>
<td align="left"><INPUT TYPE="reset" NAME="Reset" VALUE="Reset"></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</FORM>

</BODY>
</HTML>


Adesso che il nostro utente può entrare nelle News con un suo id, le possiamo anche estrarre alla stessa maniera quando vuole mantenere i suoi dati. Prendiamo il nostro vecchio file mantieni_new.asp e modifichiamolo:

<%
Option Explicit
'--------------------------------------------------------
'Purpose: mostra le news per cambiarle
'Date: 7 Aprile 2001
'Commenti: adattata per clienti con ID 
'--------------------------------------------------------
%>
<!--#include file="adovbs.inc"-->
<%
Dim objConn, strConn, objRs, strsql
dobiamo dichiararle e raccoglierle
Dim id, nome 

id = Request.QueryString("id")
nome = Request.QueryString("nome")


If Session("login") then
strConn = Application("dbconn")

'come vedi cambiamo la query con la clausola id

strsql = "Select * from tbl_news where responsabile= " & id & " order by data_morto Asc"

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConn
Set objRs = Server.CreateObject("ADODB.Recordset")

objRs.CursorLocation = adUseClient
set objRs = objConn.Execute(strsql)


response.write "<div align=center>" 
response.write "<table border='1' width='80%' cellpadding='4' cellspacing='4' bgcolor='bisquè>"
response.write "<tr><th colspan='4' align='center'><font size='+2' color='firebrick'>Mantieni le News</font></th</tr>"

Do while Not objRs.EOF
%> 
<tr>
<td width="5%"><font color='teal'><%= objRs("id") %></font></td>
<td width="75%"><font color='teal'><%= objRs("titolo") %></font></td>
<td width="10%"><a href="cambia_news.asp?id=<%= objRs("id") %>">cambia</a></td>
<td width="10%"><a href="cancella_news.asp?id=<%= objRs("id") %>">cancella</td>
</tr> 
<%
objRs.MoveNext
Loop
Response.write "</table></div>"

'quando hai tempo, metti questa in un .inc e formatala con un bel messaggio
'poi la puoi mettere dappertutto nell'ufficio
else
response.write "Mi dispiace ma questo è il mio ufficio e tu non hai la chiave..."
end if
%>


E adesso basta. Chiudiamo questo benedetto ufficio e andiamo a farci una pensata sopra.

 

Conclusione




 

Ok, io penso di fermarmi qui. Spero che tu adesso abbia appreso abbastanza per continuare a lavorare e per imparare ad adoperare questa tecnologia. In più spero che tu adesso sia in grado di identificare, disegnare e costruire gli strumenti di cui hai bisogno per il tuo lavoro.

Le regole sono semplici come hai visto. Scrivi il pseudocodice in lingua normale e poi segui con il codice.

Durante questo tutorial io ho preso molte scorciatoie. L'ho fatto più che altro per semplificare le lezioni e cercare di rimanere sul percorso di ASP. Ho persino adoperato alcuni tag HTML che sono già abolite come <font> ma, hey! non volevo cominciare a parlare di fogli di stile (CSS).

Ugualmente con l'arrivo di ASP3 ci sono molti più strumenti per connettersi con databases e per presentare il display sulla macchina del cliente.

Non li ho analizzati di proposito perché penso che è sempre meglio cominciare dal semplice. Adopera e analizza questi piccoli programmi che abbiamo scritto insieme. Vedrai che formeranno le basi di un mucchio di aggeggi che troverai utili e divertenti da costruire. E quando hai finito buttali via perché tanto il nostro lavoro è sempre così. Quello che fai oggi, domani è già obsoleto e devi ricominciare dal principio. Impara i concetti non la sintassi. La sintassi cambia ma i principi di queste tecnologie sono sempre gli stessi e quando hai imparato ASP le prossime tecnologie diventano molto più facili da usare. L'intelligenza è nascosta nei database, quando sai come mettere dentro dati, ritirarli e modificarli non c'è più limite a quello che puoi fare. 
Ricordati, il database è il tuo amico.
Buon divertimento e Auguroni.