You are on page 1of 137

Site-uri web dinamice folosind

ASP.NET
PhD. Lucian Sasu
25 mai 2009

Cuprins
1 Aplicatii Web
1.1 Pagini Web. Servere Web. Aplicatii Web . .
1.2 Modele clasice de realizare a aplicatiilor Web
1.2.1 Comunicarea cu serverul . . . . . . .
1.2.2 Limbajul HTML . . . . . . . . . . .
1.2.3 Limbajul XHTML . . . . . . . . . .
1.3 Formulare . . . . . . . . . . . . . . . . . . .
1.3.1 Text . . . . . . . . . . . . . . . . . .
1.3.2 Password . . . . . . . . . . . . . . .
1.3.3 Checkbox . . . . . . . . . . . . . . .
1.3.4 Butoane radio . . . . . . . . . . . . .
1.3.5 Butonul de Submit . . . . . . . . . .
1.3.6 Butonul de reset . . . . . . . . . . .
1.3.7 File . . . . . . . . . . . . . . . . . . .
1.3.8 Campuri ascunse . . . . . . . . . . .
1.3.9 Image . . . . . . . . . . . . . . . . .
1.3.10 Butoane . . . . . . . . . . . . . . . .
1.3.11 Textarea . . . . . . . . . . . . . . . .
1.3.12 Select . . . . . . . . . . . . . . . . .
2 ASP.NET
2.1 Generalitati . . . . . . . . . . . . . . .
2.1.1 Ce e gresit la ASP-ul clasic? . .
2.1.2 Ce aduce ASP.NET? . . . . . .
2.2 Despre ASP.NET 3.5 . . . . . . . . . .
2.3 Tipuri de siere n ASP.NET . . . . .
2.4 Modelul de cod . . . . . . . . . . . . .
2.5 Controale Web si controale HTML . .
2.6 Forme Web . . . . . . . . . . . . . . .
2.6.1 Postback . . . . . . . . . . . . .
2.6.2 Mentinerea starii prin Viewstate
3

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

7
7
10
11
14
14
16
19
20
20
21
21
22
22
22
23
24
24
25

.
.
.
.
.
.
.
.
.
.

27
27
27
29
30
30
32
36
37
37
39

CUPRINS
2.6.3
2.6.4

Utilitatea conceptului de controale . . . . . . . . . . . 41


Ciclul de viata al unei pagini (varianta sumara) . . . . 43

3 Forme Web, gestiunea st


arii
3.1 Forme Web (continuare) . . . .
3.1.1 Colectia de controale din
3.1.2 Request . . . . . . . . .
3.1.3 Response . . . . . . . .
3.1.4 Server . . . . . . . . . .
3.2 Tipuri de controale server . . .
3.2.1 Controale server HTML
3.2.2 Controale Web server . .
3.3 Gestiunea starii n ASP.NET . .
3.3.1 ViewState . . . . . . . .
3.3.2 Query String . . . . . .
3.3.3 Cross page posting . . .
3.3.4 Cookies . . . . . . . . .
3.3.5 Sesiunea . . . . . . . . .
3.3.6 Application . . . . . . .

. . . .
pagina
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

4 Validatoare, manipulatoare, controale


4.1 Controale de validare a intrarii . . . . . . . . . . .
4.1.1 Pasii de validare . . . . . . . . . . . . . . .
4.1.2 Clasa BaseValidator . . . . . . . . . . .
4.1.3 Validatorul RequiredFieldValidator . .
4.1.4 Validatorul RangeValidator . . . . . . . .
4.1.5 Validatorul CompareValidator . . . . . .
4.1.6 Validatorul RegularExpressionValidator
4.1.7 Controlul CustomValidator . . . . . . . .
4.1.8 Controlul ValidationSummary . . . . . . .
4.1.9 Grupuri de validare . . . . . . . . . . . . .
4.2 Manipulatoare HTTP . . . . . . . . . . . . . . . .
4.3 Controale utilizator . . . . . . . . . . . . . . . . .
5 Teme, pagini master, navigare
5.1 Cascading Style Sheets . . . .
5.2 Teme . . . . . . . . . . . . . .
5.3 Pagini master . . . . . . . . .
5.4 Navigare . . . . . . . . . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

47
47
47
47
48
48
49
50
53
53
55
57
58
58
59
59

.
.
.
.
.
.
.
.
.
.
.
.

61
61
62
62
63
64
65
66
66
67
67
68
71

.
.
.
.

73
73
74
77
83

CUPRINS
6 Legarea la date
6.1 Legarea la date simple . . . . . . . . .
6.2 Legarea la date multiple . . . . . . . .
6.3 Controale de date bogate . . . . . . .
6.4 Controale de surse de date . . . . . . .
6.5 Ciclul de viata al unei pagini Web . . .
6.6 Sursa de date SqlDataSource . . . . . .
6.6.1 Selectarea de nregistrari . . . .
6.6.2 Dezavantaje ale SqlDataSource
6.7 Sursa de date ObjectDataSource . . . .

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

85
86
88
90
91
91
93
93
94
94

7 Controale de lucru cu datele


7.1 Controlul GridView . . . . . . . . . . .
7.1.1 Formatare . . . . . . . . . . . .
7.1.2 Stiluri . . . . . . . . . . . . . .
7.1.3 Selectarea de linie din GridView
7.1.4 Sortare . . . . . . . . . . . . . .
7.1.5 Paginare . . . . . . . . . . . . .
7.1.6 Template-uri . . . . . . . . . .
7.2 Controalele FormView, DetailsView . .

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

97
97
97
98
98
98
99
99
99

. . . . . .
. . . . . .
. . . . . .
paginilor .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .

101
101
103
105
105
108
109
111
116
117
117
118
118

8 JavaScript si Ajax
8.1 Elemente de baza JavaScript . . . . . . . . . . . . .
8.2 Blocuri de script . . . . . . . . . . . . . . . . . . .
8.3 Manipularea elementelor HTML . . . . . . . . . . .
8.4 Utilizare de JavaScript pentru ncarcare asincrona a
8.5 Includerea blocurilor JavaScript din code-behind . .
8.6 Atacuri de injectare de script . . . . . . . . . . . .
8.7 JavaScript pentru controale utilizator . . . . . . . .
8.8 Ajax . . . . . . . . . . . . . . . . . . . . . . . . . .
8.8.1 Obiectul XMLHttpRequest . . . . . . . . . .
8.8.2 Trimiterea cererii . . . . . . . . . . . . . . .
8.8.3 Procesarea raspunsului . . . . . . . . . . . .
8.9 Un exemplu Ajax . . . . . . . . . . . . . . . . . . .

9 ASP.NET membership
123
9.1 Congurarea autenticarii prin forme . . . . . . . . . . . . . . 125
9.2 Crearea sursei de date . . . . . . . . . . . . . . . . . . . . . . 126
9.3 Congurarea stringului de conexiune si a furnizorului de membership 126
9.4 Crearea de utilizatori . . . . . . . . . . . . . . . . . . . . . . . 131
9.5 Crearea unei pagini de login . . . . . . . . . . . . . . . . . . . 132

CUPRINS

9.6

9.5.1 Controlul Login . . . . . . . . . . . . . . . . .


9.5.2 Controlul LoginStatus . . . . . . . . . . . . .
9.5.3 Controlul LoginView . . . . . . . . . . . . . .
9.5.4 Controlul PasswordRecovery . . . . . . . . .
9.5.5 Controlul ChangePassword . . . . . . . . . . .
Gestiunea utilizatorilor prin API-ul de membership
9.6.1 Aducerea listei de utilizatori . . . . . . . . . .
9.6.2 Obtinerea detaliilor despre un utilizator . . .
9.6.3 Modicarea datelor unui utilizator . . . . . .
9.6.4 Crearea si stergerea unui utilizator . . . . . .
9.6.5 Validarea unui utilizator . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

132
133
133
133
134
134
134
135
135
135
136

Capitolul 1
Aplicatii Web
1.1

Pagini Web. Servere Web. Aplicatii Web

In ingineria softului, o aplicatie Web1 este un program care este stocat


pe un server Web si accesat prin intermediul unui browser folosind reteaua.
La un capat al acestei comunicatii se aa un server (program dedicat)
care accepta interogari, formulate prin protocolul HTTP; serverul poate sa
serveasca pagini web statice (csiere scrise n limbaj HTML) sau resurse
statice (imagini, siere PDF etc). Exemple de servere folosite n prezent:
Apache - cel mai larg raspandit, la ora actuala; poate rula pe o multitudine de sisteme de operare; conform Netcraft, n ianuarie 2009, 50.33%
din site-uri rulau Apache
IIS = Internet Information Services, creat de catre Microsoft pentru
a folosit pe sistemele de operare Windows; disponibil pe Windows
2000 (IIS 5), Windows XP Professional (IIS 5.1), Windows Server 2003
(IIS 6), Windows 2008 (IIS 7.0 si 7.5), Windows Vista anumite versiuni
(IIS 7.0). IIS este folosit n dezvoltarea aplicatiilor ASP.NET. Conform
Netcraft, n luna precizata mai sus 31.61% din site-uri rulau o varianta
de IIS.
Varianta cea mai simpla este aceea n care se servesc doar resurse statice
- cum ar un site de prezentare a unei institutii, prezentari de rezultate
sau statistici etc, deci situatii n care continutul se schimba relativ rar. Paginile Web sunt scrise ntrun limbaj numit HTML. Figura 1.1 ilustreaza
arhitectura unui web server si legatura cu browserul.
Exista nsa situatii n care continutul se modica foarte des de exemplu
pentru pagina unui magazin de carti, n care apar permanent noi carti, altele
1

In original: Web application sau webapp.

CAPITOLUL 1. APLICATII
WEB

Figura 1.1: Arhitectura unui server web simplu


se epuizeaza, noi categorii de literatura, preturi etc. A crea pagini web statice
nu este o solutie, deoarece atat de multe modicari nu pot operate n timp
real de catre o persoana. Ca atare, serverul de Web poate de asemenea sa
gazduiasca o aplicatie scrisa ntr-un limbaj (alegeri populare: PHP, Java,
ASP.NET cu C#/VB.NET etc) care produce pagini Web dinamice; aceasta
aplicatie poate sa preia date dintr-o sursa de date - de regula, o baza de date
relationala - si sa produca pagini HTML actualizate. Modicarea datelor
este reectata instantaneu ntr-o pagina ceruta dupa ce aceasta modicare
s-a facut. Intrucat continutul paginilor se genereaza dinamic, paginile se mai
numesc si dinamice.
Exemple clasice de aplicatii Web sunt:
webmail permite citirea postei electronice folosind o interfata web;
exemple: Yahoo! Mail, Google Mail;
magazine electronice, site-uri de licitatii permit prezentarea de produse; utilizatorul poate sa cumpere, daca acest serviciu este prezentat;
exemplu: Amazon, eBay;
forumuri permit membrilor unei comunitati sa comunice; mesajele
sunt vizibile de catre totti membrii comunitatii si pot sa primeasca
raspuns, de asemenea tot pe forum; exemplu: Comunitatea SQL Server;
motoare de cautare: Google, Clusty;
site-uri ce ofera informatii sau predictii: mersul trenurilor, predictii
despre evolutia pretului la bilete de avion.

1.1. PAGINI WEB. SERVERE WEB. APLICATII


WEB

La celalalt capat se aa un browser (e el Internet Explorer, Mozilla


Firefox, Safari, Opera sau Google Chrome - cele mai utilizate la ora actuala).
Tot ceea ce trebuie sa faca utilizatorul este sa indice care este adresa de Web
la care se aa pagina de interes.
Acest tip de comunicare este numit clientserver: clientul este browserul, serverul este cel care raspunde prin furnizarea unei pagini web (daca
se poate). Browserul este de fapt un asa numit thin client (client subtire);
el nu necesita instalare locala a unor componente (cu exceptia browserului,
utilizabil pentru toatre site-urile), nici drepturi de administrator pe masina
pe care lucreaza; tot ceea ce trebuie sa faca este sa formuleze cereri catre
server, pe baza actiunilor utilizatorului uman si sa primeasca raspunsul de
la server, pentru a-l nfatisa sub forma unei pagini. Simplitatea modului de
operare precum si lipsa unor manevre complicate de instalare de catre utilizator fac aceast tip de aplicatii extrem de populare. Se mai considera aici si
omniprezenta browserelor un aspect care a contribuit decisiv la acceptarea
pe scara larga a aplicatiilor web.
Tot ca un avantaj al acestor aplicatii web ar faptul ca daca se doreste
schimbarea unei parti din aplicatii, aceasta modicare se face ntr-un singur
loc pe server. Clientul (browserul) este insensibil la aceasta manevra si
nu trebuie actualizat n niciun fel. Este o uriasa diferenta fata de tehnologia thick client (client gras) prin care utilizatorul primea un kit de instalare
pentru calculatorul lui, iar aplicatia nou instalata se conecta la sever; modicarea aplicatiei putea sa nsemne dezinstalarea versiunii vechi si instalarea
celei noi, cu potentiale pericole: versiuni incorecte de siere DLL (asa numitul DLL hell).
In sfarsit, trebuie spus ca nu conteaza pe ce fel de platforma sau sistem de
operare ruleaza browserul, deoarece paginile Web reprezinta doar text care
sunt ntelese de catre orice sistem. In paranteza e spus, exista totusi mici
diferente ntre modul n care browserele deseneaza pagina pe ecran, datorita
faptului ca HTML reprezinta niste specicatii despre cum ar trebui sa e
desenat un anumit cod HTML, dar nu poate obliga pe nimeni.
Ca un neajuns al acestui tip de aplicatii: daca reteaua devine nedisponibila, aplicatia web nu poate accesata. Rezolvarea acestei situatii se face
printr-ul al treilea tip de aplicatii (pe langa cele thin si thick): smart applications. De exemplu, un client de email de tipul Outlook sau Mozilla Thunderbird
care poate sa lucreze si deconectat de la retea (citire de emailuri, stergere,
pregatire de emailuri pentru a trimise, catare etc). Subiectul nu este tratat
n acest curs.

10

CAPITOLUL 1. APLICATII
WEB

1.2

Modele clasice de realizare a aplicatiilor Web

Modelul de realizare a aplicatiior Web a cunoscut o intreaga evolutie a


tehnologiilor de programare la nivel de server. Putem enumera astfel:
1. solutia CGI (Common Gateway Interface) reprezinta o serie de scripturi executate pe serverul web. Acestea pot scrise n orice limbaj
de programare (interpretat sau compilat) cu respectarea urmatoarelor
restrictii: programul scrie datele la iesirea standard si genereaza antete care permit browserului sa interpreteze corect iesirea scriptului,
conform specicatiilor HTTP. Se pot folosi limbaje precum bash, Perl,
C/C++, Delphi. Neajunsul CGI-urilor l reprezinta faptul crearii unui
nou proces pe serverul Web pentru ecare cerere, ceea ce la un numar
mare de cereri este prohibitiv.
2. solutia ISAPI (Internet Server API) reprezinta o alternativa CGI pe
platforma Windows. Dezvoltatorii Win32 pot scrie un program care sa
comunice direct cu aceasta interfata pentru a face orice lucru posibil cu
CGI, pot folosi ISAPI pentru a obtine date din formulare si pentru a
trimite continut HTML la client. Codul la nivel de server poate scris
n oricare limbaj cu suport pentru DLL-uri Windows, precum C/C++,
Visual Basic, rezultatul compilarii ind un sier .dll. Fata de CGI,
ISAPI ruleaza n acelasi spatiu de adrese cu serverul HTTP, are acces
la toate resursele serverului HTTP, pot incluse mai multe task-uri
ntr-un .dll si nu creeaza procese aditionale pentru rezolvarea cererilor
clientilor Web.
3. solutia PHP (1994) sau ASP (1996) marcheaza un salt n dezvoltarea
aplicatiilor Web. Desi difera din punct de vedere al sintaxei, ambele
limbaje sunt interpretate, codul lor ind stocat n siere externe cu
extensia .php/.asp. De fapt, ASP nu ofera un limbaj nou, ci se bazeaza pe limbajele VBScript si JScript. Un sier PHP/ASP poate
combinat cu date de tip text, marcatori HTML si comenzi script, n
momentul executiei, n urma cererii unui client Web, sierul este procesat, ecare script din cadrul lui este interpretat si rezultatul executiei
este ntrodus napoi n sierul static HTML nainte ca rezultatul sa e
trimis catre browser. Mai mult, n sprijinul programatorului, limbajele
pun la dispozitia acestuia o serie de metode si obiecte care usureaza lucrul cu cookie-uri, cu bazele de date, care preiau elegant intrarile unui
formular HTML si le proceseaza pe server, care preiau informatii despre utilizator (clientul Web), care trimit informatii la utilizator, care

1.2. MODELE CLASICE DE REALIZARE A APLICATIILOR

WEB 11
stocheaza informatii despre sesiunea unui utilizator, care partajeaza
informatii ntre utilizatorii unei aplicatii etc.
4. JSP (Java Server Pages) face parte din familia Java si reprezinta o
tehnologie care permite crearea de aplicatii Web independente de platforma. JSP separa interfata utilizator de continutul generat dinamic
permitand schimbarea ntregului sablon al site-ului WEB fara a altera informatiile asate. Tehnologia utilizeaza marcatori XML si scripturi scrise n limbajul de programare Java pentru a incapsula logica
aplicatiei care genereaza continutul paginilor WEB. JSP-urile sunt o
extensie a tehnologiei Java Servlet. Servlet-ele sunt independente de
platforma 100% si reprezinta module la nivel de server care se integreaza
n cadrul unei aplicatii Web si care pot utilizate pentru a extinde
capabilitatile unui server WEB. Tehnologia JSP si servlet-urile ofera
o alternativa pentru crearea aplicatiilor WEB fata de alte limbaje de
scripting/programare a aplicatiilor WEB, oferind independenta de platforma, performanta, separarea logicii aplicatiei de partea de interfata
utilizator, administrare usoara si extensibilitate.
Punctele de mai sus au n comun faptul ca serverul Web prezinta o
interfata de comunicare cu procese externe. Separarea software-ul n diferite
procese ofera avantajul de modularizare si usureaza procesul de integrare,
n acelasi timp extinzand functiile web server-ului. Aceste procese externe
realizeaza componenta logica a activitatii. Conguratia descrisa este redata
n gura 1.2.
Figura 1.3 arata modul n care Serverul IIS utilizeaza ASP.NET pentru a
servi pagini web dinamice; mai departe, codul ASP.NET este responsabil de
a lua legatura cu surse de date pentru a furniza continutul actual al paginilor
dinamice.

1.2.1

Comunicarea cu serverul

Paginile web sunt de obicei transmise si primite prin intermediul Internetului via HTTP2 (nesecurizat) sau HTTPS3 (securizat). Dezvoltarea protocolului HTTP a fost supervizata de catre World Wide Web Consortium,
versiunea actuala la care s-a ajuns este HTTP 1.1.
HTTP este un standard care permite crearea de cereri si raspunsuri ntre
un client si un server. Clientul - de regula un browser, dar poate sa e si un
robot de descarcare a paginilor sau o aplicatie utilizator - face o cerere catre
2
3

Hypertext Transfer Protocol.


Secure HTTP.

12

CAPITOLUL 1. APLICATII
WEB

Figura 1.2: Server Web cu interfata spre procese externe.

Figura 1.3: Server IIS folosind ASP.NET pentru generarea de pagini Web
dinamice

1.2. MODELE CLASICE DE REALIZARE A APLICATIILOR

WEB 13
un sever, folosind o adresa web. De regula, aceasta cerere HTTP (protocol la
nivelul aplicatie din stiva de protocoale TCP/IP) se foloseste de o conexiune
TCP; portul spre care se face cererea este 80, implicit folosit pentru HTTP.
Cand primeste cererea, serverul raspunde cu:
un cod de stare(de exemplu, HTTP/1.1 200 OK daca resursa ceruta
este disponibila); o lista a codurilor este data n [1], [4].
un mesaj care este resursa ceruta (pagina web sau imagine sau document etc), sau un mesaj de eroare sau alta informatie
Browserul primeste aceste raspunsul de la server si l aseaza; e de la sine
nteles ca browserul trebuie sa implementeze cat mai del acest protocol.
Mai n detaliu, o cerere arata astfel:
linie de cerere, prevum GET /images/logo.gif HTTP/1.1, care cere o
resursa numita /images/logo.gif de pe server
antete, precum Accept-Language: en
o linie goala
un mesaj optional
Cele mai importante metode de cerere prin care un client solicita ceva de
la server sunt: get si post. Acestea vor exemplicate n sectiunea 1.3.
Un aspect esential al comunicaarii prin HTTP este nsa faptul ca HTTP
este un protocol fara stare. Asta n seamna ca ori de cate ori un client
efectueaza o cerere catre un server, acesta raspunde cererii dupa care uita
tot ceea ce a comunicat cu clientul; serverul nu mentine nicio legatura cu
browserul si nu mentine resursele necesare pentru a raspunde clientului (cu
o exceptie minora, mecansimul de keep-alive care permite reutilizarea unei
conexiuni pentru alte cereri); daca apar modicari ale paginii sau a surselor
de date pe baza carora s-a construit pagina, atunci browserul nu este notificat
n niciun fel.
In acest mod serverul, netinand resurse ocupate dupa efectuarea raspunsului,
poate sa e utilizat de cat mai multi clienti simultan. Trasatura mentionata
trebuie privita ca o caracteristica voita a protocolului si nu ca o lipsa.
Mentinerea starii dintre cereri consecutive venite de la acelasi client este
totusi dorita de catre utilizatori sau programatori n majoritatea cazurilor
si acest lucru se poate emula prin utilizarea de cookieuri, campuri ascunse,
sesiuni.

14

CAPITOLUL 1. APLICATII
WEB

1.2.2

Limbajul HTML

Limbajul HTML4 este limbajul predominant folosit pentru crearea paginilor Web. El descrie structura, continutul si modul de aparitie al unei
pagini; poate sa includa referinte catre imagini, legaturi catre alte pagini,
frame-uri, formulare etc. Un exemplu simplu este:
<html>
<head>
<title>Hello HTML</title>
</head>
<body>
<p>Hello World!!</p>
<a href="http://google.com" target="_blank">Google is
your friend</a>
</body>
</html>
Continutul unui document HTML care dupa cum se observa, este un
document de tip text se creeaza pe baza unor elemente (<p>, <a> etc)
care sunt denite de catre limbaj. Un element are de regula o eticheta de
deschidere si una de nchidere (dar n HTML acest lucru nu e ntotdeauna
cerut); elementele pot avea atribute specicate prin nume si carora li asociaza
valori:
<span id="anId" class="aClass" style="color:blue;"
title="Hypertext Markup Language">HTML</span>
Un tutorial bun pentru ncepatori se gaseste la W3Schools.com. De exemplu, pentru includerea unei imagini se foloseste secventa:
<img src="boat.gif" alt="Big Boat">
Browserul, dupa primirea sierului HTML va efectua o parsare a codului;
la ntalnirea elementului img se face o cerere de tip GET pentru a obtine
imaginea de pe server.

1.2.3

Limbajul XHTML

Una din criticile care sau adus lui HTML este ca permite combinarea
continutului efectiv al unei pagini cu indicatii despre cum sa arate acest
4

Hypertext Markup Language

1.2. MODELE CLASICE DE REALIZARE A APLICATIILOR

WEB 15
continut n pagina. Suplimentar, faptul ca n HTML nu se respecta niste
reguli de buna formare face parsarea continutului greoaie si poate duce la
diferente. S-a dorit obtinerea unui limbaj pentru care interpretarea sa e mai
usoara, sa se poata separa structura de continut si de asemenea sa semene
nca cu limbajul HTML cu care creatorii de pagini web erau obisnuiti. Prin
preluarea trasaturilor limbajului XML s-a ajuns la realizarea unui limbaj
hibrid XHTML5 . Chiar daca mai exista pagini scrise n limbaj HTML,
exista o presiune constanta de a produce numai continut XHTML; chiar si
uneltele de dezvoltare se conformeaza acestei tendinte.
Implicit, continutul generat de ASP.NET este de tip XHTML. Asta nseamna
ca elementele de marcare satisfac regulile:
etichetele si numele de atribute trebuie sa e scrise cu litere mici
toate elementele trebuie sa e nchise, e cu un tag (eticheta) de nchidere
dedicat (<p></p>) e folosind un tag gol care se nchide singur (<br />).
toate atributele trebuie sa aibe valorile incluse ntre ghilimele sau apostroafe (id="errorLabel").
atributul id trebuie sa e folosit n locul atributului name (dar controalele ASP.NET generate vor avea amandoua aceste atribute, din motive
de compatibilitate cu codul JavaScript existent).
elementele trebuie sa e imbricate corect: <p><a href="...">..</a></p>
si nu <p><a href="...">..</p></a>.
documentele XHTML trebuie sa aibe un unic element radacina; acesta
este dat de eticheta html.
XHTML de asemenea nlatura suportul pentru cateva mecanisme existente n HTML, precum frame-urile sau precizari stilistice care nu utilizeaza
CSS, sau folosirea atributului target pentru link-uri.
Orice document XHTML trebuie sa nceapa cu o declaratie de tip de document (vezi [3], sectiunea de DTD), care deneste tipul de XHTML folosit.
Pentru a specica varianta XHTML 1.1 se foloseste:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
iar elementul radacina are forma:
5

Extensible HTML

16

CAPITOLUL 1. APLICATII
WEB

<html xmlns="http://www.w3.org/1999/xhtml" >


...
</html>
adica se cere declararea unui spatiu de nume.
Exista posibilitatea de a nu urma specicatiile stricte ale lui XHTML 1.1
si a folosi n schimb niste canoane mai relaxate. de exemplu, se poate utiliza
XHTML 1.0 tranzitional care impune regulile structurale din XHTML dar de
asemenea permite folosirea mecanismelor de formatare care au fost nlocuite
n XHTML 1.1 cu stiluri CSS. Declaratia de tip de document arata astfel:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Chiar si aceasta varianta poate parea prea stricta, deoarece mpiedica
utilizarea frame-urilor. Daca se doreste utilizarea acestora cu regulile date
de XHTML atunci se poate folosi XHTML 1.0 frameset declarat ca:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
Modul n care se genereaza continutul unei de catre ASP.NET este dependent de facilitatile pe care le are browserul care a facut cererea.

1.3

Formulare

Formularul reprezinta modalitatea cea mai utilizata de trimitere de informatii


dinspre browser spre server. Formularul contine elemente care de regula suporta specicarea de valori de catre utilizator (cum ar numele si parola pe
un formular de loginare, sau raspunsurile la un test grila). In momentul n
care se doreste, formularul adica setul de input-uri utilizator este trimis
catre server. Demn de mentionat este ca daca formularul contine si alte elemente (imagini, link=uri, text etc) acestea nu sunt trimise la server, deoarece
ele nu poarta informatie de la utilizator ci au ramas nemodicate.
Un formular este denit cu eticheta form:
1
2
3
4
5
6

<form name="myForm" method="get" action="default.aspx"


id="myForm">
Nume: <input name="txtNume" type="text"
id="txtNume" />
<br />
Parola: <input name="txtParola" type="password"

1.3. FORMULARE
7
8
9
10
11

17

id="txtParola" />
<br />
<input type="submit" name="butonTrimitere"
value="Trimite" id="butonTrimitere" />
</form>

(elementele de tip input sunt prezentate n cele ce urmeaza).


Pagina desenata n browser arata ca n gura 1.4.

Figura 1.4: Pagina web cu formular


Atributul action arata care este pagina catre care se va trimite continutul
formularului. In exemplul de mai sus este vorba de pagina default.aspx
aata pe acelasi server.
Atributul method arata care din metodele GET (implicita) si POST sunt
folosite pentru a trimite datele catre server. Valorile posibile sunt get si
post (nu conteaza litere mari sau mici). Cu get toate datele din formular
sunt adaugate la URL-ul specicat de atributul action, astfel ca la apasarea
butonului de trimitere n adresa va aparea (fragment):
http://localhost:61561/TestGet/default.aspx?txtNume=lmsasu&
txtParola=myPassword&butonTrimitere=Trimite
Se observa ca continutul formularului care poarta datele introduse de
utilizator sunt trimise n clar. Acelasi mecanism este folosit de exemplu de
catre pagina prin care se acceseaza motorul de cautare Google. Avantajul
acestei metode este ca se poate pune un bookmark, sau poate folosit ca
link ntr-un document.
http://www.google.ro/search?hl=ro&q=data+mining&btnG=
C%C4%83utare+Google&meta=

18

CAPITOLUL 1. APLICATII
WEB

Partea de dupa semn de ntrebare din URL se numeste query string.


Trebuie spus aici ca exista situatii n care folosirea metodei get este contraindicata; lungimea maxima a URL-ului este limitata de catre browsere, n
principal6 . De exemplu, pentru Internet Explorer lungimea maxima a URLului este de 2083 caractere, iar lungimea maxima a caii (http://www.site.com/
asta/este/in/cale) este de 2048 caractere; de asemenea, serverul sau proxyuri intermediare pot sa limiteze lungimea maxima a unui URL vezi gura
1.5; detalii suplimentare si teste - aici.

Figura 1.5: Eroare semnalata de serverul Web: URL-ul este prea lung.
Daca se specica metoda post, atunci setul de date din formular se include n corpul formularului si trimis mai departe la server; URL-ul nu va
modicat. Mai exista o diferenta semantica ntre get si post: get este
considerat idempotent, adica nu modica starea serverului la trimiteri repetate ale aceleiasi interogari (abstractie facand de cresterea unor contoare
sau nregistrarea acestor actiuni, sau orice alte efecte nereleavnte), pe cand
post e gandit pentru a produce efecte colaterale pe server tranzactii nanciare sau modicari de date.
In interiorul unui formular pot folosite urmatoarele elementele de tip
input:
text
password
6

Specificatia nu impune o lungime maxima pentru un URL

1.3. FORMULARE

19

checkbox
radio
submit
reset
le
hidden
image
button
Se folosesc cu forma generala: <input type="..." .../>. Sunt prezentate
pe scurt n cele ce urmeaza. Pe langa acestea mai sunt disponibile:
textarea
select

1.3.1

Text

Se foloseste pentru crearea unor casute text, al caror continut va furnizat


de utilizator:
1
2
3
4
5
6
7
8
9
10
11
12
13

<html>
<body>
<form action="default.aspx">
First name:
<input type="text" name="firstname">
<br />
Last name:
<input type="text" name="lastname">
<br />
<input type="submit" />
</form>
</body>
</html>

20

CAPITOLUL 1. APLICATII
WEB

Figura 1.6: Modul n care arata un input de tip text.


Iesirea este data n gura 1.6. Query string-ul n acest caz arata astfel:
firstname=Rafael&lastname=Popescu.
Poate calicat ca ind readonly (readonly="readonly") si i se poate
specica lungimea maxima a sirului acceptat: maxlength="35". De asemenea poate sa reactioneze la evenimente. O lista completa a atributelor si
evenimentelor poate gasita aici.

1.3.2

Password

Seamana cu cele de tip text, cu diferenta ca n momentul n care cineva


scrie n interiorul lui, caracterele sunt suprascrise cu un caracter inert vezi
listingul de la pagina 16 si gura 1.4. De retinut ca desi parola nu apare n
clar pe ecran, ea este trimisa totusi asa cum este scrisa; o eventuala criptare
sau folosire de protocol securizat (HTTPS) ramane sarcina celui care creeaza
aplicatia.
Asa cum sa spus la nceputul sectiunii 1.3, query string-ul asociat este:
txtNume=lmsasu&txtParola=myPassword
Documentatia completa despre acest tip se gaseste aici.

1.3.3

Checkbox

Checkbox-urile sunt folosite atunci cand utilizatorul trebuie sa specice


dintr-un set de optiuni nemutual excluzive.
1
2
3
4
5
6
7
8
9

<form>
I have
<input
<br />
I have
<input
<br />
I have
<input

a bike:
type="checkbox" name="vehicle" value="Bike">
a car:
type="checkbox" name="vehicle" value="Car">
an airplane:
type="checkbox" name="vehicle" value="Airplane">

1.3. FORMULARE
10
11

21

<input type="submit" />


</form>

Iesirea este data n gura 1.7. Daca se bifeaza Car si Airplane atunci pe
server va ajunge un query string de forma vehicle=Car&vehicle=Airplane.
Documentatia completa se gaseste aici.

Figura 1.7: Modul n care arata un input de tip checkbox.

1.3.4

Butoane radio

Permite alegerea a cel mult una din mai mult optiuni. Codul HTML si
modul n care arata sunt date mai jos.
1
2
3
4
5
6
7

<form>
<input type="radio" name="sex" value="male">Male
<br />
<input type="radio" name="sex" value="female">Female
<br />
<input type="submit" />
</form>

Figura 1.8: Modul n care arata un input de tip buton radio.


Mai multe butoane radio sunt considerate din acelasi grup daca au aceeasi
valoare a atributului name. Daca se bifeaza una din ele, se trimite query
string-ul: sex=male. Documentatia completa se gaseste aici.

1.3.5

Butonul de Submit

In exemplele anterioare formularele aveau un buton a carui apasare determina trimiterea formularului catre server. Acesta este creat cu:

22
1
2
3
4

CAPITOLUL 1. APLICATII
WEB
<form>
...
<input type="submit" />
</form>

Implicit, textul de pe el apare ca Submit Query. Daca se doreste, textul se


poate modica folosind atributul value. Detalii se gasesc aici.

1.3.6

Butonul de reset

Se obtine cu input-ul de forma: <input type="reset" /> si realizeaza


un buton pe care (implicit) scrie textul Reset si care va repune valorile din
formular la cele cu care au venit de pe server; nu se face trimiterea formularului la server. Vizual, arata ca si un buton de tip Submit.

1.3.7

File

Cu secventa:
1
2
3
4
5

<form action="default.aspx">
<input id="myFile" type="file"/>
<br />
<input type="submit" value="Incarca">
</form>
rezulta un formular de ncarcare de sier care arata precum cel din gura
1.9. Detalii se gasesc aici.

1.3.8

C
ampuri ascunse

Deseori este nevoie ca n cadrul formularului sa existe niste date care sa


vina de pe server si sa e trimise napoi odata cu restul datelor din formular.
Aceste campuri sunt ascunse, n sensul ca nu au o aparitie vizuala pe ecran.
Ele se produc cu un input de forma:
<input id="myHiddenField" type="hidden"
value="valoare invizibila"/>
Acest mecanism este extrem de util pentru a emula starea n aplicatiile Web
(HTTP este fara stare) sau pentru a putea modicat pe client (browser)
prin cod JavaScript, fara a nevoie sa se faca o cerere catre server.
Detalii se gasesc aici.

23

1.3. FORMULARE

Figura 1.9: Input-ul de tip le, dupa apasarea butonului Browse.

1.3.9

Image

Input-ul de tip imagine creeaza un control imagine care, atunci cand este
apasat trimite formularul catre server. Locatia imaginii este denita prin
atributul src:
1
2
3
4
5
6

<form action="default.aspx">
<input id="adresa" type="text" />
<br />
<input type="image" alt="text alternativ"
src="btn.png" height="20px"/>
</form>
cu iesirea data n gura 1.10

Figura 1.10: Input de tip imagine


Detalii despre acest tip de input se gasesc aici.

24

CAPITOLUL 1. APLICATII
WEB

1.3.10

Butoane

Exista un input de tip buton, care arata precum cel de Submit sau Reset,
a carui apasare va procesata exclusiv prin cod JavaScript, n browser. In
exemplul de mai jos la apasarea butonului se depune o valoare n textbox-ul
formularului, se aseaza o fereastra pe ecran si apoi se face submiterea formularului, totul prin cod JavaScript (dar oricare din actiuni este optionala):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

<html>
<head>
<script type="text/javascript">
function myJSFunction() {
var hiddenElement = document.getElementById("adresa");
if (hiddenElement != null) {
hiddenElement.value = "valoare setata din myJSFunction";
}
window.alert("functia myJSFunction s-a terminat");
document.getElementById("formular").submit();
}
</script>
</head>
<body>
<form id="formular" action="HTMLPage.htm">
<input id="adresa" type="text" size="40" />
<br />
<input id="myButton" type="button" value="button"
onclick="myJSFunction();"/>
</form>
</body>
</html>

Rezultatul este dat n gura 1.11.

1.3.11

Textarea

Input-ul de tip text este convenit a contine o singura linie. Pentru cazul
n care se doreste existenta unei casute text cu mai multe linii se poate folosi
elementul textarea:
1
2
3

<form id="myForm">
<textarea id="zonaText" cols="20" rows="4"></textarea>
<br />

1.3. FORMULARE

25

Figura 1.11: Input de tip buton. Este aratata starea dupa apasarea butonului.
4
5

<input type="submit" />


</form>
cu reprezentarea din gura 1.12. Detalii despre ce atribute si evenimente

Figura 1.12: Zona de text cu 20 de coloane si 4 linii.


suporta elementul textarea - aici.

1.3.12

Select

Elementul select permite alegerea dintr-o lista derulanta a uneia sau a


mai multor optiuni. Lista de optiuni este formata din perechi de forma cheievaloare, cheia (invizibila n pagina desenata de browser) ind cea care se
trimite catre server, iar valoarea este folosita pentru a face alegerea efectiva.
Se poate specica care este eleemntul implicit selectat:
1
2
3
4
5

<form method="get" action="default.aspx" id="myForm">


<select name="judete">
<option value="33">Vrancea</option>
<option value="14" selected="selected">Brasov</option>
<option value="18">Sibiu</option>

26
6
7
8
9
10

CAPITOLUL 1. APLICATII
WEB
<option value="21">Teleorman</option>
</select>
<br />
<input type="submit"/>
</form>

Query string-ul asociat este judete=14, iar reprezentarea este data n gura
1.13.

Figura 1.13: Reprezentarea controlului de selectare.


Este posibila si selectarea mai multor optiuni simultan, daca n cadrul
elementului select se specica si atributul multiple:
1
2
3
4
5
6

<select name="judete" multiple="multiple">


<option value="33">Vrancea</option>
<option value="14">Brasov</option>
<option value="18">Sibiu</option>
<option value="21">Teleorman</option>
</select>
Daca se specica acest atribut si niciuna din optiuni nu este selectata,
atunci reprezentarea din browser este cea din gura 1.14, iar query string-ul
va arata astfel: judete=33&judete=18.

Figura 1.14: Element option cu selectare multipla.


Detalii - aici.

Capitolul 2
ASP.NET
2.1

Generalit
ati

ASP.NET este o platforma pentru aplicatii web dezvoltata si distribuita


de catre Microsoft, pe care dezvoltatorii o folosesc pentru a contrui site-uri
web dinamice si servicii web. A fost lansat n ianuarie 2002 cu versiunea 1.0
a .NET Framework si este succesorul tehnologiei Active Server Pages (ASP)
dezvoltata tot de Microsoft. ASP.NET a fost construit pe Common Language
Runtime (CLR), ceea ce permite programatorilor sa scrie cod folosind orice
limbaj suportat de .NET.
Merita mentionat ca ASP.NET este o tehnologie freeware de la Microsoft.
ASP.NET poate folosit pentru a crea orice tip de aplicatie web, ncepand de
la mici site-uri personale pana la cele de tip business. Strictul necesar pentru
a programa cu ASP.NET este reprezentat de .NET Framework, care este
gratuit, si de Visual Web Developer Express Edition, de asemenea gratuit.
Aplicatiile ASP.NET sunt aplicatii web .NET complete care se executa
ca si cod compilat gestionat de .NET runtime. ASP.NET foloseste de asemenea capabilitatile complete a .NET Framework-ului o gama de clase la
fel de usor de nteles ca si cele pentru o aplicatie Windows obisnuita. In
esenta, ASP.NET ncearca sa estompeze linia ntre dezvoltarea de aplicatii
si dezvoltarea web prin preluarea instrumentelor si a tehnologiilor folosite de
programatorii de aplicatii desktop.

2.1.1

Ce e gresit la ASP-ul clasic?

Spagetti code
Consideram urmatorul exemplu, n care un dropdown list HTML este
populat cu rezultatul unei interogari a unei baze de date:
27

28

CAPITOLUL 2. ASP.NET

<%
Set dbConn = Server.CreateObject("ADODB.Connection")
Set rs = Server.CreateObject("ADODB.Recordset")
dbConn.Provider = "sqloledb"
dbConn.Open "Server=SERVER_NAME; Database=Pubs;
Trusted_Connection=yes"
%>
<select name="cboAuthors">
<%
rs.Open "SELECT * FROM Authors", dbConn, 3, 3
Do While Not rs.EOF
%>
<option value="<%=rs("au_id")%>">
<%=rs("au_lname") & ", " & rs("au_fname")%>
</option>
<%
rs.MoveNext
Loop
%>
</select>
Acest exemplu are nevoie de 19 linii de cod doar pentru a asa un control
HTML simplu. Dar ceea ce este mai grav e modul n care stilul de codicare
diminueaza performantele aplicatiei deoarece amesteca codul HTML cu cod
Visual Basic. Cand pagina este procesata de catre ASP ISAPI (Internet
Server Application Programming Interface), motorul de scripting de pe server
trebuie sa se activeze si sa se dezactiveze de mai multe ori pentru a gestiona
chiar si o singura cerere. Acest lucru creste cantitatea de timp necesara
pentru a procesa ntreaga pagina si a o trimite la client. Mai mult, paginile
web scrise n acest stil pot atinge foarte usor dimensiuni dicil de stapanit.
Daca se mai adauga si propriile componente COM (necesare pentru a furniza
functionalitatea pe care ASP nu o poate asigura) cosmarul managementului
codului creste.
Indiferent ce abordare se foloseste, codul devine ncurcat, lung si greu de
depanat. In ASP.NET, aceste probleme nu exista. Paginile de web sunt scrise
folosind conceptele programarii orientate pe obiecte traditionale. Paginile de
web ASP.NET contin controalele care pot programate n mod similar cu
aplicatiile desktop. Aceasta nseamna ca nu mai este nevoie de combinarea
unui set de marcaje HTML si cod inline. Daca se opteaza pentru abordarea
code behind atunci cand se creaza paginile ASP.NET, atunci codul si marcajul sunt de fapt plasate n doua siere diferite, ceea ce simplica ntretinerea

TI
2.1. GENERALITA

29

codului si permite separarea sarcinii de design a paginii web de cea destul de


dicila a programarii.
Limbajele de scriptare
La momentul crearii sale, ASP parea o solutie perfecta pentru dezvoltatorii de aplicatii desktop care vroiau sa treaca la dezvoltare web. Mai
degraba decat sa necesite nvatarea unui limbaj de programarea cu totul
nou, ASP a permis dezvoltatorilor sa foloseasca limbaje familiare cum ar
VBScript. Folosind deja popularul COM (Component Object Model) ca o
coloana vertebrala, aceste limbaje au actionat ca un vehicul pentru accesarea
componentelor si resurselor de pe server. Dar desi ASP era usor de nteles
pentru dezvoltatorii care erau deja obisnuiti cu limbaje precum VBScript,
aceasta familiaritate a avut un pret. Deoarece ASP a fost bazat pe tehnologii vechi, ce au fost initial create pentru aplicatii desktop, acestea nu au
putut sa functioneze la fel de bine n noul mediu de dezvoltare web.
Performanta nu a fost singura problema. Fiecare obiect sau variabila utilizata n ASP clasic era creata ca un tip de data variant. Asa cum mare
parte din programatorii in Visual Basic stiu, tipul de data variant este slab
tipizat, avand nevoie de cantitati mari de memorie, iar tipul exact este cunoscut doar la momentul rularii. De aici rezulta ca au performante mult mai
slabe decat variabilele explicite. De asemenea, cu acest tip de variabile era
imposibil de creat un IDE1 care sa ofere facilitati de debugging, IntelliSense
(recunoasterea elementelor lexicale) si vericarea erorilor.

2.1.2

Ce aduce ASP.NET?

Majorele diferente dintre ASP.NET si platformele de dezvoltare existente


includ urmatoarele:
ASP.NET propune un modelul de programare n ntregime obiect-orientat,
care include o arhitectura bazata pe evenimente si controale, care ncurajeaza
ncapsularea si refolosirea codului;
ASP.NET ofera posibilitatea de a programa n orice limbaj acceptat de
.NET;
ASP.NET sprijina ideea de executare rapida: paginile si componentele
ASP.NET sunt compilate (e la prima cerere, e la instalarea site-ului
pe server), n loc de a interpretate de ecare data cand acestea sunt
utilizate; a se vedea gura 2.1.
1

Integrated Development Environment, mediu integrat de dezvoltare.

30

CAPITOLUL 2. ASP.NET
modul de programare este orientat pe obiecte; orice pagina este vazuta
ca un obiect, derivat din clasa pusa la dispozitie de .NET Framework;
are un mecanism ncorporat care permite pastrarea starii paginii (chiar
daca protocolul de comunicare HTTP este fara stare);
ASP.NET permite dezoltarea de aplicatii web bazate pe evenimente,
similar cu situatia ntalnita n cadrul aplicatiilor de tip forme Windows;
este senzitiv la browserul pentru care se face trimiterea codului HTML,
alegand automat codul optimizat pentru o colectie de browsere;
ASP.NET este gazduit de catre CLR; aceasta aduce benecii notabile
precum: managementul automat al memoriei prin garbage collection;
tipuri de date sigure, vericabile; manipularea structurata a erorilor;
re de executie - pentru ecare cerere facuta de catre un client, se
lanseaza un r de executie separat;
usor de distribuit2 si congurat.

2.2

Despre ASP.NET 3.5

2.3

Tipuri de fisiere n ASP.NET

Intro aplicatie web sunt disponibile urmatoarele tipuri de siere:


siere cu extensia aspx pagini web asp.net; ele contin interfata utilizator si optional cod (JavaScript, C#);
siere cu extensia ascx controale utilizator ASP.NET; reprezinta
controale personalizate, dezvoltate de programatori, prin care se extinde paleta de controale cu care vine ASP.NET; aceste controale pot
adaugate n pagini aspx;
siere cu extensia asmx sau svc servicii web ASP.NET (prima extensie) sau servicii implementate prin Windows Communication Foundation (WCF);
web.cong sier de congurare a aplicatiei Web pentru ASP.NET;
contine stringuri de conexiune catre baza de date, congurari relativ la
managementul starii, al securitatii etc;
2

In sens de: deploy.

2.3. TIPURI DE FISIERE IN ASP.NET

Figura 2.1: Compilarea n doua trepte pentru aplicatie ASP.NET [2].

31

32

CAPITOLUL 2. ASP.NET
global.asax sier global al aplicatiei; se foloseste pentru a implementa
cod de reactie la evenimente ale aplicatiei, precum pornirea sau oprirea
ei;
siere cu extensia cs (daca este vorba de o aplicatie ASP.NET cu
C#), este partea de codebehind care prelucreaza pe server evenimentele survenite pe partea de browser si ciclul de viata al paginilor.
Se obtine astfel separarea partii de interfata utilizator de cea de cod
executat pe server;
siere cu extensia ashx HTTP handlers, pentru returnarea de continut
care sa nu e pagina web;
siere cu extensia axd folosite pentru urmarirea aplicatiei (tracing);
siere cu extensia master pentru master pages;
siere cu extensia resx pentru internationalizarea si localizarea aplicatiilor
ASP.NET;
siere cu extensia sitemap pentru crearea structurii site-ului;
siere cu extensia skin pentru crearea de teme (skinuri).

2.4

Modelul de cod

O pagina web aspx este compusa din cod ASP.NET de forma:


cod HTML; acesta este interpretat de catre browser;
controale web; acestea se recunosc prin tagurile care incep cu prexul
asp:, ca de exemplu:
<asp:CheckBox id="myCheckBox" Text="vreau bicicleta"
runat="server" />
<asp:TextBox id="usernameText" Text="Nume de utilizator"
runat="server" />
Controalele web sunt procesate pe server si vor produce cod HTML
care este inteligibil pentru un browser.
cod C# sau VB.NET

2.4. MODELUL DE COD

33

Acest ultim cod este executat pe server (deci browserul nu trebuie sa aibe
niciun tip de suport pentru executarea de cod .NET); relativ la locatia n
care se poate depune acest cod, avem posibilitatile:
1. cod inline, adica scris n interiorul paginii aspx; utilizat pentru pagini
web simple;
2. cod n spate 3 , ntr-un document separat cu extensia cs (daca este cod
C#). Este modelul preferat pentru dezvoltarea de pagini.
Alegerea ntre aceste doua modalitati este posibila la crearea unei noi pagini
web, prin checkbox-ul Place code in separate file.
Pentru primul caz, codul paginii aspx este:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

<%@ Page Language="C#" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void myButton_Click(object sender, EventArgs e)
{
myLabel.Text = "Buton apasat la: " +
DateTime.Now.ToLongTimeString();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="myButton" runat="server" Text="Apasati"
onclick="myButton_Click" />
<asp:Label ID="myLabel" runat="server"></asp:Label>
</div>
</form>
</body>
3

In original: code behind.

34
28

CAPITOLUL 2. ASP.NET
</html>

Pentru code behind, se obtin doua siere: pagina DemoCodeBehind.aspx


si sierul sursa DemoCodeBehind.aspx.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

<%@ Page Language="C#" AutoEventWireup="true"


CodeFile="DemoCodeBehind.aspx.cs" Inherits="DemoCodeBehind" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="myButton" runat="server" Text="Apasati"
onclick="myButton_Click" />
<asp:Label ID="myLabel" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
Partea de code behind este scrisa astfel:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

using
using
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Web;
System.Web.UI;
System.Web.UI.WebControls;

public partial class DemoCodeBehind : System.Web.UI.Page


{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void myButton_Click(object sender, EventArgs e)

2.4. MODELUL DE COD

35

15
16
17
18
19

myLabel.Text = "Buton apasat la: " +


DateTime.Now.ToLongTimeString();
}
}

Browserul va primi acelasi cod, deoarece interpretarea partii de C# si


ASP.NET se face de catre server. Este indicata folosirea variante de code
behind, deoarece asta permite separarea partii de layout (ce este n sarcina
unui designer) de cea de cod (sarcina de programator). In restul lucrarii ne
vom referi doar la modelul de codebehind.
Conectarea dintre pagina aspx si codebehind se face prin intermediul
directivei Page de pe primul rand. Remarcam ca se specica unde se aa
pagina de codebehind (atributul CodeFile); de asemenea faptul ca pagina
aspx este de fapt un obiect, derivat din clasa care contine code-behind (atributul Inherits). Controalele declarate n pagina aspx vor create automat,
ntr-o clasa partiala, care completeaza n mod transparent codul din sierul
DemoCodeBehind.aspx.cs. Astfel, pentru declaratia din pagina aspx:
<asp:Label ID="myLabel" runat="server"></asp:Label>
serverul va genera automat declaratia de camp:
protected global::System.Web.UI.WebControls.Label myLabel;
Acest lucru era vizibil n ASP.NET 1.1, prin cod generat automat de catre
designer n sierul de code behind; pentru versiunea ASP.NET 2.0 sau mai
noua, aceasta declaratie este generata automat de catre server4 . Se remarca
aici calicarea cu protected a campului, pentru a disponibil si n pagina
aspx derivata. O vedere a acestui cod se poate obtine din Visual Studio,
meniul ViewWiew Code Gen File.
Evenimentele (precum apasarea de buton, schimbarea itemului curent
selectat dintr-o lista de optiuni, ncarcarea paginii) sunt tratate prin metode
n partea de codebehind. In exemplul dat mai sus se observa ca evenimentul
de apasare a butonului este procesat prin metoda (n acest context: event
handler, manipulator de metoda) myButton_Click, iar legatura se specica
prin atributul onclick din pagina aspx. Se poate face si atasarea event
handlerului prin cod:
4

Codul dat a fost preluat din locatia n care modulul de ASP.NET si depoziteaza aceste fisiere, %systemroot%\Microsoft.NET\Framework\v2.0.50727\Temporary
ASP.NET files\[nume aplicatie]. Fisierul din care s-a luat declaratia este o clasa partiala,
care completeaza clasa DemoCodeBehind.

36

CAPITOLUL 2. ASP.NET

myButton.Click += myButton_Click;
Se remarca de asemenea si metoda Page_Load care este mostenita din
clasa de baza System.Web.UI.Page. Apelul automat al metodei face parte
din ciclul de viata al unei pagini, subiect tratat ulterior.

2.5

Controale Web si controale HTML

Un control Web reprezinta o clasa (exemplu: System.Web.UI.WebControls.Label)


care poate utilizata pe parte de codebehind; are un aspect vizual, generanduse cod HTML de catre server, cod care poate interpretat de browser; are de asemenea aspect comportamental evenimente si proprietati
de exemplu un obiect de tip Label poate sa suporte modicari prin latime,
text, culoare, vizibilitate. Avantajul acestor controale este ca permit generarea de cod HTML complex, fara ca programatorul sa e interesat de detalii:
eticheta de mai sus va genera un element de tip <span> pentru browser.
Exemplul devine mai elocvent pentru controale Web de tipul Calendar sau
forma de login. In plus, se creeaza programatorului iluzia ca modul de dezvoltare al aplicatiilor web este foarte asemanator cu cel folosit pentru aplicatiile
de tip Windows Forms, unde exista o abundenta de controale.
Din exemplul <asp:Label...> de mai sus, se observa atributul runat
cu valoarea server care este mandatoriu (ca prezenta si valoare) pentru
controalele web. Valoarea atributului id reprezinta numele variabilei cu care
se acceseaza controlul pe parte de server.
La cealalta extrema se aa codul HTML simplu, care este direct interpretat de catre browser. Problema cu acest cod este ca nu poate accesat de
catre code behind. Pentru a se permite accesarea programatica, sa introdus
conceptul de control HTML. Un control HTML se obtine din codul HTML
prin adaugarea a doua atribute: runat cu valoarea server si id avand drept
valoare un nume de variabila:
<input id="myHiddenField" type="hidden" runat="server"/>
Accesarea lui n code behind se face cu:
myHiddenField.Value = "valoare setata de pe code behind";
De remarcat ca si pentru aceste controale HTML se face interpretare pe
server, deoarece codul din browser nu prezinta atributul runat; runat este
interpretat de catre mediul ASP.NET si este eliminat la trimiterea spre browser.

2.6. FORME WEB

2.6

37

Forme Web

O foma web (denumirea consacrata sub care sunt cunoscute paginile web
aspx) reprezinta partea centrala a unei aplicatii ASP.NET. Exista doua parti
ale unei astfel de forme web:
partea care se aseaza pe client cod HTML, rezultat prin executarea
codului ASP.NET
partea care se aa pe server, adica pagina aspx, clasa de code behind
si cod .NET apelat de catre programator
Evident, trebuie sa existe o comunicare ntre aceste doua parti. Spre exemplu, daca este vorba de o pagina care permite unui utilizator sa si faca
cont, datele specicate n pagina web sunt trimise prin formular (a se vedea 1.3) napoi catre server; acesta este numit n jargon postback; serverul
receptioneaza acest formular si poate sa execute o secventa de pasi: validarea datelor din formular, crearea contului. Pagina apelata va formula un
raspuns (cod HTML) pe care l va trimite browserului. Dupa aceasta, ciclul
se poate relua. Trimiterea formularului ete un mecanism de baza specicat
de protocolul HTTP; ASP.NET nu aduce nimic nou aici.
Unul din mecansimele esentiale pentru o usoara dezvoltare a unui formular este pastrarea starii. Desi foloseste mecanism clasic (campuri ascunse), modul transparent n care este integrat n framework duce la reducerea substantiala a codului. In lipsa acestui mecansim, n Java sau PHP
trebuie facuta o implementare manuala.

2.6.1

Postback

Sa presupunem ca avem pagina default.aspx care contine anumite date


(de exemplu, lista studentilor din Facultatea de Matematica si Informatica).
Atunci urmatorul scenariul poate avea loc:
1. Un utilizator cere prin browser aceasta pagina. Serverul IIS primeste
cererea, determina faptul ca este o pagina aspx si invoca motorul ASP.NET
pentru a o executa. Motorul creeaza pagina si controalele continute, se
executa codul de initializare detalii la sectiunea 2.6.4 apoi pagina
este creeata ca sir de caractere HTML si returnata clientului. Obiectul
pagina si controalele incluse sunt distruse (adica devin neutilizabile; sa
ne amintim ca protocolul de comunicare este fara stare, deci pe server
nu e obligatoriu sa mentina resursele folosite anterior).

38

CAPITOLUL 2. ASP.NET
2. O data pagina trimisa catre browser, este randul utilizatorului sa produca actiunea de trimitere napoi a paginii, de exemplu prin apasarea
unui buton de tip Submit.
3. Formularul din pagina este trimis napoi la server, catre pagina default.aspx (acesta este comportamentul implicit pentru ASP.NET, dar se
poate modica). Motorul ASP.NET primeste iarasi cerere si recreeaza
pagina (deoarece pagina anterioara, de la pasul 1 a fost dealocata) de
pe server; aceasta refacere va restabili totusi valorile controalelor la
starea anterioara, prin mecansimul de viewstate sectiunea 2.6.2.
4. ASP.NET determina care a fost actiunea care a determinat trimiterea
napoi si executa event handlerele asociate (metoda myButton_Click,
de exemplu). Un asemenea event handler executa o operatie de modicare a continutului formei web (myLabel.Text=...), eventual apeland
la cod pentru extragere de date de pe un server de baze de date, etc.
5. Pagina default.aspx cu continutul astfel modicat este transformata
n cod HTML si trimisa serverului. Obiectele folosite pentru crearea
acestui raspuns sunt disponibilizate. Ciclul se reia de la pasul 2.

Postback-ul poate declansat si de o alta actiune decat apasarea unui buton de tip submit; de exemplu, la adaugarea de control web de tip dropdown
list, se poate specica n Visual Studio, prin proprietatea de tip boolean
AutoPostback daca modicarea itemului curent selectat duce la trimiterea
automata a formularului catre server. Acest mecanism este util pentru cazul
n care exista un dropdown list cu judete; alegerea unui anumit judet necesita
modicarea unui alt dropdown list care contine localitatile din judetul curent
selectat. Efectul se obtine prin cod JavaScript care actioneaza pe client, cod
este injectat automat de catre frameworkul ASP.NET, sub forma:
1
2
3
4
5
6
7
8
9
10
11

<script type="text/javascript">
//<![CDATA[
var theForm = document.forms[form1];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();

2.6. FORME WEB


12
13
14
15

39

}
}
//]]>
</script>

Se observa ca avem tot o trimitere de formular, dar dictata de cod. __EVENTTARGET


si __EVENTARGUMENT sunt doua campuri ascunse ce sunt populate cu detalii
despre cine a produs acest postback si eventualele detalii aferente. Dropdownlistul este generat n cod HTML astfel:
1
2
3
4

<select name="DropDownList2"
onchange="javascript:setTimeout
(__doPostBack(\DropDownList2\,\\), 0)"
id="DropDownList2">
In alte cadre de lucru pentru crearea de pagini web dinamice (Java, ASP,
PHP) un astfel de cod cade n sarcina programatorului. Trebuie nsa zis ca
postback-ul este disponbil doar pentru controale web.
Pentru a determina pe parte de code behind daca cererea e postback sau
nu, se poate folosi proprietatea de tip boolean Page.IsPostBack; aceasta
are valoarea true daca este un postback, false altfel. Mecanismul este util
pentru ca de regula la postback se face umplerea controalelor cu valori dintro sursa de date, n timp ce la postback acest lucru (de regula costisitor) se
poate evita daca se foloseste mecanismul de viewstate.

2.6.2

Mentinerea st
arii prin Viewstate

In lipsa mecanismului de Viewstate (care poate inhibat la nivel de


control), la ecare postback s-ar reface pagina la starea initiala, pierzandu
se valorile depuse anterior n controale. De exemplu, daca la procesarea
anterioara (a doua cerere catre pagina) sa setat continutul unei etichete
la o anumita valoare, la a treia cerere aceasta valoare sar pierde. Este
explicabil, deoarece HTTP este protocol fara stare, iar serverul nu mentine
de la o cerere la alta valorile actuale ale controalelor. De regula, asemenea
efect este nedorit.
Mecansimul prin care se pastreaza ultima valoare a unui control (e el
web sau HTML) este viewstate. Pentru ecare web control se poate seta
valoarea EnableViewState la true (de fapt, valoarea implicita), prin asta
semnalanduse ca se va mentine starea. Mentinerea se face prin intermediul
unui camp ascuns numit __VIEWSTATE n cod HTML si accesat cu variabila
ViewState pe parte de code behind. Pentru un control HTML trebuie sa se
specice enableviewstate=true.

40

CAPITOLUL 2. ASP.NET

In codul HTML generat pentru browser contine un string cu o codicare


Base64 a starii controalelor (contine starea tuturor controalelor care au exprimata optiunea de viewstate). Acest camp este procesat de catre server pe
partea de code behind, n mod automat, o data la postback, apoi nainte de
trimitere a raspunsului catre client.
Modul n care lucreaz
viewstateul pentru prima cerere si pentru postback
urile ulterioare este redat n gurile 2.2 si 2.3 ([2]).

Figura 2.2: Modul de lucru pentru viewstate la prima cerere [2].


In acest fel eliberarea resurselor necesitate de catre server pentru procesarea paginii pot eliberate fara problema; apare nsa cazul unui camp ascuns
care va plimbat permanent ntre client si server, ceea ce duce la ngreunarea
comunicarii (pagina mai mare trimitere mai lenta). De regula, pentru o
pagina Web se folosesc o multime de controale, care implicit au partea de
viewstate neinhibata, deci se poate ajunge la dimeniuni mari pentru campul
ascuns; se mai ia aici n calcul si expandarea intrinseca indusa de codicarea
Base64.
Pentru contracararea acestui efect, reamintim ca sunt controale a caror
stare nu se schimba n timp (e.g. butoane), sau a caror stare este refacuta de
ecare data, pentru care dezactivarea optiunii de viewstate poate nsemna
o economie importanta de spatiu. De asemenea, evitarea stabilirii valorii
pentru controale prin cod (si precizarea lor la designul paginii aspx) reduce
viewstate-ul.
Exista chiar situatii cand pagina cu o dimensiune prea mare a campurilor
ascunse sunt blocate de catre proxy-uri. Pentru aceasta, viewstateul poate
spart n mai multe bucati; detalii se gasesc n [2], pagina 81 (View State

2.6. FORME WEB

41

Figura 2.3: Modul de lucru pentru viewstate pentru postback [2].


Chunking).
In nal, menctionam ca viewstate se poate folos nu doar de catre controalele din pagina, ci si de catre programator, permitanduse adagarea si
regasirea unor perechi de forma (cheie, valoare).

2.6.3

Utilitatea conceptului de controale

Sa consideram forma web:


1
2
3
4
5
6
7
8
9
10
11
12
13

<%@ Page Language="C#" AutoEventWireup="true"


CodeFile="UtilitateControale.aspx.cs"
Inherits="UtilitateControale" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" method="get">

42

CAPITOLUL 2. ASP.NET
<div>
<asp:Label ID="Lable1" runat="server" Text="Nume">
</asp:Label>
<asp:TextBox ID="txtName" runat="server">
</asp:TextBox>
<br />
<asp:CheckBox ID="chkApples" runat="server"
Text="Vreau mere" />
<br />
<asp:CheckBox ID="chkPears" runat="server"
Text="Vreau pere" />
<br />
<asp:Button ID="btnSend" runat="server"
onclick="btnSend_Click"
Text="Trimite" />
</div>
</form>
</body>
</html>

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

La trimiterea conform selectiei din gura 2.4, query string-ul arata astfel
(fragment, am omis viewstate-ul si alte campuri ascunse):
txtName=Rafael&chkApples=on&btnSend=Trimite

Figura 2.4: Pagina web obtinuta cu controale web.


In codebehind, valoarea controalelor se poate accesa cu5 :
if (Request.Form["chkApples"] == "on"
&& Request.Form["chkPears"] != "on") ...

1
2
5

Daca transmiterea de parametri se face cu metoda get si nu cu post, atunci n loc de


Request.Form se foloseste Request.QueryString.

2.6. FORME WEB

43

Este nsa mai natural a se interpreta cele doua casute de checkbox ca niste
componente care au o proprietate, Checked, de tip boolean; de asemenea,
casuta de text poate sa e accesata foarte usor:
1
2
3
4
5

string name = txtName.Text;


if (chkApples.Checked && !chkPears.Checked)
{
txtName.Text += " vrea doar mere";
}
Astfel, consultarea valorilor de pe formular este simpla, n maniera de realizare a aplicatiilor de tip Windows Forms. In cele de mai sus, Request este
un obiect de tip HttpRequest pus la dispozitie prin mostenire din clasa Page,
pentru a avea acces la datele cererii dinspre client catre server.
Acelasi mecanism este valabil si pentru controalele HTML:

1
2
3
4
5

Nume<input id="txtName2" type="text" runat="server" /><br />


<input name="chkApples2" type="checkbox" runat="server"
id="chkApples2" /> Vreau mere<br />
<input name="chkApples2" type="checkbox" runat="server"
id="chkPears2" /> Vreau pere
cu procesarea pe code behind (atentie la modul de accesare a textului din
inputul de tip text):

1
2
3
4

if (chkApples2.Checked == true && chkPears2.Checked == false)


{
txtName2.Value += " vrea doar mere";
}

2.6.4

Ciclul de viat
a al unei pagini (variant
a sumar
a)

Pasii parcursi de la primirea unei cereri pentru o forma web pana la


furnizarea raspunsului catre client sunt:
1. initializarea paginii
2. instantierea codului utilizator
3. validare
4. procesarea de evenimente
5. legarea automata la date
6. disponibilizarea de resurse

44

CAPITOLUL 2. ASP.NET

Initializarea paginii
La acest pas se creeaza pagina ASP.NET (se instantiaza atat clasa corespunzatoare portiunii de codebehind, cat si cea corespunzatoare paginii
aspx); controalele sunt instantiate. Daca pagina nu este prima data ceruta de
catre acest browser (adica daca este un postback), atunci se face restaurarea
starii din viewstate. Aici se apeleaza de catre framework metoda Page.Init.
Initializarea codului utilizator
Este apelata metoda Page.Load (de regula ea este scrisa Page_Load n
code behind). Aici de regula se scrie cod care face ncarcarea datelor n
pagina.
Valid
arile
Uneori se cere ca valorile furnizate de catre utilizator n browser sa satisfaca anumite cerinte. Procesul de validare (care se poate efectua si de catre
codul JavaScript de pe client, dar nu obligatoriu) trebuie sa e ndeplinit pentru a se asigura ca valorile cu care urmeaza sa se lucreze au relevanta. In caz
contrar, pagina se poate retrimite pentru comletarea adecvata a intrarilor.
Procesarea de evenimente
Sunt executate metodele care functioneaza pe post de event handler-i.
Sunt doua feluri de procesaei:
raspuns imediat, daca este vorba de apasare de buton sau postback
automat
rspuns de tip schimbare: daca sa stabilit un event handler pentru un
anumit control, dar nu s-a precizat AutoPostback=true, si n plus se
detecteaza (prin comparatie cu valorile din viewstate) ca a aparut o
schimbare n starea controlului, atunci se exectua acest event handler.
Procesarea evenimentelor de tip schimbare se face nainte de procesarea evenimentelor de tip raspuns imediat.
Legare automat
a la date
Fenomenul se va detalia ntrun capitol ulterior. Este vorba de controale care se leaga la surse de date. Acestea si pot remprospata automat
continutul, dupa ce eventualele modicari / adaugari / stergeri de date.

2.6. FORME WEB

45

Disponibilizarea resurselor
Se genereaza pagina HTML car eva trimisa catre browser. Obiectele
instantiate pentru aceasta cerere devin neutilizabile.

46

CAPITOLUL 2. ASP.NET

Capitolul 3
Forme Web, gestiunea st
arii
3.1
3.1.1

Forme Web (continuare)


Colectia de controale din pagin
a

O pagina reprezinta un container pentru controalele dispuse pe ea; un


control poate de asemenea sa e de tip container (e.g. Panel, MultiView).
Regasirea unui control copil continut se face e prin iterarea peste colectia
Controls, e prin folosirea metodei FindControl(string id). Proprietatea
si metoda amintita sunt mostenite din clasa System.Web.UI.Control, baza
a tot ceea ce nseamna controale server.

3.1.2

Request

Proprietatea Request reprezinta obiect de tipul System.Web.HttpRequest


asociat cererii HTTP efectuate de browser. Exista urmatoarele metode si
proprietati (lista este incompleta):
Browser permite accesarea descrierii proprietatilor browserului folosit de client (tipul, numele, versiunea, platforma, capabilitati etc);
Cookies permite accesarea cookie-urilor trimise de site catre browser;
Form permite accesarea formularului si a continutului sau;
QueryString pentru accesarea parametrilor interogarii facute prin
get;
URL, URLReferrer adresa curenta, respectiv adresa paginii din care
sa facut cererea curenta;
47


CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

48

UserHostName, UserHostAddress adresa si numele calculatorului


de pe care sa facut interogarea;
UserLanguages lista de limbi pe care o are setata browserul clientului; utila pentru internationalizare.
Pentru o lista completa a metodelor si proprietatilor, invitam consultarea
MSDNului.

3.1.3

Response

Desi rar folosit, acest obiect, instanta a clasei System.Web.HttpResponse


da acces la cateva mecanisme, printre care:
setarea de cookie-uri ce sunt trimise spre client via proprietatea
Cookies;
saltul la o pagina noua via metoda Redirect; n felul acesta, de pe
server se trimite un mesaj browserului prin care este instruit sa ceara
pagina indicata de server; se poate face redirectare la orice fel de pagina
(chiar si la una de tip htm), aata oriunde (chiar si pe un alt server);
determinarea starii de conectare a clientului prin interogarea proprietatii boolene IsClientConnected; daca raspunsul este false,
atunci se poate renunta la o procesare consumatoare de resurse pe
partea de server;
trimiterea de continut, altceva decat sir de caractere via proprietatea ContentType; tipurile posibile de continut sunt prevazute de catre
specicatiile MIME type.
lucrul direct cu uxul de iesire catre client, prin proprietatea OutputStream.

3.1.4

Server

Obiectul Server, de tip System.Web.HttpServerUtility da acces la metode auxiliare pentru procesarea de cereri web. Deosebit de utile sunt metodele HtmlEncode si duala ei HtmlDecode. Daca codul ASP.NET posteaza
continut de tip sir de caractere n pagina, este obligatoriu a se face codicarea
lor conform canoanelor HTML, altfel caractere precum < sau > pot produce
ravagii n pagina; ele trebuie codicate ca ind &lt; respectiv &gt;.
Similar, substituirea corecta a caracterelor n adree, se folosesc metodele
UrlEncode si UrlDecode. Pentru determinarea caii zice corespunzatoare

3.2. TIPURI DE CONTROALE SERVER

49

unui sier de pe site se foloseste metoda MapPath(). In sfarsit, pentru


transferarea la o alta pagina, fara a se face redirectare prin browser (ca la
Response.Redirect), se poate folosi Server.Transfer(), cu restrictia ca
transferul sa se faca doar catre pagina ASP.NET de pe acelasi server.

3.2

Tipuri de controale server

Exista doua tipuri majore de controale, asa cum s-a specicat si n 2.5:
controale server HTML si controale server Web. Acestea din urma cunosc
specializarile: controale bogate, de validare, de date, de navigare, de login,
parti Web, pentru ASP.NET AJAX si de tip ASP.NET mobil.
Toate controalele de tip server au ca principala trasatura faptul ca se pot
procesa ca obiecte pe server, avand deci un tip de date reprezentat pe platforma .NET. Clasa de baza pentru orice control este clasa System.Web.UI.Control,
care e derivata de clasa System.Web.UI.WebControls.WebControl, reprezentand baza pentru controalele de tip server si System.Web.UI.HtmlControls.HtmlControls,
baza pentru controalele server HTML. Clasa Control contine si transmite
derivatilor proprietatile si metodele:
ClientID proprietate ce returneaza identicatorul ecarui control din
pagina HTML; acesta va putea utilizat n JavaScript, prin functia
document.getElementById();
Controls proprietate care returneaza o colectie de controale copil ale
obiectului curent. De exemplu, un control declarat cu asp:TextBox
este copil al formularului;
EnableViewState returneaza sau seteaza o valoare logica specicand
daca ultima stare setata pentru un control va sau nu salvata n
ViewState (proprietate a paginii, care va transformata n campul
ascuns __VIEWSTATE).
ID este identicatoru controlului, adica numele de variabila cu care
se poate acces n code behind controlul respectiv;
Page obiectul pagina care contine controlul curent;
Parent controlul n care este copil controlul curent;
Visible proprietate cu valoare logica, specicand daca controlul este
vizibil sau nu;
DataBind() se face popularea controlului la surse de date;


CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

50

FindControl() se cauta recursiv un control cu un anumit nume n


controlul curent;
HasControl() returneaza true sau false, aratand daca controlul
curent are sau nu controale copil;
Render() se scrie codul HTML asociat controlului curent; metoda
se apeleaza de regula de catre motorul de ASP.NET si nu direct de
programator.

3.2.1

Controale server HTML

Sunt din trei categorii mari: controale de tip input (e.g. butoane, checkbox, casute de text etc), controale de tip container (formular, tabel, textarea
etc) si grupul format din HtmlImage, HtmlLink, HtmlTitle. Clasa de baza
este HtmlControl, iar proprietatile expuse sunt:
Attributes proprietate care permite accesarea sau adaugarea de atribute;
Disabled returneaza sau seteaza starea de inhibare a controlului;
daca are valoarea true, va asat pe pagina, dar cu culoare gri deschis;
Style permite accesarea sai modicarea stilurilor CSS pentru controlul curent;
TagName returneaza numele controlului.
Un control de tip HtmlContainerControl reprezinta un control HTML
care are atat eticheta de deschidere, cat si de nchidere, cum ar a sau img.
Pe langa cele mostenite din HtmlControl, mai avem proprietatile:
InnerHtml returneaza sau seteaza textul HTML dintre etichetele de
deschidere si nchidere. Toate caracterele sunt lasate asau cum se dau;
facilitatea este folosita de regula pentru includerea de continut HTML;
InnerText ca mai sus, cu deosebirea ca textul setat sufera modicarea
caracterelor care au semnicatie HTML predenita (<, >, ghilimele etc)
sunt nlocuite cu codicari corespunatoare (&lt;, &gt;, &quot; etc).
Clasa HtmlInputControl este folosita ca baza pentru controalele care permit interactiunea cu utilizatorul, cum ar <input type="text">, <input
type="submit">. Fata de cele mostenite din HtmlInputControl, se mai pun
la dispozitie proprietatile:

3.2. TIPURI DE CONTROALE SERVER

51

Type obtine tipul unui obiect HtmlInputControl;


Value obtine sau seteaza continutul pentru controlul curent.
Exemplu: sa presupunem ca avem codul HTML:
1

<input type="text" runat="server" id="myTextBox" />


iar pe partea de code-behind codul (fragment):

1
2
3
4
5
6
7
8
9

protected void Page_Load(object sender, EventArgs e)


{
myTextBox.Style["font-size"] = "30px";
myTextBox.Style["color"] = "red";
myTextBox.Value = "Introduceti numele";
myTextBox.Attributes["onfocus"] =
"alert(numele de familie)";
}
La rulare codul HTML generat va (fagment):

1
2
3

<input name="myTextBox" type="text" id="myTextBox"


style="font-size:30px;color:red;" value="Introduceti numele"
onfocus="alert(numele de familie)" />
cu efectul din gura 3.1.

Figura 3.1: Setarea de proprietati pentru controale server HTML


Controalele server HTML pot manipula doua evenimente pe parte de
server:
ServerClick este un click procesat de partea de code-behind; de
exemplu, pentru codul:


CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

52
1
2

<a href="http://www.google.com" runat="server"


id="myAnchor" onserverclick="MyServerClick">apasa aici</a>

si implementarea n partea de code-behind:


1
2
3
4

protected void MyServerClick(object sender, EventArgs e)


{
Response.Redirect("http://www.clusty.com");
}
nu se va deschide pagina de Google, ci cea setata de catre codul C#.
Efectul se obtine deoarece apasarea pe link nu e procesata de catre
browser n modul natural, ci are loc trimiterea formularului napoi catre
server, asa cum se poate deduce din codul HTML rezultat:

1
2

<a id="myAnchor" href="javascript:__doPostBack(myAnchor,)">


apasa aici</a>
Acest tip de eveniment este disponibil doar pentru o parte din controalele server HTML.

ServerChange se declanseaza atunci cand se modica continutul unui


control poate avea stari diferite: text, checkbox etc. De exemplu:
1
2
3
4
5
6

<input id="myCheckbox" type="checkbox"


runat="server" onserverchange="MyServerChange"/>
<br />
<asp:Label ID="myLabel" runat="server" Text=""></asp:Label>
<br />
<input type="submit" id="btnSubmit"/>
cu partea de code-behind (fragment):

1
2
3
4

protected void MyServerChange(object sender, EventArgs e)


{
myLabel.Text = myCheckbox.Checked.ToString();
}
La apasarea butonului de tip Submit se va executa pe server metoda
MyServerChange. In acest caz, schimbarea starii casutei de optiune nu
duce automat la trimiterea formularului catre server, dupa cum se poate
constata din inspectarea codului HTML obtinut - lipseste procesarea
unui eveniment de tip JavaScript.


IN ASP.NET
3.3. GESTIUNEA STARII

3.2.2

53

Controale Web server

Reprezinta clase din spatiul de nume System.Web.UI.WebControls, gandite


pentru a extinde gama de controale HTML; un control de tip Web server are
nu doar o reprezentare graca mai bogata datorita unui cod bogat de HTML
care se genereaza automat ci si un comportament mai orientat catre comunicarea cu serverul. Clasa de baza este WebControl, care expune mult mai
multe proprietati si metode decat analoagele lor de tip HTML server control.
Spre exemplu, se pune la dispozitie proprietatea Font prin care se specica
proprietatile fontului curent: corp de litera, culoare, decorare, marime etc.
Se elimina astfel necesitatea de a sti foarte bine numele atributelor CSS si
valorile lor, deoarece clasele folosite sunt facute astfel ncat sa furnizeze doar
valorile acceptabile.
Toate controalele se declara n pagina aspx cu sintaxa <asp:numeControl>,
au automat proprietatea runat cu valoarea setata pe server mai mult, daca
atributul lipseste, se declara eroare de compilare.
Spre deosebire de controalele HTML server, ecare control server Web
dispune de metoda Focus() care poate utilizata pe parte de code-behind
pentru a selecta acel control ca ind cel curent. Pentru o casuta de text
cu identicatorul myTextbox, apelul myTextbox.Focus() duce la injectarea
urmatoarei sectiuni n codul paginii HTML rezultate:
1
2
3
4

<script type="text/javascript">
<!-WebForm_AutoFocus(myTextbox);// -->
</script>
unde functia JavaScript WebForm_AutoFocus provine dintr-un sier de resurse pus la dispozitie de catre ASP.NET, numit WebResource.axd.
Daca pe un formular sunt dispuse mai multe butoane, este posibila specicarea unui buton ca ind implicit adica apasarea lui tastei Enter sa e
interpretata ca apasarea pe acest buton. Specicarea lui se face prin intermediul formularului, care prin atributul DefaultButton poate specica ID-ul
butonului care va considerat ca implicit. De asemenea, daca se folosesc
panouri (<asp:Panel>), acestea putand grupa mai multe butoane, se poate
specica la nivel de panou care e butonul implicit.

3.3

Gestiunea st
arii n ASP.NET

HTTP este un protocol care nu pastreaza starea. Motorul de ASP.NET


distruge obiectele pe care le-a format pentru a raspunde cererii clientului. De


CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

54

multe ori, nsa, este nevoie ca ntre doua cereri succesive o anumita informatie
sa e pastrata si recuperata dace este nevoie de ea. Exemplul clasic este cosul
de cumparaturi pe care l pune la dispozitie un site de tip comert electronic:
vizitatorul poate sa adauge din pagini diferite obiectele pe care le cumpara;
la orice moment, acest cos este disponbibil pentru a inspectat sau modicat
de acel cumparator.
Managementul starii n ASP.NET se poate face cu:
1. ViewState
2. Query String
3. Cookie-uri
4. Sesiunea (Session)
5. Application
6. Prolul
7. Caching
Vom prezenta doar primele cinci metode. O comparatie a lor se gaseste n
tabelele 3.1 si 3.2.
Tabela 3.1: Optiuni de management al starilor (1).
View State
Tipuri de date Tot ce e
permise
serializabil
Stocare
Un camp ascuns
n pagina
Durata de
Permanent retinut
viata
la postback-uri
Vizibilitate

Pagina curenta

Securitate

Usor de citit,
relativ greu de modif.
poate criptat
Nu afecteaza serverul
dar poate ngreuna
comunicatia

Performanta

Query String
Un numar limitat
de caractere
Adresa URL din
browser
se pierde cand se
introduce o noua
adresa
Pagin tinta

Cookie-uri utilizator
S iruri de caractere
Memoria (RAM/HDD)
a calc. clientului
Setat de programator

Vizibil n clar,
usor de modicat

Intreaga aplicatie
ASP.NET
Nesigur, poate
modicat de utiliz.

Buna, deoarece datele


sunt putine

Buna, deoarece
datele sunt putine


IN ASP.NET
3.3. GESTIUNEA STARII

55

Tabela 3.2: Optiuni de management al starilor (2).


Sesiune
Application
Tipuri de date Orice tip serializabil
Orice tip .NET
permise
Stocare
Memoria serverului sau
Memoria serverului
baza de date
Durata de
Expira dupa un t de la
Durata de viata
viata
ultima accesare a serverului a aplicatiei

In toata aplicatia,
Vizibilitate
In toata aplicatia,
n cadrul unei sesiuni
global
Securitate
Sigur, deoarece datele nu
Foarte sigure, deoarece datele nu
sunt trimise la client
sunt trimise la client
Performanta
Sesiuni mari server lent Multe date server lent
Utilizare
Stocare de cumparaturi
Variabile globale

3.3.1

ViewState

Stocheaza datele n interiorul paginii curente, sub forma unui camp ascuns. La orice trimitere de formular cu atre server, acest camp este proiectat
napoi. Este de regula folosit pentru a stoca ultima valoare a unui control (si
se include aici si setare privind stilul controlului, nu doar continutul); poate
de asemenea mbogatit cu perechi de forma cheievaloare, care ulterior
pot modicate sau sterse.
1
2
3
4
5
6
7

ViewState["Counter"] = 1;
...
int counter;
if (ViewState["Counter"] != null)
{
counter = (int)ViewState["Counter"];
}
Cheia este de tip sir de caractere; se poate folosi drept valoare orice tip de
date serializabile (care are atributul [Serializable] denit atat pentru el
cat si pentru clasele din care este wderivat, direct sau nu).
Exemplu: clasa Customer denita de programator precum:

1
2
3

[Serializable]
public class Customer
{


CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

56
4
5
6
7
8
9
10
11

public string FirstName;


public string LastName;
public Customer(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}

poate instantiata si stocata n ViewState:


1
2

Customer cust = new Customer("Rafael", "Popescu");


ViewState["CurrentCustomer"] = cust;
respectiv refacut cu:

Customer cust = ViewState["CurrentCustomer"] as Customer;


Aici este important faptul ca campurile FirstName si LastName sunt serializabile (proprietate implicita a clasei String). Daca sunt campuri dintr-un tip
neserializabil, sau daca nu se doreste serializarea lor, atunci acestea trebuie
sa e prexate cu atributul [NonSerializable].
Situatiile n care nu se recomanda folosirea ViewState-ului pentru mentinerea
datelor sunt:
datele au caracter condential; codicarea prin Base64 este reversibila
si usor de citit; mai mult, se poate modica acest continut cu un efort
mediu (vezi [2]);
se foloseste o informatie care trebuie sa e accesibila pentru mai multe
pagini; n acest caz sunt mai indicate sesiunea, query string-ul sau
cookie-urile;
datele ce trebuie stocate sunt voluminoase, ceea ce ngreuneaza comunicatia
spre si dinspre server (ca parte a formularului, acest camp este plimbat
permanent).
Pentru mbunatatirea timpilor de raspuns, se poate elimina acest viewstate atunci cand nu este cu adevarat nevoie de el. Asemenea cazuri sunt:
controlul nu si modica niciodata starea (continut, caracteristici vizuale);
controlul este repopulat la ecare postback;


IN ASP.NET
3.3. GESTIUNEA STARII

57

este un control de tip input, a carui valoare este setata de utilizator,


deci oricum serverul le mentine.
Pentru a se omite salvarea automata n ViewState pentru starea unui
control, se poate specica proprietatea EnableViewState cu valoarea false,
sau se poate specica la nivel de pagina, e prin modicarea ei ca anterior
la nivel de pagina, e la directiva:
1

<%@ Page Language="C#" EnableViewState="false" ... %>


Securitatea ViewState-ului poate privita din 2 perspective: ne intereseaza sa nu se poata face modicarea continutului (chiar daca acest continut
poate usor descifrat), sau chiar sa nu se poata descifra ce sa salvat.
Primul aspect este automat rezolvat, deoarece o data cu valorile perechilor cheievaloare serializata se salveaza si o suma de control asociata
continutului. Cand se reprimeste la server campul ascuns, se recalculeaza
aceasta suma de control; daca nu coincide cu valoarea din ViewState, nseamna
ca sa intervenit n el.
Daca se vrea ca ViewState-ul sa e codicat, atunci se va specica n
directiva Page:

%@Page ViewStateEncryptionMode="Always" ... %>

In loc de Always se mai poate utiliza Never sau Auto.

3.3.2

Query String

Din adresa http://www.google.ro/search?q=data+mining&lang=ro, query string-ul este partea de dupa semnul de ntrebare. Reprezentarea se face
sub forma variabila=valoare, iar mai multe astfel de perechi pot separate
prin caracterul &.
Exista urmatoarele limitari ale unui query string:
Informatia este limitata la siruri de caractere, care trebuie sa contine
caractere valide pentru un URL.
Informatia este vizibila pentru oricine;
Pot aparea modicari neanutate ale componentelor din QS; de exemplu,
n loc de lang se poate decide sa se foloseasca doar l.
lungimea maxima a acestui URL este limitata; a se revedea 1.3.
Un QS poate folosit din partea de code behind astfel:


CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

58
1

Response.Redirect("newpage.aspx?recordID=" + recordID.ToString());
Trebuie permanent avut grija ca adresa astfel formata sa contina mereu caracterel valide pentru un URL, adica un set destul de redus. Acest lucru se
obtine prin apelul metodei Server.UrlEncode(detaliu).

3.3.3

Cross page posting

[2], pag 233 si urm

3.3.4

Cookies

Cookie-urile utilizator reprezinta siere care sunt menc tinute de catre


client (browser) e n memoria sa (si deci disponibile doar pe durata cat
browserul este deschis), e pe harddisk (si deci pot valabile la repornirea browserului). Reprezinta perechi de forma cheievaloare, ambele de tip
string. Un cookie este trimis automat de catre browser serverului si apoi
napoi.
Crearea unui cookie si atasarea lui la raspuns se face astfel:
1
2
3
4

HttpCookie cookie = new HttpCookie("Preferences");


cookie["LanguagePref"] = "English";
cookie["Country"] = "US";
Response.Cookies.Add(cookie);
Mai sus s-a denit un cookie care va stocat doar n browser; daca
se doreste ca acesta sa e stocat pe HDD, se va specica o data limita de
valabilitate:

cookie.Expires = DateTime.Now.AddYears(1);
Redobandirea unui cookie se face prin:

1
2
3
4
5
6

HttpCookie cookie = Request.Cookies["Preferences"];


string language;
if (cookie != null)
{
language = cookie["LanguagePref"];
}


IN ASP.NET
3.3. GESTIUNEA STARII

3.3.5

59

Sesiunea

Sesiunea nu este parte a HTTP-ului, dar este un concept implementat


de catre orice framework pentru crearea de pagini web dinamice l implementeaza. O sesiune este caracteristica unui browser deschis, reprezinta un
container de elemente structurate ca si cheievaloare, unde cheia este de tip
string iar valoarea orice obiect serializabil. De regula, se mentine n memoria
serverului cate o sesiune, instantiata la ecare inceput de sesiune. Alternativ,
se poate specica faptul ca sesiunile sa e memorate ntro baza de date.
Fiecare sesiune este identicata de un sir de 120 de biti lungime, care
se salveaza de regula ntrun cookie pe browser; la orice cerere efectuata de
catre browser, se trimite automat si acest cookie, ceea ce permite serverului
sa determine care este sesiunea atasata browserului; pe partea de code behind
se poate accesa continutul sesiunii. Daca se suspecteaza ca clientul nu are
mecansimul de cookie permis (sau browserul nu permite asa ceva), atunci se
poate face codicarea acestui identicator de sesiune prin intermediul URL
ului, setare disponibila din sierul de congurare web.cong; sau se poate
folosi autodetectare, deci sa se decida automat care din variante sa se aplice.
Adaugarea (sau suprascriere) si accesarea continutului din sesiune se fac
precum urmeaza (exemplu):
1
2

Session["ProductsDataSet"] = dsProducts;
dsProducts = Session["ProductsDataSet"] as DataSet;
Sesiunea este pierduta ntruna din urmatoarele situatii:
utilizatorul nchide browserul; aceasta duce la pierderea cookie-ului care
contine indenticatorul de sesiune;
sesiunea expira; implicit, n ASP.NET dupa 20 de minute de la ultima
accesare dinspre clientul care a determinat crearea sesiunii, se dealoca
automat aceasta sesiune de catre server, pentru a nu irosi resursele; valoarea de timeout se poate specica n sierul de congurare web.cong;
daca programatorul apeleaza n code behind Session.Abandon().
Daca cineva urmaresste comunicatia pe retea, poate sa obtina acest cookie, si deci acces la sesiune. Pentru aceasta se poate folosi Secure Socket
Layer (SSL).

3.3.6

Application

Obiectul Application este unic pentru toata lumea, deci poate sa contina
niste valori care sunt de interes general: contoare de exemplu numarul de

60

CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

utilizatori curent loginati sau seturi de date care nu se modica dictionare


de traducere.
1
2
3
4
5
6
7
8
9
10
11
12
13

protected void Page_Load(Object sender, EventArgs e)


{
// Acquire exclusive access.
Application.Lock();
int count = 0;
if (Application["HitCounterForOrderPage"] != null)
count = (int)Application["HitCounterForOrderPage"];
count++;
Application["HitCounterForOrderPage"] = count;
// Release exclusive access.
Application.UnLock();
lblCounter.Text = count.ToString();
}

Capitolul 4
Validatoare, manipulatoare de
HTTP, controale utilizator
4.1

Controale de validare a intr


arii

In cazul formularelor, o parte considerabila o reprezinta controalele de


preluare a datelor de la utilizator. Pentru aceste date preluate un minim de
reguli se cere, de obicei, sa e respectat. De exemplu, pentru un nume de
utilizator, se cere ca acesta sa e nevid; pentru o adresa de email sau un
numar de telefon, acesta trebuie sa aibe un anumit format.
Validarea se poate face n doua locuri: pe server (la postback) sau pe
client, nainte de trimiterea formularului care le contine. A doua varianta
este, evident, preferata, deoarece se scuteste un drum pana la server, pentru
ca acolo sa se constate ca datele sunt invalide. Am prefera deci ca n codul
HTML care se trimite clientului sa existe invocare de cod JavaScript care
sa verice, pe cat posibil, daca regulile de validare a datelor de intrare sunt
satisfacute.
Pentru a evita scrierea acestui cod de validare manual, sau introdus
urmatoarele controale de validare:
<asp:RequiredFieldValidator> - verica daca un camp de intrare are
continut;
<asp:RangeValidator> - determina daca valoarea specicata ntrun
control de intrare are valoarea cuprinsa ntre doua margini precizate;
<asp:CompareValidator> - verica daca valoarea unui control este ntr
o relatie anume cu alta valoare;
61

62CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE


<asp:RegularExpressionValidator> - verica daca valoarea unui control
satisface o anumita expresie regulata;
<asp:CustomValidator> - pentru cazurile n care logica de validare nu
se regaseste printre controalele enumerate anterior;
<asp:ValidationSummary> - arata un sumar al erorilor de validare
pentru controalele carora li s-a asociat validator
Pentru un control se poate specica mai mult de un validator; de exemplu,
pentru un textbox se poate asocia un validator de tip RequiredFieldValidator
care verica daca continutul casutei de text este nevid; suplimentar, se poate
asocia un validator de expresie regulata, pentru a vedea daca continutul satisface un anumit format. Este chiar cerut a se asocia validatorul de camp
cerut, deoarece pentru un RegularExpressionValidator (ca de altfel si
pentru RangeValidator si CompareValidator), testul de validare se considera trecut daca intrarea este lasata goala.
Controalele de preluare a datelor care sunt validate sunt: TextBox, ListBox, DropDownList, RadioButtonList, HtmlInputText, HtmlTextArea, HtmlSelect. Cand se valideaza un control de tip lista (care contine particula
List n denumire), se valideaza proprietatea Value pentru obiectul ListItem
curent selectat.

4.1.1

Pasii de validare

Validarea se porneste atunci cand utilizatorul apasa un buton (sau link


sau ImageButton) care determina trimiterea formularului catre server. Fiecare componenta pomenita are o proprietate numita CausesValidation de
tip boolean care daca are valoarea true atunci se va face validarea paginii.
Validarea se face iterand peste controale si vericand daca sunt ndeplinite
conditiile specicare. Pentru validatoarele care nu sunt respectate, se retrimite pagina, cu indicarea cazurilor care nu au fost respectate. Scenariul
descris corespunde situatiei n care n browserul folosit pentru asare nu se
permite executare de cod JavaScript; daca se permite si validatoarele nu sunt
respectate, atunci pagina nici macar nu mai ajunge sa e trimisa catre server,
ci se va asa direct mesajul de eroare pentru ecare validator nevalidat n
parte.

4.1.2

Clasa BaseValidator

Toate validatoarele sunt derivate din clasa BaseValidator. Proprietatile


esentiale propagate n derivati sunt:


4.1. CONTROALE DE VALIDARE A INTRARII

63

ControlToValidate id-ul controlului pentru care se aplica validarea;


este necesar a specicat;
Display cum anume se aseaza mesajul de eroare; daca este specicata valoarea Static, atunci spatiul necesar asarii este prealocat; daca
este specicata valoarea Dynamic, atunci la asarea acestui continut
se va produce deplasarea elementelor ce-i urmeaza pentru a face loc
continutului;
EnableClientScript pentru valoarea true, se va permite apelarea
de cod JavaScript pe client, pentru a verica validitatea;
Enabled specica daca este o validare activata sau nu;
ErrorMessage mesajul de eroare care va asat ntrun control
ValidationSumary, daca exista asa ceva;
Text textul de eroare care se va asa daca validatorul nu este respectat;
ValidationGroup se refera la posibilitatea de grupare de validatori
n mai multe grupuri;

4.1.3

Validatorul RequiredFieldValidator

Verica daca un control are sau nu continut introdus. Implicit, se va


verica daca textul este vid (sau contine doar spatii); daca se doreste ca
aceasta comparatie sa se faca cu un sir de caractere specicat de utilizator,
atunci valoarea aceasta se poate da n propietatea InitialValue. Daca
continutul textbox-ului coincide cu aceasta valoare initiala (dupa aplicarea
unei operatii de Trim pe continutul controlului), atunci se raporteaza eroare
de validare.
Exemplu:
1
2
3
4
5
6

<asp:TextBox ID="txtUserName" runat="server"></asp:TextBox>


<asp:RequiredFieldValidator ID="RequiredFieldValidatorUserName"
runat="server" ControlToValidate="txtUserName"
ErrorMessage="Numele lipseste">
*
</asp:RequiredFieldValidator>
Daca se trimite formularul prin apasarea de buton iar casuta de text este
goala, atunci se va asa o steluta rosie n dreptul casutei gura 4.1. Textul

64CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE


specicat n proprietatea ErrorMessage este vizibil doar daca pe pagina se
mai adauga si un control de tip ValidationSummary, cu rezultatul din gura
4.2.
1

<asp:ValidationSummary ID="sumarValidare" runat="server" />

Figura 4.1: Validator de valoare ceruta

Figura 4.2: Validator de valoare ceruta, cu sumarizator de validare

4.1.4

Validatorul RangeValidator

Se foloseste pentru a verica daca o valoare specicata este intr-un interval specicat prin intermediul proprietatilor MinimumValue si MaximumValue;
tipul de date pentru care se face comparatie este specicat n proprietatea
Type. Se pot specica tipurile:
Currency


4.1. CONTROALE DE VALIDARE A INTRARII

65

Date
Double
Integer
String
1
2
3
4
5
6

<asp:TextBox runat="server" ID="DayOff" />


<asp:RangeValidator runat="server" Display="dynamic"
ControlToValidate="DayOff" Type="Date"
ErrorMessage="Day Off is not within the valid interval"
MinimumValue="08/05/2008" MaximumValue="08/20/2008">*
</asp:RangeValidator>

4.1.5

Validatorul CompareValidator

Se folosete pentru a verica daca valoarea specicata ntr-un control este


ntr-o relatie (mai mare, mai mic etc) cu o valoare specicata, sau chiar cu
valoarea unui alt control.
Prin proprietatea Operator se specica relatia pe care trebuie sa o aibe
controlul la care este atasata validarea (vazut aici ca membru stang al relatiei
binare) cu o alta valoare. Optiunile sunt: Equal, NotEqual, GreaterThan,
GreaterThanEqual, LessThan, LessThanEqual si DataTypeCheck. Ultima
valoare este utila pentru a verica daca valoarea din control se poate reprezenta n tipul de date specicat via Type.
1
2
3
4
5
6

<asp:TextBox runat="server" ID="Age" />


<asp:CompareValidator runat="server" Display="dynamic"
ControlToValidate="Age" ValueToCompare="18"
ErrorMessage="You must be at least 18 years old"
Type="Integer" Operator="GreaterThanEqual">*
</asp:CompareValidator>
O alta situatie des ntalnita este cand trebuie soecicat ntrun textbox o valoare care sa coincida cu cea scrisa n alt textbox, de exemplu
la validarea unei parole alese. Pentru aceasta, se va specica proprietatea
ControlToCompare cu referinta la celalalt textbox de comparatie:

1
2
3

<asp:TextBox runat="server" TextMode="Password" ID="Password" />


<asp:TextBox runat="server" TextMode="Password" ID="Password2" />
<asp:CompareValidator runat="server"

66CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE


ControlToValidate="Password2" ControlToCompare="Password"
ErrorMessage="The passwords dont match"
Type="String" Display="dynamic">
<img src="imgError.gif" alt="The passwords dont match" />
</asp:CompareValidator>

4
5
6
7
8

4.1.6

Validatorul RegularExpressionValidator

Este utilizat n cazul n care se doreste specicarea unei expresii regulate


fata de care sa se faca validarea. Exemplul cel mai des invocat este cel al
unei adrese de email, cu reprezentarea (acceptabila, dar si alte variante mai
1
inspirate se pot da) .*@.{2,}.{2,}
.

<asp:TextBox runat="server" ID="Email" />


<asp:RegularExpressionValidator runat="server"
ControlToValidate="Email"
ValidationExpression=".*@.{2,}\..{2,}"
ErrorMessage="E-mail is not in a valid format"
Display="dynamic">*
</asp:RegularExpressionValidator>

1
2
3
4
5
6
7

4.1.7

Controlul CustomValidator

Exista situatii care validarea nu poate facuta cu ce sa prezentat mai


sus; e se invoca resurse de pe server (vericarea unor date din baza de date,
sau logica specica domeniului), e este vorba de un sir de pasi care denesc
validarea. Pentru aceasta situatie se foloseste CustomValidator. Codul se
poate executa pe parte doar de server sau de server + client.
Numele functiei JavaScript care se apeleaza pentru validarea n browser se
specica ca valoarea a proprietatii ClientValidationFunction, iar metoda
din code-behind se refera cu atributul asp.net onservervalidate. Pentru
ambele functii, ca prim argument se specica validatorul care a declansat
evenimentul de vericare, iar al doilea parametru este un argument care
da acces la valoarea controlului pentru care se face validarea, mpreuna cu
posibilitatea de a seta validitatea starii.
Pentru JavaScript, funtia de validare a faptului ca numarul este divizibil
cu 5 este:
<script type="text/javascript">
function myFunction(ctl, args) {

1
2
1

A se vedea Regular Expression Library.


4.1. CONTROALE DE VALIDARE A INTRARII

67

args.IsValid = (args.Value % 5 == 0);

3
4
5

}
</script>
iar pe partea de code-behind:

1
2
3
4
5
6
7
8
9
10
11
12

protected void CustomValidator1_ServerValidate(object source,


ServerValidateEventArgs args)
{
if (int.Parse(args.Value) % 5 == 0)
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}
}

referirea lor n cadrul controlului ind:


1
2
3
4
5
6
7

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>


<asp:CustomValidator ID="myValidator" runat="server"
ErrorMessage="Numarul nu e divizibil cu 5"
ClientValidationFunction="myFunction"
ControlToValidate="TextBox1" Display="Dynamic"
onservervalidate="CustomValidator1_ServerValidate">*
</asp:CustomValidator>

4.1.8

Controlul ValidationSummary

Acest control nu este prevazut pentru validare, ci pentru a strange un


sumar al erorilor din pagina. De la ecare validator care semnaleaza eroare se
preia continutul proprietactii ErrorMessage si se arata e n pagina, e ntro fereastra JavaScript, daca proprietatea ShowMessageBox are valoarea true.
Modul de asare a erorrilor este specicat de proprietatea DisplayMode, cu
valorile: SingleParagraph, List, BulletList.

4.1.9

Grupuri de validare

Pentru paginile mai stufoase, se poate imagina o grupare a controalelor


(de exemplu, prin obiecte de tip Panel). Proprietatea ValidationGroup se

68CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE


poate specica la nivel de control de validare, sub forma unui sir de caractere;
de asemenea, ecare buton care produce postback poate sa specice o valoare
pentru aceeasi proprietate; la apasarea lui, se face vericarea validatoarelor
doar pentru cele care au acelasi grup ca si butonul actionat. Pentru toate
celelate validatoare care nu fac parte din grup, se omite partea de vericare
a corectitudinii.

4.2

Manipulatoare HTTP

Manipulatoarele HTTP (n original: HTTP handlers) sunt modalitati


de a produce un raspuns de catre motorul de ASP.NET pentru o cerere
venita. In sectiunea <httpHandlers> a sierului web.config se afa o suita de
subelemente <add> care specica cine anume va raspunde la o cerere pentru
un anumit tip de sier (aspx, axd etc). De exemplu, cererile catre siere cu
extensia cong sau cs sunt manipulate de catre HttpForbiddenHandler care
genereaza o exceptie.
Pentru crearea unui manipulator HTTP se scrie o clasa care implementeaza interfata IHttpHandler; interfata obliga la implementarea metodei
ProcessRequest() si a proprietatii readonly IsReusable. Metoda efectueaza ntreaga munca (consultare de resurse, implementare de logica a
aplicatiei, vericari), iar proprietatea comunica motorului de ASP.NET daca
obiectul de manipulare de HTTP este reutilizabil sau trebuie neaparat distrus
si refacut de la 0 pentru o alta cerere.
Exemplu:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

using System;
using System.Web;
namespace TestHTTPHandler
{
public class SimpleHandler : IHttpHandler
{
public void ProcessRequest(System.Web.HttpContext context)
{
HttpResponse response = context.Response;
response.Write("<html><body><h1>Rendered by the SimpleHandler");
response.Write("</h1></body></html>") ;
}
public bool IsReusable
{
get {return true;}

4.2. MANIPULATOARE HTTP


17
18
19

69

}
}
}
In sierul web.cong, n sectiunea httpHandlers se adauga intrarea:

<add verb="*" path="fisier.fis" type="TestHTTPHandler.SimpleHandler"/>


Daca n adresa se specica "sier.s", atunci se va apela o instanta a clasei
TestHTTPHandler.SimpleHandler care va produce documentul HTML:

<html><body><h1>Rendered by the SimpleHandler</h1></body></html>


Pentru IIS 5.x sau 6, serverul nu va recunoaste extensia s (mai corect: nu
va invoca handlerul denit de noi) ci va cauta sierul cu numele sier.s;
negasindu-l, va returna o eroare. Pentru a obtine comportamentul descris
mai sus, trebuie facuta o mapare la nivel de extensie de sier din panoul de
control al serverului IIS (comanda inetmgr.exe).
O alta posibilitate de a lucra cu aceste manipulatoare de HTTP este denirea unor siere cu extensia ashx care pot apelate de catre utilizator sau
de browser. Potentialul acestei abordari este mare: se poate servi continut
provenind din cereri atipice, de exemplu se pot cere imagini sau alte resurse
care sunt stocate n baza de date. Pe langa forma de stocare diferita, se
poate sa se implementeze niste pasi autorizare, decorare a datelor, ltrare
care sa permita accesarea datelor avand n vedere o politica complexa.
Exemplul dat mai jos implementeaza urmatorul scenariu: ntro pagina
HTML dorim sa avem referinte catre imagini care se aa undeva pe harddisk,
dar nu neaparat n directoare gasite sub directorul aplicatiei web. Deoarece
referita la o imagine se face cu o adresa relativa la radacina aplicatiei web, este
nevoie de a specica o cale catre siere prin intermediul unui manipulator
de HTTP. Construim un HTTP handler sub forma de sier ashx care, la
metoda ProcessRequest va interoga query string-ul fp (cheie stabilita de
catre noi) care va copia sierul imagine referit de query string n uxul celui
care a facut cererea. In felul acesta, o imagine poate avea atributul src
cu valoarea ImageLoader.ashx?fp=d:\images\winter.jpg (dupa fp se poate
scrie orice permite determinarea unica a caii catre sier).

1
2
3
4
5
6

using
using
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Web;
System.IO;
System.Web.Services;

70CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

namespace AlbumFoto
{
/// <summary>
/// loads an image from the disk
/// </summary>
[WebService(Namespace = "http://cs.unitbv.ro/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class ImageLoader : IHttpHandler
{
/// <summary>
/// Enables processing of HTTP Web requests by a custom
/// HttpHandler that implements the
/// <see cref="T:System.Web.IHttpHandler"/> interface.
/// </summary>
/// <param name="context">An
/// <see cref="T:System.Web.HttpContext"/>
/// object that provides references to the intrinsic
/// server objects
/// (for example, Request, Response, Session, and Server)
/// used to service HTTP requests.</param>
public void ProcessRequest(HttpContext context)
{
string fileFullPath = context.Request.QueryString["fp"];
if (String.IsNullOrEmpty(fileFullPath))
{
return;
}
int posLasDot = fileFullPath.LastIndexOf(".");
string fileType = fileFullPath.Substring(posLasDot + 1)
.ToLower().Trim();
if (fileType == "jpg")
{
fileType = "jpeg";
}
context.Response.ContentType = "image/" + fileType;
BinaryReader br = new BinaryReader(
File.OpenRead(fileFullPath));
int bufferLength = 1024;

4.3. CONTROALE UTILIZATOR


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

71

byte[] buffer;
while ((buffer = br.ReadBytes(bufferLength)).Length > 0)
{
context.Response.OutputStream.Write(
buffer, 0, buffer.Length);
}
br.Close();
}
public bool IsReusable
{
get
{
return true;
}
}
}
}

4.3

Controale utilizator

Va urma...

72CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE

Capitolul 5
Teme, pagini master, navigare
Temele permit specicarea de detalii vizuale pentru paginile web. Se
permite astfel completarea facilitatilor CSS. Pentru un site se pot deni mai
multe teme, care se pot aplica individual, pentru ecare utilizator in parte.

5.1

Cascading Style Sheets

Folosind Cascading Style Sheets (CSS) reprezinta modalitatea de separare


a aspectului vizual de partea de continut; mai mult decat atat, permite
centralizarea acestor reguli de stil si reutilizarea lor. Regulile CSS se refera
la modul n care vor decorate vizual elementele HTML de catre browser.
Regulile sunt aplicate de catre browser asupra codului HTML primit de la
server.
O regula se poate referi n cazul cel mai simplu la numele de element
caruia i se va aplica:
body
{
font-family: Verdana, Arial, Sans-Serif;
font-size: small;
}

1
2
3
4
5

De exemplu, pentru codul de mai sus se arata ca regula se aplica elementului


body, fontul ind: Verdana, sau daca acesta nu este disponibil n browser,
atunci Arial, sau daca nici acesta nu este disponibil, atunci se va folosi
fontul Sans-Serif implicit al browserului1 . Alternativ, pentru un anumit
(sau orice) element, stilul se poate aplica doar daca elementul respectiv are
1

Despre fonturi sans serif: aici.

73

74

CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE

denita o clasa anume. De exemplu, n listingul de mai jos, stilul se aplica


oricui are clasa heading1, precum n <p class="heading1">continut</p>:
1
2
3
4
5
6
7

.heading1
{
font-weight: bold;
font-size: large;
color: lime;
font-family: Verdana, Arial, Sans-Serif;
}
O foaie de stiluri un sier CSS poate specica un set de reguli, care
sunt invocate n pagina HTML prin intermediul unui link din cadrul elementului head:

1
2

<link href="StyleSheet.css" rel="stylesheet"


type="text/css" />

Stilurile se aplica cu predilectie elementelor HTML, dar se pot specica


si controalelor Web server, folosind atributul CssClass.

5.2

Teme

Stilurile CSS se pot aplica usor elementelor de tip HTML sau controalelor,
dar ele vin cu un continut x, specic HTML-ului: dimensiunea fontului,
culoarea fundalului etc. Se pune ntrebarea: cum anume se poate aplica ideea
de stil si pentru proprietatile unui control ASP.NET? avand n vedere ca un
asemenea control poate veni cu proprietati al caror nume nu se regaseste n
ceea ce pune la dispozitie CSSul, avem nevoie de o modalitate de a completa
facilitatile acestuia din urma. Spre exemplu ne propunem sa setam stilul unui
control de tip Calendar; avand n vedere ca acest control este particularizat
prin proprietati specice claselor ASP.NET, vrem sa completam facilitatile
CSSului.
Diferentele ntre stilurile CSS si temele ASP.NET sunt:
1. Temele sunt asociate controalelor, nu CSS-uluil; dar temele preiau ideea
de baza a CSS-ului, denirea de stil si reutilizarea lui pentru obtinerea
unui layout unitar;
2. Temele sunt aplicate de catre server; sierul CSS mentionat pentru o
pagina HTML este descarcat de catre browser si interpretat tot de catre
el;

5.2. TEME

75

3. Temele pot aplicate prin intermediul sierelor de congurare; aceasta


permite aplicarea unei teme paginilor dintr-un ntreg folder fara a
nevoie sa se modice paginile aspx
4. Temele nu se aplica n aceeasi ordine ca si stilurile CSS; daca se specica
o proprietate ntro tema si ntr-un control, atunci setarea din tema este
cea care se aplica
Toate temele se denesc n cate un director din directorul numit App_Themes
aat direct n radacina aplicatiei web. La un moment dat, pentru o anumita
pagina cel mult o tema este activa. Pentru a deni o tema, este nevoie sa
se deneasca cel putin un sier text cu extensia skin. Un sier skin contine
declaratii de controale ASP.NET, pentru care se pot specica proprietatile
dorite:
1
2

<asp:ListBox runat="server" ForeColor="White"


BackColor="Orange"/>
Spre deosebire de declaratiile asemanatoare din paginile aspx, atributul
id nu se poate specica; atributul runat trebuie sa e prezent, iar n rest orice
alt atribut poate sa lipseasca. Se pot crea mai multe siere skin, de exemplu
ecare continand declaratii pentru controale nrudite. Exista posibilitatea de
a deni siere de skin si la nivel global, dar acest lucru este nerecomandat,
din cauza ca ngreuneaza instalarea aplicatiei pe alte servere.
Exemplu de sier skin:

1
2
3

<asp:ListBox runat="server" ForeColor="White" BackColor="Orange"/>


<asp:TextBox runat="server" ForeColor="White" BackColor="Orange"/>
<asp:Button runat="server" ForeColor="White" BackColor="Orange"/>
Pentru a aplica o tema anume unei pagini, se poate proceda n mai multe
feluri: se poate folosi atributul Theme n cadrul directivei Page, avand valoarea numele directorului de tema dorit:

<%@ Page Language="C#" AutoEventWireup="true" ... Theme="FunkyTheme" %>


O alta varianta este specicarea proprietatii Theme a paginii curente n code
behind:

1
2
3
4

protected void Page_PreInit(object sender, EventArgs e)


{
Theme = "FunkyTheme";
}

76

CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE

Mentionam ca tema se poate seta n code behind doar n evenimentul de


Page_PreInit, eveniment care se declanseaza nainte de Page_Load. In ambele cazuri, efectul este acelasi.
Daca se doreste ca un anumit control sa nu e mbracat conform setarilor
de tema, se poate specica n cadrul paginii aspx atributul EnableTheming
cu valoarea false.
Pentru un acelasi control se pot specica mai multe skin-uri, precum mai
jos:
1
2
3
4
5
6
7
8
9
10
11
12

<asp:ListBox runat="server" ForeColor="White"


BackColor="Orange" />
<asp:TextBox runat="server" ForeColor="White"
BackColor="Orange" />
<asp:Button runat="server" ForeColor="White"
BackColor="Orange" />
<asp:TextBox runat="server" ForeColor="White"
BackColor="DarkOrange"
Font-Bold="True" SkinID="Dramatic" />
<asp:Button runat="server" ForeColor="White"
BackColor="DarkOrange" Font-Bold="True"
SkinID="Dramatic" />

Specicarea skin-ului cu nume, va trebui specicata pentru controlul n


cauza din pagina aspx proprietatea SkinID avand valoarea identicatorul de
skin:
1
2

<asp:Button ID="Button1" runat="server" ...


SkinID="Dramatic" />

In cadrul unui director de tip tema, se poate de asemenea crea un sier de


tip CSS. Daca o pagina foloseste tema curenta, atunci se va aplica automat
si stilul CSS din directorul temei. Acest lucru este util daca:
se doreste aplicarea de CSS pentru elemente HTML care nu corespund
controalelor server;
se considera ca CSS-urile, ind standardizate, ar trebui folosite mai
mult;
aceste siere CSS deja exista si se doreste utilizarea lor, fara a nevoie
ca sa e rescrise sub forma de teme
Exista o oarecare problema: pentru a putea schimba tema la momentul
rularii, deci pentru a aplica CSS-ul din directorul noii teme, este nevoie

5.3. PAGINI MASTER

77

ca sa se poata modica elementul link din interiorul portiunii de head.


Modicarea se face automat daca elementul head are precizat atributul runat
cu valoarea server.
Temele se pot aplica si prin intermediul sierului de congurare, n sectiunea
system.web:
<configuration>
<system.web>
<pages theme="FunkyTheme" />
</system.web>
</configuration>

1
2
3
4
5

Daca o pagina are specicata tema, atunci aceasta din urma specicare are
prioritate fata de ceea ce apare n sierul web.cong.
Dupa cum sa aratat mai sus, temele pot aplicate dinamic, prin interventie
din code behind:
1
2
3
4
5
6
7
8
9
10
11
12
13
14

protected void Page_PreInit(object sender, EventArgs e)


{
if (Session["Theme"] == null)
{
// No theme has been chosen. Choose a default
// (or set a blank string to make sure no theme
// is used).
Page.Theme = "";
}
else
{
Page.Theme = Session["Theme"] as String;
}
}

unde depunerea n sesiune sar face prin alegerea dintr-o lista de optiuni (un
control de tip DropdownList).

5.3

Pagini master

Pentru crearea unei structuri unitare a unui site, se pot folosi variantele:
controale utilizator; pot utilizate pentru a implementa principiul
dont repeat yourself, dar nimeni nu poate sa sa garanteze ca acest
continut, chiar daca e identic, este si dispus identic;

78

CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE


frameuri HTML; nu mai sunt suportate de standardul XHTML; motivele pentru care frame-urile sunt considerate o alegere nepotrivitasunt
dezbatute n peste 7000 de tratari ale subiectului aici.
pagini master varianta standard n ASP.NET.

O pagina master permite crearea unui sablon care va aplicat peste niste
pagini de tip continut. Utilizarea unei pagini master pentru tot site-ul
determina o aparitie consistenta a acestor pagini. Folosind pagini master,
sa raspuns urmatoarelor probleme:
se deneste o singura data o portiune de pagina care poate reutilizata
ori de cate ori se doreste
se denesc regiunile editabile, adica acele zone n care o pagina ce
foloseste sablonul are voie sa adauge continut;
suport din partea unei unelte precum Visual Studio
se permite particularizarea unor aspecte din pagina master, din pagini
de continut
O pagina master este un sier cu extensia master. Foloseste un model
de declarare similar cu cel al paginilor aspx, adica pagina pe care se pot
depune controale si parte de code-behind. Adaugarea unei pagini master se
face asemanator cu adaugarea unei pagini obisnuite de tip aspx. Rezultatul
va :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<%@ Master Language="C#" AutoEventWireup="true"


CodeBehind="MyMasterPage.master.cs"
Inherits="WebApplication1.MyMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">

5.3. PAGINI MASTER


16
17
18
19
20
21
22
23
24

79

<div>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1"
runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>

Controlul de tip ContentPlaceHolder nu are proprietati deosebite, doar


ca specica locul n care o pagina care vrea sa aplice acest sablon si va depune
continutul. Altfel zis, aceasta este partea n care se va asa continutul variabil dat de diverse pagini. Remarcam ca pagina master deneste partea de
nceput a sierului HTML (elementele html, head, body). Se remarca faptul
ca elementul head apare n interiorul unui control de tip ContentPlaceHolder,
ceea ce are sens, deoarece astfel se poate specica ulterior continut suplimentar: elemente link, script-uri Java, tag-uri meta etc, cu valori specice
ecarei pagini continut.
O pagina care foloseste un master page se numeste pagina continut2 ;
legatura dintre ea si pagina master trebuie specicata explicit, n directiva
Page:
1

<%@ Page Language="C#" MasterPageFile="~/MyMasterPage.master" ... %>


Specicarea caii cu ~ la nceput se refera la radacina site-ului; daca se foloseste
direct numele sierului de master, atunci se va cauta ntrun director al
carui nume este MasterPages; daca sierul nu este gasit, atunci se cauta n
radacina site-ului.
O pagina continut nu va mai deni partea de html, head, body, deoarece
acestea sunt deja date de catre master page; va avea n schimb un control de
tip asp:Content, care prin intermediul atributului ContentPlaceHolderID
specica n ce control de tip ContentPlaceHolder va asezat:

1
2
3
4
5
6
7

<%@ Page Title="" Language="C#"


MasterPageFile="~/MyMasterPage.Master" AutoEventWireup="true"
CodeBehind="WebForm1.aspx.cs"
Inherits="WebApplication1.WebForm1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1"
2

In original: content page.

80

CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE


runat="server">
</asp:Content>

8
9

Se remarca atributul Title din directiva Page, care permite stabilirea


unui titlu pentru pagina, chiar daca elementul title este prezent n pagina
master.
Un master page tipic arata precum n gura 5.1 ([2]),
Design-ul se poate face mai evoluat folosind CSS, precum n listing-ul
urmator:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

.leftPanel
{
position: absolute;
top: 70px;
left: 10px;
width: 150px;
}
.rightPanel
{
position: absolute;
top: 70px;
right: 10px;
width: 150px;
}
.centerPanel
{
margin-left: 151px;
margin-right: 151px;
padding-left: 12px;
padding-right: 12px;
}

invocat de catre divuri prin:


1
2
3
4
5
6

<div class="leftPanel">...</div>
<div class="centerPanel">
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
<div class="rightPanel">...</div>
O porblema care poate aparea este calea relativa catre diferite resurse
(imagini, siere cod JavaScript) invocata n master page. De exemplu, daca

5.3. PAGINI MASTER

81

Figura 5.1: Structura unei pagini de tip master


se creeaza un folder numit MasterPages si n el se depune o pagina master,
care invoca o imagine precum:
1

<img src="banner.jpg" />

atunci la design in VS 2008 pagina se vede bine; daca se foloseste o pagina


continut ntrun alt folder, atunci la asare va lipsi imaginea, deoarece ea
este cautata relativ la pagina continut. Codul de imagine de mai sus ind
de tip HTML, serverul nu l proceseaza, iar browserul nu gaseste imaginea
n directorul unde se aa pagina de continut.
O rezolvare rapida este transformarea codului HTML al imaginii n control de tip server HTML, iar n aceasta situatie calea catre imagine este
interpretata de catre server (si nu de browser) ca o cale relativa la pagina
master. O a doua varianta este specicarea caii pentru acest control de tip
server folosind locatia absoluta pornind de la radacina serverului cu ~:
1

<img src="~/MasterPages/banner.jpg" runat="server" />


Ca ordine de executare a evenimentelor, se poate vedea, folosind facilitatea de Trace din pagini ca se executa prima data partea de Page.PreInit
din master page, apoi Page.PreInit din content page; Page.Load din master

82

CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE

page, apoi Page.Load din content page; astfel se asigura faptul ca codul din
pagina continut are ultimul cuvant.
Exista situatii n care din pagina de continut se doreste accesarea paginii
master, de exemplu penqtru a accede la ceva publicat de catre pagina master:
1
2
3
4
5

public string BannerText


{
get { return lblTitleContent.Text; }
set { lblTitleContent.Text = value; }
}
Se poate obtine acces la aceasta proprietate prin proprietatea Master:

1
2
3
4
5
6

protected void Page_Load(object sender, EventArgs e)


{
SiteTemplate master =
Master as SiteTemplate;
master.BannerText = "Content Page #1";
}
Conversia cu as este necesara, deoarece proprietatea Master este de tip
MasterPage. Pentru a se evita conversia, se poate folosi o directiva n cadrul
paginii continut:

<%@ MasterType VirtualPath="~/SiteTemplate.master" %>

si atunci partea de ncarcare a paginii de mai sus devine:


1
2
3
4

protected void Page_Load(object sender, EventArgs e)


{
Master.BannerText = "Content Page #1";
}
Spargand ncapsularea, se poate accesa direct continutul din masterpage:

1
2
3
4
5

Label lbl = Master.FindControl("lblTitleContent") as Label;


if (lbl != null)
{
lbl.Text = "hello from content page;
}
Daca se doreste modicarea de master page dinamic, se poate, prin
actionarea asupra proprietatii Page.MasterPageFile n cadrul evenimentului Page.Init. Mecansimul e util daca se doreste adaptarea de master
page la tipul de vizitator, sau se doreste a s eface co-branding.

5.4. NAVIGARE

5.4

Navigare

Va urma...

83

84

CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE

Capitolul 6
Legarea la date
Legarea la date1 reprezinta capacitatea unui control ASP.NET de a-si
prelua continutul din diverse surse: baze de date clasice, proprietati, metode,
servicii web etc. Dupa ce continutul este preluat, e asat conform specicului
controlului.
Un rol la fel de important l au sursele de date, controale prin intermediul
carora se determina care este provenienta datelor; ele actioneaza ca o punte
de legatura ntre datele asate si controalele ASP.NET; suplimentar, mai
permit si specicarea modului de manipulare a lor: datele se sterg, se adauga,
se modica. Este remarcabila exibilitatea de utilizare a lor, permitand
specicarea legaturii ntre controale si date e exclusiv declarativ (fara sau
cu foarte putin cod pe parte de codebehind), e prin cod, daca se doreste
personalizare.
Modul n care functioneaza acest mecanism este declarativ, folosind cod
scris n pagina aspx, acolo unde se precizeaza care e controlul de asare. Se
separa partea de codebehind de cea de specicare a sursei de date.
Exista doua feluri de legari de date: pentru date simple (unice) si pentru
date multiple. In primul caz este vorba de controale de tip eticheta, buton,
LinkButton, Image pentru care se poate specica o singura valoare care va
folosita. Se folosesc aici expresiile de legare.
Alte controale suporta asarea de mai multe valori sau legarea cu valori
repetate. De exemplu, putem avea o lista de butoane radio, un tabel, sau
combobox-uri. Toate acestea expun o proprietate DataSource, care accepta
un obiect de sursa de date. Cand se specica valoare pentru aceasta proprietate (e declarativ, adica n pagina aspx, e prin codebehind), se creeaza
o legatura de la controlul de asare la datele ce urmeaza a prezentate; mai
trebuie apelata doar metoda DataBind() la nivel de control sau de pagina
1

In original: data binding.

85

86

CAPITOLUL 6. LEGAREA LA DATE

pentru a se face efectiv popularea.

6.1

Legarea la date simple

Pentru controalele care suporta legarea la date simple adica date care
au o singura valoare si nu o multime de valori se foloseste o expresie de
legare. Expresia apare n partea de cod aspx; este delimitata de portiunile
<%# si %>:
<%# expresie %>

De exemplu, daca avem o proprietate de tip string numita NumeUtilizator


n pagina, atunci se poate ca expresia de legare la date sa e:
<%# NumeUtilizator %>

Pentru evaluarea unei expresii de legare trebuie sa se apeleze metoda


DataBind pentru pagina sau pentru controlul respectiv, altfel nu se va asa
nicio valoare. Daca este vorba de o metoda sau proprietate sau camp din
clasa de code behind, pentru ca sa se poata utiliza n expresie de legare
de date, e nevoie ca gradul de accesibilitate sa e public, protected sau
internal.
Urmatoarele exemple de expresii sunt valide:
<%#
<%#
<%#
<%#

1
2
3
4

GetUserName() %>
1 + (2 * 20) %>
"John " + "Smith" %>
Request.Browser.Browser %>

O expresie de legare la date se poate scrie oriunde n pagina, dar de regula


se precizeaza pentru o proprietate a unui control:
1
2
3
4
5
6
7
8
9
10
11

<asp:Image ID="image1" runat="server"


ImageUrl=<%# FilePath %> />
<br />
<asp:Label ID="label1" runat="server"
Text=<%# FilePath %> />
<br />
<asp:TextBox ID="textBox1" runat="server"
Text=<%# GetFilePath() %> />
<br />
<asp:HyperLink ID="hyperLink1" runat="server"
NavigateUrl=<%# LogoPath.Value %>

6.1. LEGAREA LA DATE SIMPLE


12
13
14
15
16

87

Text="Show logo" />


<br />
<b><%# FilePath %></b>
<br />
<img src="<%# GetFilePath() %>">

Expresiile pot precizate chiar si n afara formularului HTML.


Apelarea codului de legare la date adica evaluarea efectiva a expresiilor
si introducerea lor n codul HTML ce va trimis catre browser se face printrun apel precum:
1
2
3
4

protected void Page_Load(object sender, System.EventArgs e)


{
this.DataBind();
}
Se poate apela metoda DataBind() si n alte metode, nu doar n event handlerul de ncarcare de pagina.
Un alt tip de expresie ce sa introdus odata cu .NET Framework 2.0 este:

<%$ AppSettings:numeSetare %>

referinduse la un nume de setare care se specica n sierul de congurare


n sectiunea appSettings:
1
2
3

<appSettings>
<add key="numeSetare" value="valoare din fisierul de configurare"/>
</appSettings>
Un exemplu de utilizare este:

<asp:Literal Runat="server" Text="<%$ AppSettings:numeSetare %>" />


Exista cateva diferente ntre aceasta expresie de legare de date si cea
precedenta:
Nu e nevoie sa se apeleze metoda DataBind() pentru evaluarea expresiei, aceasta din urma facanduse automat;
Expresiile cu $ nu se pot insera oriunde n pagina, spre deosebire de
cele cu #; ele se aplica numai controalelor pentru a specica o valoare
de proprietate; daca se doreste doar sa se aseze valoarea expresiei, se
va folosi un control de tip Literal, precum sa exemplicat mai sus;

88

CAPITOLUL 6. LEGAREA LA DATE


prima parte a expresiei cu $ indica numele entitatii care e folosita pentru evaluare; avem la dispozitie AppSettings, ConnectionStrings sau
Resources.

Expresia este des utilizata pentru referirea la un string de conexiune pentru


o sursa de date:
1
2

<asp:SqlDataSource
ConnectionString="<%$ ConnectionStrings:Northwind %>" ... />

6.2

Legarea la date multiple

Sunt cazuri n care un control este conceput nu pentru asarea unei date
simple, ci a unei ntregi colectii; colectia poate sa e un vector de elemente,
set de nregistrari din baza de date etc. Controalele care pot asa colectii de
elemente sunt:
HtmlSelect, ListBox, DropDownList
CheckBoxList si RadioButtonList
BulletedList care creeaza o lista cu buline sau numerotata
Fiecare va asa o singura valoare care provine dintr-o proprietate a unui
element ce se aseaza. Proprietatile care se specica la nivelul controalor de
asare sunt:
DataSource se refera la un obiect de date care contine o colectie de
date ce se vor asate;
DataSourceID reprezinta identicatorul unui control de tip sursa de
date; se specica e valoare pentru ea, e pentru DataSource;
DataTextField reprezinta numele proprietatii din ecare element care
se vrea a asat, ce va aparea vizibil n pagina HTML;
DataTextFormatString specica modul de formatare pentru ceea ce
se va asa;
DataValueField - reprezinta un nume de proprietate, a carui valoare
se evalueaza pentru ecare element care va asat; deosebirea fata
de DataTextField este ca valoarea nu se afseaza n browser, ci este
transmisa prin formular; de regula, reprezinta o cheie de identicare a
ecarui element.

6.2. LEGAREA LA DATE MULTIPLE

89

Exemplu: setam o colectie de perechi de forma cheie-valoare, stocate ntr


un dictionar; se face popularea pentru diferite controale de tip multivaloare.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

<form id="form1" runat="server">


<div>
<select id="Select1" name="Select1" runat="server"
datatextfield="Key" datavaluefield="value">
<option></option>
</select>
<select id="Select2" multiple="true" name="Select2"
runat="server" datatextfield="Key"
datavaluefield="Value">
<option></option>
</select>
<asp:ListBox ID="ListBox1" runat="server"
DataTextField="Key" DataValueField="Value">
</asp:ListBox>
<asp:DropDownList ID="DropDownList1" runat="server"
DataTextField="Key" DataValueField="Value">
</asp:DropDownList>
<asp:CheckBoxList ID="CheckBoxList1" runat="server"
DataTextField="Key" DataValueField="Value">
</asp:CheckBoxList>
<asp:RadioButtonList ID="RadioButtonList1" runat="server"
DataTextField="Key" DataValueField="Value">
</asp:RadioButtonList>
</div>
</form>

Pe partea de code behind avem:


1
2
3
4
5
6
7
8
9
10
11

Dictionary<string, string> myDictionary = new Dictionary<string, string>();


myDictionary.Add("key1", "aa");
myDictionary.Add("key2", "ab");
myDictionary.Add("key3", "ac");
Select1.DataSource = myDictionary;
Select2.DataSource = myDictionary;
ListBox1.DataSource = myDictionary;
DropDownList1.DataSource = myDictionary;
CheckBoxList1.DataSource = myDictionary;
RadioButtonList1.DataSource = myDictionary;

90
12
13

CAPITOLUL 6. LEGAREA LA DATE

Page.DataBind();

Efectul este cel din gura 6.2.

Determinarea pe partea de code-behind a elementelor selectate din controale se face folosind proprietatea SelectedIndex pentru ecare control n
parte.
Legarea la date multiple poate avea ca sursa orice tip de date care implementeaza interfata ICollection, exemplele notabile ind: colectii ArrayList,
Hashtable, Collection si clase din ADO.NET DataReader sau DataView.

6.3

Controale de date bogate

Pe langa listele pomenite mai exista posibilitatea de a folosi niste controale de date de tip tabelar, anume introduse pentru asarea de date. Ele
permit asarea mai multor proprietati din ecare element, de exemplu lista
tuturor valorilor campurilor dintro nregistrare. Controalele sunt:
GridView: folosite pentru a arata tabele mari cu date; permit paginare,
selectare, editare, stergere de date;
DetailsView: arata un singur element la un moment dat, ntr-o tabela
cu o linie pentru ecare camp asat; permite editarea
FormView: ca precedentul, dar permite denirea unor sabloane ce ofera
mai multa exibilitate
Pentru un GridView, o declaratie sucient de buna este:
1

<asp:GridView ID="grid" runat="server" AutoGenerateColumns="true" />

6.4. CONTROALE DE SURSE DE DATE

91

iar legarea de date se face prin specicarea unei valori adecvate pentru proprietatea DataSource, ce se leaga la un obiect de tip DataReader sau de tip
DataTable.
Legarea la un obiect DataReader duce la un consum mic de memorie, dar
este inecienta pentru multe scenarii, deoarece nu permite ltrare pe serverul
de aplicatii, sau sortare. De asemenea, nu poate folosit pentru legare la mai
multe controale, simultan. Se poate folosi un set de date deconectat (clasa
DataSet), care n plus are si avantajul de a agnostica relativ la tipul de
server de date folosit.
Aceste aspecte vor prezentate ntrun curs urmator.

6.4

Controale de surse de date

Reprezinta puntea de legatura ntre o coletie de date si controalele care le


aseaza. Ele implementeaza interfata IDataSource. Sunt oferite urmatoarele:
SqlDataSource: pentru legaturi la servere de baze de date sau la surse
de date precum ODBC;
ObjectDataSource: pentru legaturi la clase;
AccessDataSource: pentru baze de date Access (siere cu extensia
mdb);
XmlDataSource: pentru legaturi catre documente XML;
SiteMapDataSource: pentru legaturi catre sier Web.sitemap care contine
structura unui site.

6.5

Ciclul de viata
al unei pagini Web

Evenimentele dintr-o pagina ASP.NET se succed astfel:


1. PreInit se pot face urmatoarele: vericarea proprietatii IsPostBack,
creare/recreare de controale dinamice, setarea paginii master, setarea
temei, setarea sau citirea valorilor din prol;
2. Init se poate folosi pentru initializarea sau citirea proprietatilor controalelor;
3. InitComplete pentru apelarea de cod care asigura efectuarea tuturor
initializarilor;

92

CAPITOLUL 6. LEGAREA LA DATE


4. PreLoad se poate scrie cod care sa se apeleze nainte de apelarea
metodei Load;
5. Load apeleaza metoda OnLoad a ecarui control din pagina, recursiv;
se pot seta proprietati si stabili conexiuni la baza de date;
6. evenimente de control precum apasarea de buton, schimbarea indexului activ dintr-un dropdownlist;
7. LoadComplete cod care trebuie executat dupa ce sa facut initializarea
tuturor controalelor din pagina;
8. PreRender dupa el se apeleaza metoda DataBind pentru ecare control care are proprietatea DataSourceID setata; la acest eveniment se
specica cod care trebuie executat pentru setari nale asupra controalor din pagina;
9. SaveStateComplete nainte de acest eveniment, ViewState-ul a fost
salvat pentru pagina curenta; orice schimbare de stare de la acest punct
este ignorata;

10. Render se apeleaza metoda Render pentru ecare control continut;


11. Unload se apeleaza aceasta metoda pentru ecare control n parte;
n ecare control aceasta metoda poate folosita pentru a face disponibilizari de resurse (altceva decat memorie);
Legarea la date se petrece n urmatorii doi pasi:
1. controlul de sursa de date efectueaza toate modicarile cerute - update,
insert, delete. Fiecare din aceste trei modicari are cate doua evenimente asociate, procesate prin metode al caror nume se termina cu
ing si ed: Inserting, Inserted; acest moment apare imediat dupa
rularea handlerelor de eveniment pentru controale;
2. se apeleaza interogarile de date iar datele aduse sunt injectate n controalele de asare; aici se apeleaza metodele Selecting si Selected; pasul
este efectuat imediat dupa evenimentul PreRender
Ultimul pas de mai sus poate aduce a redundanta si apel ne-necesar n
cazul n care nu sa facut nicio modicare pe baza de catre utilizator; chiar
asa si este, iar acest aspect poate mbunatatit prin folosirea mecanismelor
de caching.

6.6. SURSA DE DATE SQLDATASOURCE

6.6

93

Sursa de date SqlDataSource

Se declara n pagina aspx sub forma:


1

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ... />

si reprezinta o sursa de date care foloseste furnizor de date ADO.NET. Se


pot deci folosi urmatoarele variante de furnizori:
System.Data.SqlClient
System.Data.OracleClient
System.Data.OleDb
System.Data.Odbc
Tipul de furnizor se specica prin proprietatea ProviderName:
1

<asp:SqlDataSource ProviderName="System.Data.SqlClient" ... />

6.6.1

Selectarea de nregistr
ari

Pentru un control SqlDataSource trebuie sa se specice care este comanda ce aduce elementele selectate. Suplimentar, se pot seta comenzi
de stergere, modicare, inserare. Proprietatile se numesc: SelectCommand,
InsertCommand, UpdateCommand, DeleteCommand, toate de tip string. Valorile lor pot fraze SQL sau denumiri de proceduri stocate aate pe server.
Crearea unui control care aduce setul tuturor angajatilor - a se arata la
curs;
De aratat:
crearea de comenzi parametrizate de tip select; alegerea valorii se face
dintr-un dropdownlist
ca mai sus, cu alegerea din QueryString (2 pagini aspx); varianta: la
Selecting se seteaza valoarea parametrului din clauza where;
update pe gridview; atentie la numele de parametri;
optimistic lock;
stergere pentru tabela; de precizat rolul proprietatii DataKeyNames
pentru gridview; de procesat exceptie, de aratat pe o tabela nelegata
de altele;
inserare folosind DetailsView

94

CAPITOLUL 6. LEGAREA LA DATE

6.6.2

Dezavantaje ale SqlDataSource

Desi usor de utilizat, exista cateva probleme care fac folosirea lui SqlDataSource
neinspirata pentru proiecte de anvergura mare:
1. logica de acces la date este continuta n pagina ASP.NET; este greu
de facut calibrare pentru aceste interogari, proling-ul e greu de implementat;
2. mentenanta dicila: ecare pagina care foloseste legarea la date ar
trebui sa aibe propriul set de date; reutilizarea este inexistenta; daca
trebuie modicata o interogare scrisa ca si cod SQL direct n pagina,
atunci trebuie schimbat peste tot la fel; problema are o mbunatatire
usoara (dar nu totala) prin folosirea de proceduri stocate, care duc nsa
la o alta problema - scrierea logicii de business n codul SQL;
3. lipsa de exibilitate - ecare control care se populeaza ar avea nevoie
de propriul control de date; daca pentru o pagina se prevad mai multe
variante de asare a datelor, atunci pagina se va umple rapiud de controale de date;
4. daca se iese din scenariul interogare/update-delete-insert pe aceeasi
baza de date, codul devine incurcat si greu de mentinut; o biblioteca
de implementare a logicii aplicatiei sau chiar si numai de acces la date
simplica enorm codul.

6.7

Sursa de date ObjectDataSource

Nu se foloseste un furnizor de date SQL ca la cazul precedent, ci se face


conexiunea cu o clasa sau un obiect care implementeaza logica de furnizare a
datelor; poate o componenta de tip business logic, sau o biblioteca de acces
la date care se bazeaza pe un data mapper care creeaza obiecte din domeniul
aplicatiei exibilitate maxima.
Conditii impuse de acest mod de lucru (dar restrictiile sunt suportabile):
Pentru ecare interogare, logica trebuie sa e integrata ntro singura
metoda a unei clase; asta favorizeaza modelul simplu de transaction
script sau crearea unei clase de tip business facade. lucru de altfe si
recomandat;
Trebuie sa returneze rezultatul cerut sau sa duca la efectuarea respectivei operatii;

6.7. SURSA DE DATE OBJECTDATASOURCE

95

Rezultatul unei interogari de tip select trebuie sa e o colectie de


elemente, precum un DataSet, DataTable, DataView sau colectie de
obiecte; ecare astfel de obiect ar trebuie sa si expuna valorile prin
proprietati publice si nu campuri!
se pot folosi metode instante sau statice; n primul caz trebuie sa existe
un constructor implicit pentru clasa care furnizeaza serviciul, n celalalt
nu se mai poate folosi polimorsmul;
obiectul trebuie sa e fara stare.

96

CAPITOLUL 6. LEGAREA LA DATE

Capitolul 7
Controale de lucru cu datele
7.1

Controlul GridView

Pasi:
1. denirea coloanelor; tipuri de coloane:
(a) BoundField
(b) ButtonField
(c) CheckBoxField
(d) CommandField
(e) HyperLinkField
(f) ImageField
(g) TemplateField
2. ascunderea, schimbarea ordinii coloanelor - declarativ si din code-behind
3. proprietati: DataField, DataFormatString, HeaderText, FooterText,
HeaderImageUrl, ReadOnly, InsertVisible, Visible, SortExpression, HtmlEncode, NullDisplayText, ConvertEmptyStringToNull

7.1.1

Formatare

Exemplu: {0:C} - parametrul este formatat sub forma de valoare monetara, in functie de setarile serverului web sau de partea de globalizare;
{0:MM/dd/yy} - Month, day, year.
97

98

CAPITOLUL 7. CONTROALE DE LUCRU CU DATELE

7.1.2

Stiluri

Se seteaza stilurile CSS pentru:


HeaderStyle
RowStyle
AlternatingRowStyle
SelectedRowStyle
EditRowStyle
EmptyDataRowStyle
FooterStyle
PagerStyle
Stiluri: ForeColor, BackColor, BorderColor, BorderStyle, BorderWidth,
Height, Width, HorizontalAlign, VerticalAlign, Font, Wrap; alternativ: se
poate folosi proprietatea CssClass; se poate alege dintr-o serie de stiluri predenite; demo: GridStyles.aspx
Formatare la momentul incarcarii, prin tratarea evenimentului RowDataBound - demo: RuntimeFormatting.aspx

7.1.3

Selectarea de linie din GridView

Evenimente: SelectedIndexChanging, SelectedIndexChanged; demo:


SelectRow.aspx

7.1.4

Sortare

Demo pentru GridView cu SqlDataSource; demo pentru ObjectDataSource - GridViewObjectDataSourceSorting.aspx


Problema: la sortare indexul elementului curent selectat ar trebui pus pe
-1, deoarece prin sortare, indexul selectat este pus pe o inregistrare care se
gaseste pe pozitia selectata anterior; repunerea pe aceeasi inregistrare sortata
se poate face, dar trebuie mentinuta valoarea selectata in viewstate si apoi
parcurs intregul grid;
Important: proprietatea EnableSortingAndPagingCallbacks.

7.2. CONTROALELE FORMVIEW, DETAILSVIEW

7.1.5

99

Paginare

Demo; modul in care se face paginare in SQL Server 2005+, folosind


Common Table Expressions (CTE)

7.1.6

Template-uri

Demo:
adaugare de campuri template; creare de coloana cu valoare compusa:
TemplateCampCompus.aspx
template-uri de editare - se pot adauga validatoare; se pot alege campurile care se editeaza; se poate modica modul in care arata controlul de
editare - e.g. control dropdown; demo: EditTemplate1.aspx; data binding bidirectional = metoda Bind(); folosire de dropdownlist pentru
TitleOfCourtesy = EditTemplate2.aspx;

7.2

Controalele FormView, DetailsView

100

CAPITOLUL 7. CONTROALE DE LUCRU CU DATELE

Capitolul 8
JavaScript si Ajax
Factorul esential ce faciliteaza comunicarea dintre client (browser) si server (codul ASP.NET) este trimiterea formularului dispre browser catre server, de regula catre aceeasi pagina postback. Evident, acest postback este
dependent de existenta unui cod de reactie pe server, cod care sa produca o
modicare a starii paginii.
Exista nsa destule situatii n care reactia poate avea loc doar pe client,
fara a nevoie sa se faca trimiterea formularului catre server. Se scuteste astfel o deplasare catre si dinspre server, ceea ce creeaza impresia unei interfete
utilizator care raspunde rapid clientului. De exemplu, expandarea elementelor dintr-un meniu sau expandarea nodurilor dintr-un arbore, sau ascunderea
unor elemente de pe ecran (tabele, randuri, imagini) se poate efectua de regula doar cu resurse locale se actioneaza asupra portiuni din pagina. Toate
aceste efecte sunt obtinute prin utilizarea codului JavaScript care este executat de catre browserul clientului.
Cursul prezinta tehnici de integrare a codului JavaScript cu ASP.NET.

8.1

Elemente de baz
a JavaScript

JavaScript permite scrierea de cod client, executat de catre browser.


JavaScript este vazut actualmente ca un dialect al ECMAScript1 ; este un
limbaj slab tipizat (variabilele nu si declara tipurile de date decat arareori), dinamic (permit modicarea codului si a tipurilor de date, n timpul
executiei), interpretat. Codul JavaScript este inclus direct n documentul
HTML sau referit de catre acesta; el e descarcat de catre browser si rulat.
Pentru a include cod JavaScript n pagina HTML, se poate proceda astfel:
1

Standard definit de Ecma International, standard aprobat si de ISO/IEC


Standard ECMA-262, ECMAScript Language Specification.

101

102

CAPITOLUL 8. JAVASCRIPT S I AJAX

se deneste tratarea unui eveniment pentru un control HTML direct


sub forma codului care va executat;
se adauga un element <script> care contine cod JavaScript. Elementul
contine cod care se executa atunci cand browserul ajunge sa l ncarce
sau codul unei functii care poate apelata direct sau indirect ca parte
a procesarii unui eveniment.
Actionarea de catre codul JavaScript asupra componentelor din pagina
se face prin HTML DOM (Document Object Model), adica DHTML. Evenimentele care pot declansa apelul unui cod JavaScript sunt:
onchange - apare atunci cand se schimba starea unui control - selectare/deselectare a unui checkbox, mutarea focusului din textboxul curent
pe alt control etc;
onclick - apare atunci cand se apasa click de mouse pe un control
onmouseover - cand mouse-ul se misca deasupra unui control
onmouseout - cand mouse-ul se misca n afara controlului
onkeydown, onkeyup - cand utilizatorul apasa/elibereaza o tasta
onfocus - atunci cand un control primeste focusul
onload - apare atunci cand o pagina se termina de ncarcat
onunload - apare atunci cand o pagina este pe cale de a descarcata
din browser (chiar dupa ce s-a dat clic pe un link sau s-a introdus o
noua adresa pentru browser)
Aceste evenimente pot setate declarativ:
1
2
3
4
5
6

<form>
<input id="myText" type="text"
onmouseover="window.alert(mouse over);"/>
<input type="button"
onclick="window.confirm(esti sigur(a)?);"); />
</form>
In cazul n care este vorba de un buton denit ca Web server control,
numele onclick este deja utilizat pentru a face corespondenta cu metoda din
code-behind care face procesarea evenimentului pe server; ca atare, numele
de eveniment de pe client se deneste folosesind OnClientClick. Tratarea
evenimentelor poate specicata si din code-behind, folosind proprietatea
Attributes; de exemplu:

8.2. BLOCURI DE SCRIPT


1
2
3
4
5
6
7
8
9
10
11
12
13
14

103

<form id="form1" runat="server">


<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</div>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click"
Text="Ataseaza eveniment JavaScript" />
</form>
protected void Button1_Click(object sender, EventArgs e)
{
TextBox1.Attributes.Add("onmouseover",
"window.alert(Mouse plutind peste textbox);");
}

8.2

Blocuri de script

Daca bucata de cod JavaScript care se scrie pentru tratarea de eveniment


este de dimensiuni mai mari sau se reutilizeaza, atunci este mai practic ca
scrierea sa se faca ntro sectiune dedicata, cuprinsa n interiorul elementului
<script>. Elementul preia un atribut prin care se specica limbajul n care
sunt scrise instructiunile. Daca browserul nu accepta scripturi JavaScript,
atunci aceasta sectiune este ignorata:
1
2
3
4
5
6
7

<script type="text/javascript">
<!-var i = 7;
window.alert(Mesaj afisat cand browserul ajunge
cu incarcarea in acest loc);
//-->
</script>
Comentariile sunt necesare pentru browserele care nu inteleg codul JavaScript,
iar comentariul // era util pentru cazul in care se folosea anumite versiuni de
Netscape. Cele mai multe browsere actuale nteleg codul JavaScript, chiar
daca unele sunt setate sa nu l execute.
Dupa cum da de nteles codul de mai sus, se declara o variabila numita i
careia i se da valoarea 7; ea va vizibila n ntreaga pagina. Apoi browserul
executa instructiunea de asare a unei ferestre de mesaj. Comportamentul
este util pentru cazul n care la o anumita portiune din pagina html este
nevoie sa se execute un anumit cod.

104

CAPITOLUL 8. JAVASCRIPT S I AJAX

Daca se doreste ca un bloc de instructiuni sa nu e executat de ndata ce


browserul l ncarca, se poate folosi o functie denita de programator:
1
2
3
4
5

<script type="text/javascript">
function showMessage(message){
window.alert(message);
}
</script>
Un loc des folosit pentru scrierea de functii este sectiunea <head> a paginii
web, ceea ce permite o regasire mai usoara. Apelarea functiei denite anterior
este posibila prin:

1
2
3

<asp:TextBox ID="TextBox1" runat="server"


onmouseover="showMessage(mouse peste textbox);">
</asp:TextBox>
iar efectul este redat n gura 8.2.

Figura 8.1: Rezultatul apelarii functiei JavaScript.


Se observa ca pentru o functie JavaScript nu se declara tipul de retur. O
varianta des folosita este scrierea codului JavaScript ntr-un sier cu extensia
consacrata js care este ncarcat de catre browser. Adresa sierului este data
sub prin atributul src al elementrului script:
1
2

<script type="text/javascript" src="scripts/myCode.js">


</script>

8.3. MANIPULAREA ELEMENTELOR HTML

8.3

105

Manipularea elementelor HTML

Schimbarea continutului paginii se face prin identicarea elementului/elementelor de pagina ce trebuie schimbat/schimbate; n cazul unui element al
carui id se cunoaste, ind specicat ca valoare a atributului id, identicarea
se face prin intermediul metodei document.getElementById():
1

var myElement = document.getElementById(textbox1);


Daca este vorba de regasirea unei familii de elemente nrudite, se poate folosi document.getElementsByTagName sau document.getElementsByName.
Odata recuperate elementele de interes, se schimba starea lor tot prin instructiuni
JavaScript. Proprietatile uzuale sunt:
innerHTML - reprezinta continutul HTML dintre eticheta de deschidere
si de nchidere;
style - permite referirea elementelor de stil din elementul curent; de
exemplu, myElement.style.fontSize se foloseste pentru schimbarea
dimensiunii fontului unui element;
value - reprezinta starea curenta a controlului; de exemplu, starea unui
checkbox sau textul dintr-o casuta de text;
parentElement - da acces la elementul parinte; util pentru a muta sau
sterge elementul curent;

8.4

Utilizare de JavaScript pentru nc


arcare asincron
a a paginilor

Urmatorul exemplu este preluat din [2]. Sa presupunem ca se doreste


ncarcarea ntr-un gridview a unor detalii legate de o lista de carti (nume,
editura, ISBN) si a pozei lor. Randarea ntregii tabele de catre browser poate
sa ia mult timp daca sunt multe date sau daca pozele se ncarca greu; se poate
folosi un truc care pacaleste rabdarea persoanei care asteapta ncarcarea paginii: ca poza se ncarca o imagine neutra, pe post de placeholder; deoarece
este una singura pentru tot gridul, o data ncarcata pentru o celula, devine
instantaneu asabila pentru toate celelate celule (facilitate oferita de browser). Ulterior, pentru ecare carte se cere de catre browser imaginea efectiva,
prin cod JavaScript. Timpul necesar pentru ncarcarea completa a gridului
cu tot cu imaginile respective nu scade, dar utilizatorul poate sa nceapa sa
citeasca pagina si sa deleze pe ecran.
Gridul poate sa e declarat astfel:

106
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

CAPITOLUL 8. JAVASCRIPT S I AJAX


<asp:GridView id="GridView1" runat="server"
AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title"/>
<asp:BoundField DataField="isbn" HeaderText="ISBN"/>
<asp:BoundField DataField="Publisher" HeaderText="Publisher"/>
<asp:TemplateField>
<HeaderTemplate>
Book Cover
</HeaderTemplate>
<ItemTemplate>
<img src="UnknownBook.gif"
onerror="this.src=Unknownbook.gif;"
onload=
"GetBookImage(this, <%# DataBinder.Eval(
Container.DataItem, "isbn") %>);"
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Accentul cade pe ultimul camp de pe ecare linie, care este n prima faza o
referinta catre o imagine neutra, aata n aplicatia web, iar cand se termina
de ncarcat (lucru de altminteri rapid), se face apel de functie JavaScript care
va cere ncarcarea imaginii aferente ecarui ISBN. Aceasta a doua ncarcare
poate lenta, motivul pentru care se foloseste mecanismul prezentat.
Functia GetBookImage este:
1
2
3
4
5
6
7
8
9
10

<script language="javascript" type="text/javascript">


function GetBookImage(img, url)
{
// Detach the event handler (the code makes just one attempt
// to get the picture).
img.onload = null;
// Try to get the picture from the GetBookImage.aspx page.
img.src = GetBookImage.aspx?isbn= + url;
}
</script>

Pagina GetBookImage.aspx (se putea folosi si un manipulator de HTTP,


adica cod ashx) este cea care face ncarcarea imaginii respective, e dintr-un
serviciu extern aplicatiei web curente, e din baza de date. Etapele ncarcarii
sunt date n gurile 8.2 si 8.3.


A PAGINILOR107
8.4. UTILIZARE DE JAVASCRIPT PENTRU INCARCARE
ASINCRONA

Figura 8.2: Aparitia initiala a paginii [2]

Figura 8.3: Incarcarea imaginilor n pagina [2]

108

CAPITOLUL 8. JAVASCRIPT S I AJAX

8.5

Includerea blocurilor JavaScript din codebehind

Uneori este mai exibil ca includerea de cod JavaScript sa se faca la rulare, daca se ndeplinesc anumite condtii. Pentru aceasta se poate folosi proprietatea Page.ClientScript care expune cateva metode pentru gestiunea
blocurilor de script. Metodele sunt:
1. RegisterClientScriptBlock() - scrie un bloc de script la nceputul
formularului web, chiar dupa <form runat="server">;
2. RegisterStartupScript() - scrie un bloc la sfarsitul formularului web,
chiar nainte de </form>.
Ca un argument al functiilor se specica un nume de script; acesta trebuie
sa e un string unic, rolul lui este de a se asigura ca nu se adauga acelasi
script de doua ori. De exemplu, pentru includerea repetata de controale care
folosesc JavaScript, mecanismul duce la inserarea doar a unui singur script.
De exemplu, codul de mai jos produce includerea unui script care aseaza
o fereastra de conrmare la trimiterea formularului - vezi si gura 8.4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14

protected void Page_Load(object sender, EventArgs e)


{
string script = @"
<script type=text/javascript>
function myConfirm()
{
return confirm(Vrei trimiterea datelor?);
}
</script>
";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"confirmare", script);
Page.Form.Attributes.Add("onsubmit", "return myConfirm();");
}

Mecanismul este util n situatia n care exista controale utilizator care folosesc
JavaScript.
O alta varianta este includerea unui bloc de script care face referinta catre
un sier JavaScript:
1
2
3

string includeScript = @"scripts/myscript.js";


Page.ClientScript.RegisterClientScriptInclude("myInclude",
includeScript);

8.6. ATACURI DE INJECTARE DE SCRIPT

109

Figura 8.4: Executarea de cod JavaScript adaugat prin inregistrare de bloc


de script
care duce la includerea n codul HTML, n interiorul formularului, a codului:
1
2

<script src="scripts/myscript.js" type="text/javascript">


</script>

8.6

Atacuri de injectare de script

Unul din fenomenele la care este vulnerabila o pagina web este atasarea
de cod JavaScript de catre utilizator. De exemplu, n interiorul unui textbox
se poate scrie cod JavaScript, ceea ce duce la executarea lui pe client; sau
folosirea de elemente HTML n text poate duce la modicarea asarii n
pagina. Daca datele sunt preluate pur si simplu de la utilizator si introduse
n baza de date, la reasarea lor pentru un alt utilizator, executandse pe
client, pot afecta pe toti ceilalti utilizatori.
Aceste script-uri se pot trimite via elementele <script>, <object>, <applet>,
<embed>. O varianta simpla de rezovare este de a face codicarea caracterelor
folosind metoda Server.HtmlEncode.
Implicit, ASP.NET poate sa determine daca continutul unei casute de
text are potential de injectare de script. Pentru o pagina cu un textbox si
un buton ce produce postback - gura 8.5, comportamentul dictat de server
este cel dat n gura 8.6 - adica frameworkul ASP.NET depisteaza automat
introducerea de elemente HTML si reactioneaza prin respingere:
Se poate inhiba comportamentul de respingere al ASP.NET-ului, prin
specicarea proprietatii ValidateRequest din cadrul directivei Page, de la
nceputul paginii aspx:
1

<%@ Page ValidateRequest="false"...

110

CAPITOLUL 8. JAVASCRIPT S I AJAX

Figura 8.5: Incercare de trimitere de cod JavaScript prin textbox

Figura 8.6: Respingere de catre ASP.NET


In aceasta situatie, reasarea naiva a stringului din textbox ntr-un label
duce la injectarea unui cod JavaScript n pagina, cod care va executat de
catre browser - vezi gura 8.7.
1
2
3
4

protected void Page_Load(object sender, EventArgs e)


{
myLabel.Text = TextBox1.Text;
}

Figura 8.7: Inhibarea respingerii de cod JavaScript


Validarea stringurilor trimise de catre utilizator poate inhibata pentru
ntregul site, prin specicarea n sierul web.cong a elementului pages, cu

8.7. JAVASCRIPT PENTRU CONTROALE UTILIZATOR

111

atributul ValidateRequests avand valoarea false:


1
2
3
4
5

<configuration>
<system.web>
<pages validateRequest="false" />
</system.web>
</configuration>
Pentru a preveni executarea de cod JavaScript pentru pagini care au specicata inhibarea validarii cererilor, se poate folosi metoda de codicare a stringurilor HTML data de Server.HtmlEncode sau de HttpUtility.HtmlEncode:

1
2
3
4

protected void Page_Load(object sender, EventArgs e)


{
myLabel.Text = Server.HtmlEncode(TextBox1.Text);
}
modalitate care de fapt se recomanda ori de cate ori se face asare de text
preluat dintr-o sursa de date oarecare.

8.7

JavaScript pentru controale utilizator

In cazul dezvoltarii de controale utilizator, este indicat ca produsul realizat sa poata folosit ca un modul n pagina, fara a nevoie sa se cunoasca
detaliile de implementare; implicit, toata partea de cod JavaScript necesara
functionarii controlului trebuie sa e ascunsa n control. Exemplicarea ce
urmeaza este preluata din [2].
Sa peresupunem ca se vrea crearea de ferestre popup pentru incarcarea
diferitelor mesaje (reclame sau ajutor contextual). Acest lucru se face prin
JavaScript, pe baza codului:
1
2
3
4
5

<script type="text/javascript">
window.open(http://www.apress.com, myWindow,
toolbar=0, height=500, width=800, resizable=1, scrollbars=1);
window.focus();
</script>
Metoda JavaScript Open primeste ca prim parametru adresa paginii care
trebuie deschisa, numele ferestrei care se deschide util daca se doreste reutilizarea ferestrei popup, pentru incarcarea de continut nou apoi un sir
de perechi de forma nume=valoare, specicand diferite aspecte vizuale ale
ferestrei de popup: dimensiuni, daca este sau nu redimensionabila, daca sa

112

CAPITOLUL 8. JAVASCRIPT S I AJAX

arate sau nu barele de derulare, sau daca se aseaza n prim plan sau n
fundal.
Putem crea un control ascx care sa poata inclus n orice pagina; aspectele vizuale pot setate prin proprietati. Controlul va putea utilizat
ntro pagina web precum cele uzuale - etichete, casute de text etc. Avantajul controlului este ca permite reutilizarea usoara a codului, ntr-o maniera
declarativa.
Codul pentru pagina de popup (controlul ascx) este:
1

using
using
using
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Web;
System.Web.UI;
System.Web.UI.WebControls;
System.Text;

namespace DemoCurs8
{
public partial class CustomPopup : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.Request.Browser.EcmaScriptVersion.Major >= 1)
{
StringBuilder javaScriptString = new StringBuilder();
javaScriptString.Append("<script type=text/javascript>");
javaScriptString.Append("\n<!-- ");
javaScriptString.Append("\nvar popupWindow" + ID +
"= window.open(");
javaScriptString.Append(Url + ", " + ID);
javaScriptString.Append(",toolbar=0,");
javaScriptString.Append("height=" + WindowHeight + ",");
javaScriptString.Append("width=" + WindowWidth + ",");
javaScriptString.Append("resizable=" +
Convert.ToInt16(Resizable).ToString() + ",");
javaScriptString.Append("scrollbars=" +
Convert.ToInt16(ScrollBars).ToString());
javaScriptString.Append(");\n");
if (PopUnder) javaScriptString.Append("popupWindow" + ID +
".blur(); ");

8.7. JAVASCRIPT PENTRU CONTROALE UTILIZATOR

113

javaScriptString.Append("\n-->\n");
javaScriptString.Append("</script>\n");
Literal1.Text = javaScriptString.ToString();
}
}
public bool PopUnder
{
get
{
return (bool)ViewState["PopUnder"];
}
set
{
ViewState["PopUnder"] = value;
}
}
public string Url
{
get
{
return (string)ViewState["Url"];
}
set
{
ViewState["Url"] = value;
}
}
public int WindowHeight
{
get
{
return (int)ViewState["WindowHeight"];
}
set
{
if (value < 1)
{
throw new ArgumentException(@"WindowHeight must be

114

CAPITOLUL 8. JAVASCRIPT S I AJAX


greater than 0");
}
ViewState["WindowHeight"] = value;
}
}
public int WindowWidth
{
get
{
return (int)ViewState["WindowWidth"];
}
set
{
if (value < 1)
{
throw new ArgumentException(@"WindowWidth must be
greater than 0");
}
ViewState["WindowWidth"] = value;
}
}
public bool Resizable
{
get
{
return (bool)ViewState["Resizable"];
}
set
{
ViewState["Resizable"] = value;
}
}
public bool ScrollBars
{
get
{
return (bool)ViewState["ScrollBars"];
}

8.7. JAVASCRIPT PENTRU CONTROALE UTILIZATOR

115

set
{
ViewState["ScrollBars"] = value;
}
}
public CustomPopup()
{
PopUnder = true;
Url = "about:blank";
WindowHeight = 300;
WindowWidth = 300;
Resizable = false;
ScrollBars = false;
}
}
}
O pagina aspx care utilizeaza controlul ar :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

<%@ Page Language="C#" AutoEventWireup="true"


CodeBehind="UseCustomPopup.aspx.cs"
Inherits="DemoCurs8.UseCustomPopup" %>
<%@ Register src="CustomPopup.ascx" tagname="CustomPopup" tagprefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:CustomPopup ID="myCustomPopup" runat="server" PopUnder="true"
Url="http://localhost/index1.html" Resizable="true"/>
<uc1:CustomPopup ID="CustomPopup1" runat="server" PopUnder="false"
Url="http://localhost/index2.html" Resizable="true"/>
</div>
</form>

116
23
24

CAPITOLUL 8. JAVASCRIPT S I AJAX


</body>
</html>

O alta varianta de implementare este cea n care controlul se dezvolta ca


un control server particularizat2 , asa cum se arata n [2], capitolele 27 si 31.

8.8

Ajax

Pana acum, orice cerere de date dinspre server nseamna trimiterea formularului catre server si reasarea paginii. Ca efect, se observa activitatea
sacadata "click si asteapta", precum si faptul ca pagina este rencarcata, cu
saltul la nceputul ei. Desi pentru ASP.NET exista posibilitatea de a specica atributul MaintainScrollPositionOnPostback cu valoarea true n
cazul directivei de pagina, comportamentul vizual este acceptabil pe Internet Explorer, dar nesatisfacator pe Mozilla Firefox.
Ajax = Asynchronous JavaScript and XML este un grup de tehnici web
inter-relationate care permit dezvoltarea de aplicatii web interactive sau cu
un aspect asemanator cu cel al aplicatiilor ce ruleaza folosind doar resurse
locale. Prin Ajax se pot aduce date de la server, n mod asincron, fara a
necesara trimiterea propriu-zisa a formularului catre server; pagina ramane
ncarcata n browser, dar anumite portiuni din ea sufera modicari pe baza
continutului adus de la server.
JavaScript este de ajutor aici deoarece, presupunand problema preluarii
asincrone a datelor rezolvata, permite identicarea fragmentelor de document care trebuie sa e modicate si permite schimbarea lor. Totusi, doar
JavaScript nu este sucient, deoarece el se descurca cu resurse locale, n timp
ce pentru anumite actiuni utilizator este nevoie de preluare de date pe care
doar un server le poate furniza. Paginile care utilizeaza Ajax comunica n
fundal cu serverul; de ndata ce raspunsul este primit n ntregime, se efectueaza activitati aditionale. Din cauza caracterului asincron al comunicarii,
pagina nu este ntrerupta, iar utilizatorul poate sa efectueze si alte actiuni
n ea. Raspunsul poate furnizat sub forma unui document XML sau ca
un simplu text. Este responsabilitatea codului Ajax scris de programator sa
parcurga raspunsul si sa actioneze n consecinta.
Un aspect neplacut al programarii cu Ajax este faptul ca exista diferente
mari ntre browsere, ncepand chiar de la formularea cererii. Exista biblioteci
cross-browser care pot folosite n acest sens.
2

In original: custom server control.

8.8. AJAX

8.8.1

117

Obiectul XMLHttpRequest

Pentru a face comunicarea cu serverul dinspre pagina web, trebuie formulata o cerere catre server iar raspunsul trebuie sa e preluat. Ambele actiuni
sunt efectuate de obiectul XMLHttpRequest. Obtinerea lui se face diferentiat,
dupa browser: Internet Explorer 5 sau 6 foloseste ActiveX, iar IE7 si Mozilla
Firefox folosesc un obiect JavaScript nativ. Ca atare, codul de instantiere
a obiectului XMLHttpRequest trebuie sa e scris luand n considerare toate
variantele, deoarece nu se poate sti ce browser este folosit de catre client.
Codul este:
1
2
3
4
5
6
7
8
9
10
11
12

var xmlRequest;
try
{
// Asta merge daca XMLHttpRequest face parte din JavaScript.
xmlRequest = new XMLHttpRequest();
}
catch(err)
{
// altfel, se cere serviciu de la ActiveX
xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
//in acest punct obiectul XMLHttpRequest este instantiat

8.8.2

Trimiterea cererii

Pentru trimiterea unei cereri se folosesc metodele open() si send(). Prima


metoda seteaza datele de apel - adresa la care se face apelul si tipul de comanda HTTP (GET, POST, PUT). Exemplu:
1

xmlRequest.open("GET" , myURL);

URL-ul apelat poate sa contina un query string cu perechi de atribute si valori; ceea ce se aa la adresa referita trebuie sa poata prelua acesti parametri
si sa formuleze raspunsul n consecinta.
Se mai poate da un parametru optional care specica daca cererea trebuie sa e trimisa asincron (implicit) si nca doi care dau numele si parola
utilizatorului (nerecomandat).
Metoda send() trimite efectiv comanda catre server:
1

xmlRequest.send(null);

118

CAPITOLUL 8. JAVASCRIPT S I AJAX

8.8.3

Procesarea r
aspunsului

Raspunsul se proceseaza prin intermediul unui manipulator de eveniment


care este apelat atunci cand soseste raspunsul catre browser. Manipulatorul
este o functie JavaScript care se apeleaza de catre browser:
xmlRequest.onreadystatechange = UpdatePage;

Setarea event handlerului se face nainte de trimiterea cererii catre server


(naintea apelarii lui send).
Atunci cand raspunsul este primit, el poate accesat prin intermediul proprietactilor responseText si responseXML, proprietati ale obiectului XMLHttpRequest.
Prima proprietate da raspunsul sub forma unui sir de caractere; a doua metoda preia documentul ca un arbore de noduri. Se poate folosi si altceva
decat XML pentru crearea unui raspuns structurat, de exemplu JSON3 sau
cod HTML gata preformatat.

8.9

Un exemplu Ajax

Pentru crearea unei pagini ce foloseste Ajax e nevoie de:


pagina Web care sa foloseasca Ajax; nu e obligatoriu sa e forma web
(pagina aspx), poate o pagina HTML obisnuita;
O alta pagina (aspx) sau manipulator de HTTP (cod ashx) care sa
primeasca cererea si sa furnizeze un raspuns. Pagina sau handlerul
preia eventualii parametrii transmisi ca parte a adresei si formuleaza
un raspuns corespunzator.
In exemplul de mai jos raspunsul este furnizat de catre un HTTP handler;
acesta preia din query string doua valori, furnizate pentru atributele value1
si respectiv value2 si returneaza suma numerelor (daca se poate face suma);
se returneaza suma lor mpreuna cu data si timpul de pe server la care sa
efectuat calculul (cele doua valori - suma si momentul sunt despartite prin
virgula).
Codul pentru handlerul de HTTP care primeste cererea este:
using
using
using
using

1
2
3
4
3

System;
System.Collections.Generic;
System.Linq;
System.Web;

JavaScript Object Notation.

8.9. UN EXEMPLU AJAX


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

119

using System.Web.Services;
namespace DemoCurs8
{
/// <summary>
/// Summary description for $codebehindclassname$
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class HandlerCalculator : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
HttpResponse response = context.Response;
HttpRequest request = context.Request;
//tipul de raspuns este text simplu
response.ContentType = "text/plain";
int value1, value2;
if (
int.TryParse(request.QueryString["value1"], out value1) &&
int.TryParse(request.QueryString["value2"], out value2)
)
{
int sum = value1 + value2;
response.Write(sum.ToString());
response.Write(",");
response.Write(DateTime.Now.ToString());
}
else
{
response.Write("-");
}
}
public bool IsReusable
{
get
{
return true;
}

120
46
47
48

CAPITOLUL 8. JAVASCRIPT S I AJAX


}
}
}
Pentru pagina web care folosesste Ajax se scrie codul:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

<%@ Page Language="C#" AutoEventWireup="true"


CodeBehind="AjaxPage.aspx.cs" Inherits="DemoCurs8.AjaxPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Pagina care foloseste Ajax</title>
<script type="text/javascript">
var xmlRequest;
function CreateXMLHttpRequest() {
try {
// Asta merge daca XMLHttpRequest face parte din JavaScript.
xmlRequest = new XMLHttpRequest();
}
catch (err) {
// altfel, se cere serviciu de la ActiveX
xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
//in acest punct obiectul XMLHttpRequest este instantiat
}
function sendRequest()
{
xmlRequest.open("GET", "HandlerCalculator.ashx?value1=" +
document.getElementById(TextBoxValue1).value +
"&value2=" + document.getElementById(TextBoxValue2).value);
xmlRequest.onreadystatechange = UpdatePage;
xmlRequest.send(null);
}
function UpdatePage()
{
if (xmlRequest.readyState == 4)//primire completa de raspuns
{

8.9. UN EXEMPLU AJAX


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

121

if (xmlRequest.status == 200)//codul http este de tip "OK"


{
var response = xmlRequest.responseText;
var lblResult = document.getElementById(lblResult);
if (response == -)
{
lblResult.innerHTML = Nu se poate calcula suma;
}
else
{
var tokens = response.split(,);
lblResult.innerHTML = Suma este: + tokens[0] +
<br />Calculata la: + tokens[1];
}
}
}
}
</script>
</head>
<body onload="CreateXMLHttpRequest();">
<form id="form1" runat="server">
<div>
<img src="images/anilion1_e0.gif" alt="leu" /><br />
Primul numar:
<asp:TextBox ID="TextBoxValue1" runat="server"
onkeyup="sendRequest();"></asp:TextBox>
<br />
Al doilea numar:
<asp:TextBox ID="TextBoxValue2" runat="server"
onkeyup="sendRequest();"></asp:TextBox>
<br />
<asp:Label ID="lblResult" runat="server"></asp:Label>
</div>
</form>
</body>
</html>

122

CAPITOLUL 8. JAVASCRIPT S I AJAX

Capitolul 9
ASP.NET membership
ASP.NET pune la dispozitie un API pentru gestiunea utilizatorilor care
pot sa acceseze o aplicatie. Se ofera suport pentru urmatoarele operatii, care
n mod normal ar trebuie implementate de ecare data n cadrul unei aplicatii
web:
crearea si stergerea de utilizatori programatic sau prin interfata pusa
la dispozitie automat;
abilitatea de a reseta parole, cu posibilitatea de a trimite noua parola
prin email, daca a fost specicata o adresa;
posibilitatea de a se crea parole n mod automat, daca se foloseste
crearea programatica a utilizatorilor;
determinarea listei de utilizatori, mpreuna cu detaliile asociate;
controale predenite pentru loginare, creare de utilizator, resetare de
parola;
O ierarhizare a acestor functionalitati este data n gura 9.1.
Exemplicarea mecanismului se va face cu referire la serverul de baze
de date SQL Server 2005 Express Edition, pentru care exista suport nativ;
trebuie zis nsa ca daca se doreste personalizarea sursei de date care gestioneaza utilizatorii, acest lucru este posibil prin implementarea unui furnizor de
membership. API-ul furnizat este insenzitiv la modul de stocare al detaliilor legate de utilizator - particularitatile de accesare a datelor sunt rezolvate
la nivelul implementarii de furnizor de membership.
Pasii ce trebuie urmati pentru utilizarea unui API-ului de membership
sunt:
1. congurarea modului de autenticare n sierul web.cong;
123

124

CAPITOLUL 9. ASP.NET MEMBERSHIP

Figura 9.1: Elementele utilizate n lucrul cu membership-ul furnizat de


ASP.NET [2]


9.1. CONFIGURAREA AUTENTIFICARII
PRIN FORME

125

2. setarea detaliilor relativ la stocarea datelor utilizatorilor;


3. congurarea stringului de conexiune si a furnizorului de membership;
4. crearea de utilizatori ai aplicatiei web;
5. crearea unei pagini de login.

9.1

Configurarea autentific
arii prin forme

Trebuie mai ntai structurata aplicatia ca resurse protejate prin nume si


parola, grupate sub forma de directoare. De regula, n radacina aplicatiei
Web trebuie sa e lasate doar paginile care accepta accesare de utilizator
anononim (neautenticat), cum ar pagina de login sau cea n care se creeaza
contul. In rest, paginile sunt grupate n directoare pentru care se specica tot
prin sier de congurare ca nu se accepta decat apel de utilizator autenticat.
Primul pas e deci de a specica forma de autenticare. In sierul web.cong
din radacina aplicatiei se va scrie:
<system . web>
<a u t h e n t i c a t i o n mode="Forms" />
</system . web>
In forma de mai sus se permite accesarea anonima a paginilor.
Daca se doreste ca pentru directorul numit protejat sa se permita numai accesarea de catre utilizatori autenticati, atunci se va crea un sier
web.cong (comanda add new item din solution explorer) care sa contina:
<c o n f i g u r a t i o n >
<system . web>
<a u t h o r i z a t i o n >
<deny u s e r s=" ? " />
</ a u t h o r i z a t i o n >
</system . web>
</ c o n f i g u r a t i o n >
Simbolul ? refera un utilizator neautenticat. Datorita acestei setari, orice
utilizator care doreste sa acceseze o pagina aspx din directorul protejat va
vericat: daca are tichetul furnizat de un proces de autenticare, atunci i
se permite accesul; altfel, este redirectat automat la pagina de login.

126

9.2

CAPITOLUL 9. ASP.NET MEMBERSHIP

Crearea sursei de date

Daca se foloseste SQL Server Express Edition 2005 n conjunctie cu


ASP.NET, furnizorul de membership va crea automat un sier de date,
cu o structura bine denita, care va putea folosit pentru memorarea datelor utilizatorilor. Se va crea un sier numit ASPNETDB.MDF n directorul
App_Data al aplicatiei web. Desi functioneaza satisfacator pentru etapa de
dezvoltare, este total neadecvat pentru un sistem aat n productie. Daca
este o versiune de server diferita de ce s-a spus (de exemplu: SQL Server
2000 sau 2005 non-express), atunci se poate interveni pentru a crea aceasta
sursa de date n interiorul unui server, sau chiar n interiorul unei baze de
date preexistente. Aceasta varianta (evitarea sierului ASPNETDB.MDF) e
sugerata pentru sisteme de productie.
Pentru crearea structurii de tabele necesare pentru memorarea datelor de
autenticare se poate folosi utilizatrul din linie de comanda aspnet_regsql.exe,
pornit din varianta de command prompt realizata de instalarea lui .NET Framework. Pornirea uneltei n sistem wizard se face prin tastarea numelui
aplicatiei pomenite, dupa care va aparea fereastra din gura 9.2. Wizard-ul
permite e adaugarea structurilor de date necesare la un server, e stergerea
lor (gura 9.3). Ulterior, se specica: serverul SQL n care se va face salvarea datelor si contul de acces pentru server (cont necesar utilitarului) gura 9.4. In baza de date specicata se vor crea tabele precum se vede
n gura 9.5 care vor stoca datele legate de utilizatori, proluri, roluri etc.
Structura acestor tabele nu trebuie sa e nteleasa de catre programator, ea
va folosita de catre API-ul de membership.
Mentionam ca unealta de integrare poate folosita si exlusiv din linia de
comanda cu parametri, fara a nevoie sa se utilizeze wizardul grac din
gurile 9.2 - 9.5.

9.3

Configurarea stringului de conexiune si a


furnizorului de membership

Daca sa folosit utilitarul aspnet_regsql ca mai sus, atunci este nevoie


sa se specice n sierul de congurare web.cong stringul de conexiune care
va folosit pentru furnizorul de membership SQL. Acest lucru se face ca la
orice string de conexiune, prin adagarea n sectiunea connectionStrings a
unei intrari:
<c o n n e c t i o n S t r i n g s >
<add name="myConStrMembership"

9.3. CONFIGURAREA STRINGULUI DE CONEXIUNE S I A FURNIZORULUI DE MEMBERSHI

Figura 9.2: Utilitarul de congurare a sursei de date pentru autenticare

Figura 9.3: Specicarea modului de lucru pentru utilitarul aspnet_regsql

128

CAPITOLUL 9. ASP.NET MEMBERSHIP

Figura 9.4: Specicarea serverului, contului si bazei de date

Figura 9.5: Tabelele rezultate dupa utilizarea uneltei de integrare a serverului


de baze de date cu partea de SQL Membership din ASP.NET

9.3. CONFIGURAREA STRINGULUI DE CONEXIUNE S I A FURNIZORULUI DE MEMBERSHI


c o n n e c t i o n S t r i n g=" data s o u r c e =( l o c a l ) \ d e v e l o p ;
u s e r i d=sa ; password=1q2w3e
i n i t i a l c a t a l o g=t e s t " />
</ c o n n e c t i o n S t r i n g s >
Pentru a specica apoi metoda de autenticare, se va adauga n sierul
web.cong un element ce precizeaza modul de autenticare:
<system . web>
<a u t h e n t i c a t i o n mode="Forms" />
<membership d e f a u l t P r o v i d e r=" MyMembershipProvider ">
<p r o v i d e r s >
<add name=" MyMembershipProvider "
connectionStringName="myConStrMembership"
applic at ionN am e=" test_membership "
e n a b l e P a s s w o r d R e t r i e v a l=" f a l s e "
e n a b l e P a s s w o r d R e s e t=" t r u e "
requiresQuestionAndAnswer=" t r u e "
r e q u i r e s U n i q u e E m a i l=" t r u e "
passwordFormat=" Hashed "
type=" System . Web . S e c u r i t y . SqlMembershipProvider " />
</ p r o v i d e r s >
</membership>
</system . web>
In interiorul elementului membership pot exista mai multe elemente providers,
dar cel specicat prin intermediul atributului defaultProvider este cel aat
n uz. La lansarea interfetei de administrare a aplicatiei Project ASP.NET
Conguration se va putea alege dintre furnizorul implicit si cel denit anterior MyMembershipProvider asa cum se vede n gura 9.6.
Atributele elementului add din cadrul furnizorului denit sunt:
name - deneste un nume unic asociat furnizorului curent;
applicationName - numele aplicatiei web pentru care functioneaza furnizorul de securitate ales
description - o descriere optionala
passwordFormat - formatul n care vor salvate parolele n baza de
date; valori posibile: Clear, Encrypted, Hashed
minRequiredNonalphanumericCharacters - care este numarul minim de
caractere non-alfanumerice care sunt cerute n parola

130

CAPITOLUL 9. ASP.NET MEMBERSHIP

Figura 9.6: Congurare din aplicatia de administrare a aplicatiei Web


minRequiredPasswordLength - lungimea minima a parolei
passwordStrengthRegularExpression - o expresie regulata care descrie
formatul general pe care trebuie sa l respecte o parola;
enablePasswordReset - daca se permite suprascrierea unei parole uitate;
valori posibile: true, false
enablePasswordRetrieval - se precizeaza daca parola poate recuperata
prin apeluri de metode din API-ul de membership; posibil d.n.d nu sa
folosit varianta de Hashed
maxInvalidPasswordAttempts - numarul maxim de ncercari consecutive gresite suportate de sistem pentru un utilizator; daca se ajunge
la acest prag, contul utilizatorului este dezactivat pentru o anumita
perioada
passwordAttemptWindow - cat timp este blocat un utilizator care face
prea multe ncercari de introducere a unei parole;
requiresQuestionAndAnswer - daca pentru recuperarea parolei utilizatorul trebuie sa dea un raspuns la o ntrebare;

9.4. CREAREA DE UTILIZATORI

131

requiresUniqueEmail - specica daca adresa de email trebuie sa e


unica pentru utilizatorii care se nscriu n sistem

9.4

Crearea de utilizatori

Se poate crea un utilizator din interfata de management al aplicatiei Web:


tab-ul Security, apoi Create User, precum n gura 9.7.

Figura 9.7: Adaugarea unui utilizator


Din acest moment se poate folosi n partea de codebehind:
protected void LoginAction_Click ( object s e nde r , EventArgs e )
{
i f ( Membership . V a l i d a t e U s e r ( UsernameText . Text , PasswordText . Text ) )
{
F or m s A ut he nt ic at ion . RedirectFromLoginPage ( UsernameText . Text , f a l s e ) ;
}
else
{
LegendStatus . Text = "Nume i n v a l i d ! " ;

132

CAPITOLUL 9. ASP.NET MEMBERSHIP

}
}
cu sanse de autenticare reusita pentru numele de utilizator si parola salvate
n baza de date.

9.5

Crearea unei pagini de login

Pagina de login se poate face cu controale puse la dispozitie de catre


ASP.NET sau prin pagini create de programator. Controalele ASP.NET
sunt:
Login - control compus care rezolva cele mai multe probleme legate de
autenticare - asarea unor casute de text n care se pot scrie numele
de utilizator si parola;
LoginStatus - exprima starea de autenticare a unui utilizator; daca nu
e autenticat, utilizatorul va vedea un buton a carui apasare va duce
la redirectarea catre pagina de login; altfel va asa un buton de logout;
LoginView - permite asarea conditionala a diferitelor controale; daca
utilizatorul este autenticat, atunci va vedeaun anumit continut, altfel
un altul;
PasswordRecovery - permite recuperarea parolei de catre utilizator;
ChangePassword - cere parola veche si permite specicarea unei noi
parole;
CreateUserWizard - include un wizard complex care permite crearea
de conturi utilizator.
Avantajul acestor controale este minimul de cod care trebuie scris pentru
a putea face uz de partea de membership.

9.5.1

Controlul Login

-demo live
Fata de setarile implicite ale controlului, se mai poate interveni asupra
proprietatilor:
CreateUserText - arata textul de pe un link care va folosit pentru
redirectare catre o pagina care da posibilitatea de a crea un nou cont
de utilizator;

9.5. CREAREA UNEI PAGINI DE LOGIN

133

CreateUserUrl - da adresa paginii de creare de cont de utilizator;


HelpPageText - textul link-ului catre o pagina de help
HelpPageUrl - adresa paginii care contine partea de help
UsernameRequiredErrorMessage, PasswordRequiredErrorMessage mesajele de eroare care apar daca utilizatorul nu scrie numele de cont
sau parola
DestinationPageUrl - adresa paginii catre care se face redirectare daca
autenticarea este reusita; este valabila n cazul n care utilizatorul nu
a fost redirectat catre pagina de login dintr-o pagina protejata;
PasswordRecoveryUrl - adresa paginii de unde se poate face recuperarea parolei
Se pot trata urmatoarele evenimente:
LoggingIn - apare nainte ca utilizatorul sa se logineze;
LoggedIn - apare dupa ce utilizatorului i sau recunoscut numele si
parola introduse;
LoginError - daca numele si parola introduse nu sunt recunoscute
Authenticate - gestioneza procesul de autenticare; daca se implementeaza un manipulator pentru eveniment, atunci ntreaga responsabilitate a vericarii identitatii sistemului este n sarcina programatorului.

9.5.2

Controlul LoginStatus

-demo live

9.5.3

Controlul LoginView

Permite asarea unor seturi diferite de controale, n functie de autenticarea utilizatorului: autenticat sau nu; mai departe, se pot face particularizari
n functie de rolul pe care l are utilizatorul. Controlul consta din templateuri, ecare avand un anumit continut.
-demo live

9.5.4

Controlul PasswordRecovery

-demo live

134

CAPITOLUL 9. ASP.NET MEMBERSHIP

9.5.5

Controlul ChangePassword

-demo live

9.6

Gestiunea utilizatorilor prin API-ul de membership

Este posibil ca la un momemnt dat sa se doresca scrierea de cod care sa


permita gestionarea prin cod a utilizatorilor. Plecand de la metodele oferite
de clasa Membership, se pot face urmatoarele operatii:
creare de noi utilizatori
stergerea de utilizatori
modicarea datelor utilizatorilor existenti
aducerea listei de utilizatori
aducerea detaliilor despre un utilizator
validarea credentialelor fata de sursa de date.
Multe din metodele clasei Membership pot lucra cu un parametru de tip
MembershipUser sau returneaza coletie de obiecte d eacest tip.

9.6.1

Aducerea listei de utilizatori

Sa presupunem ca vom aduce lista de utilizatori ntr-un grid, avand coloanele: username, email si nca o coloana ce contine link de selectare. Codul
pentru crearea de grid n pagina aspx este:
<asp : GridView ID=" GridView1 " runat=" s e r v e r "
AutoGenerateColumns=" F a l s e " DataKeyNames="UserName">
<Columns>
<asp : CommandField ShowSelectButton=" t r u e " />
<asp : BoundField D a t a F i e l d="UserName"
HeaderText=" username " />
<asp : BoundField D a t a F i e l d=" Email "
HeaderText=" e m a i l a d d r e s s " />
</Columns>
</asp : GridView>
Legarea la date se poate face din partea de code-behind astfel:

9.6. GESTIUNEA UTILIZATORILOR PRIN API-UL DE MEMBERSHIP135


public p a r t i a l c l a s s A l l U s e r s : System . Web . UI . Page
{
MembershipUserCollection a l l U s e r s ;
protected void Page_Load ( object s e nde r , EventArgs e )
{
a l l U s e r s = Membership . G e t A l l U s e r s ( ) ;
GridView1 . DataSource = a l l U s e r s ;
GridView1 . DataBind ( ) ;
}
}

9.6.2

Obtinerea detaliilor despre un utilizator

Odata ce se obtine un obiect MembershipUser pentru care se cer detaliile,


pe baza proprietatilor expuse de obiect se pot aa detalii de interes. Pentru
codul de mai sus, n partea de code-behind se adauga metoda:
protected void GridView1_SelectedIndexChanged ( object s e nde r ,
EventArgs e )
{
M e m b e r s h i p U s e r C o l l e c t i o n allUsersWithName =
Membership . FindUsersByName ( GridView1 . S e l e c t e d V a l u e as string ) ;
i f ( allUsersWithName . Count == 1 )
{
Label1 . Text = " Last l o g i n dat e " +
allUsersWithName [ GridView1 . S e l e c t e d V a l u e as string ] .
LastLoginDate . ToString ( ) ;
}
}

9.6.3

Modificarea datelor unui utilizator

O data ce este regasit obiectul de tip MembershipUser pentru un utilizator


ale carui date trebuie schimbate, se pot accesa diferite proprietati ale sale
(EmailText, CommentTextBox, IsApprovedCheck etc) iar via metoda statica
Membership.UpdateUser(obiect) se face salvarea datelor modicate.

9.6.4

Crearea si stergerea unui utilizator

Se fac prin metodele statice Membership.CreateUser, respectiv Membership.DeleteUser.

136

9.6.5

CAPITOLUL 9. ASP.NET MEMBERSHIP

Validarea unui utilizator

Validarea utilizatorului vizavi de sursa de date folosite se face prin in termediul metodei statice Membership.ValidateUser(string username, string
password).

Bibliografie
[1] D. Gourley, B. Totty, M. Sayer, S. Reddy, and A. Aggarwal. HTTP: The
Definitive Guide. OReilly, 2002.
[2] M. MacDonald and M. Szpuszta. Pro ASP.NET 3.5 in C# 2008. Apress,
2008.
[3] L. Sasu. Tehnologii XML. Note de curs, Facultatea de Matematica si
Informatica, Universitatea Transilvania din Brasov, 2007.
[4] C. Wong. HTTP Pocket Reference. OReilly, 2000.

137

You might also like