41759043-Curs-Aspnet

135
Site-uri web dinamice ˆ ın ASP.NET Ph.D. Lucian Sasu 5 octombrie 2009

Transcript of 41759043-Curs-Aspnet

Page 1: 41759043-Curs-Aspnet

Site-uri web dinamice ın ASP.NET

Ph.D. Lucian Sasu

5 octombrie 2009

Page 2: 41759043-Curs-Aspnet

2

Page 3: 41759043-Curs-Aspnet

Cuprins

1 Aplicatii Web 71.1 Servere si aplicatii Web . . . . . . . . . . . . . . . . . . . . . . 71.2 Modele clasice de realizare a aplicatiilor Web . . . . . . . . . . 10

1.2.1 Comunicarea cu serverul . . . . . . . . . . . . . . . . . 111.2.2 Limbajul HTML . . . . . . . . . . . . . . . . . . . . . 141.2.3 Limbajul XHTML . . . . . . . . . . . . . . . . . . . . 15

1.3 Formulare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161.3.1 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191.3.2 Password . . . . . . . . . . . . . . . . . . . . . . . . . 201.3.3 Checkbox . . . . . . . . . . . . . . . . . . . . . . . . . 201.3.4 Butoane radio . . . . . . . . . . . . . . . . . . . . . . . 211.3.5 Butonul de Submit . . . . . . . . . . . . . . . . . . . . 211.3.6 Butonul de reset . . . . . . . . . . . . . . . . . . . . . 221.3.7 File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221.3.8 Campuri ascunse . . . . . . . . . . . . . . . . . . . . . 221.3.9 Image . . . . . . . . . . . . . . . . . . . . . . . . . . . 231.3.10 Butoane . . . . . . . . . . . . . . . . . . . . . . . . . . 241.3.11 Textarea . . . . . . . . . . . . . . . . . . . . . . . . . . 241.3.12 Select . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

2 ASP.NET 272.1 Generalitati . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

2.1.1 Ce e gresit la ASP-ul clasic? . . . . . . . . . . . . . . . 272.1.2 Ce aduce ASP.NET? . . . . . . . . . . . . . . . . . . . 29

2.2 Despre ASP.NET 3.5 . . . . . . . . . . . . . . . . . . . . . . . 302.3 Tipuri de fisiere ın ASP.NET . . . . . . . . . . . . . . . . . . 302.4 Modelul de cod . . . . . . . . . . . . . . . . . . . . . . . . . . 322.5 Controale Web si controale HTML . . . . . . . . . . . . . . . 362.6 Forme Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

2.6.1 Postback . . . . . . . . . . . . . . . . . . . . . . . . . . 372.6.2 Mentinerea starii prin Viewstate . . . . . . . . . . . . . 39

3

Page 4: 41759043-Curs-Aspnet

4 CUPRINS

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

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

3 Forme Web, gestiunea starii 47

3.1 Forme Web (continuare) . . . . . . . . . . . . . . . . . . . . . 47

3.1.1 Colectia de controale din pagina . . . . . . . . . . . . . 47

3.1.2 Request . . . . . . . . . . . . . . . . . . . . . . . . . . 47

3.1.3 Response . . . . . . . . . . . . . . . . . . . . . . . . . 48

3.1.4 Server . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

3.2 Tipuri de controale server . . . . . . . . . . . . . . . . . . . . 49

3.2.1 Controale server HTML . . . . . . . . . . . . . . . . . 50

3.2.2 Controale Web server . . . . . . . . . . . . . . . . . . . 53

3.3 Gestiunea starii ın ASP.NET . . . . . . . . . . . . . . . . . . . 53

3.3.1 ViewState . . . . . . . . . . . . . . . . . . . . . . . . . 55

3.3.2 Query String . . . . . . . . . . . . . . . . . . . . . . . 57

3.3.3 Cross page posting . . . . . . . . . . . . . . . . . . . . 58

3.3.4 Cookies . . . . . . . . . . . . . . . . . . . . . . . . . . 58

3.3.5 Sesiunea . . . . . . . . . . . . . . . . . . . . . . . . . . 59

3.3.6 Application . . . . . . . . . . . . . . . . . . . . . . . . 59

4 Validatoare, manipulatoare, controale 61

4.1 Controale de validare a intrarii . . . . . . . . . . . . . . . . . . 61

4.1.1 Pasii de validare . . . . . . . . . . . . . . . . . . . . . . 62

4.1.2 Clasa BaseValidator . . . . . . . . . . . . . . . . . . 62

4.1.3 Validatorul RequiredFieldValidator . . . . . . . . . 63

4.1.4 Validatorul RangeValidator . . . . . . . . . . . . . . . 64

4.1.5 Validatorul CompareValidator . . . . . . . . . . . . . 65

4.1.6 Validatorul RegularExpressionValidator . . . . . . . 66

4.1.7 Controlul CustomValidator . . . . . . . . . . . . . . . 66

4.1.8 Controlul ValidationSummary . . . . . . . . . . . . . . 67

4.1.9 Grupuri de validare . . . . . . . . . . . . . . . . . . . . 67

4.2 Manipulatoare HTTP . . . . . . . . . . . . . . . . . . . . . . . 68

4.3 Controale utilizator . . . . . . . . . . . . . . . . . . . . . . . . 71

5 Teme, pagini master, navigare 73

5.1 Cascading Style Sheets . . . . . . . . . . . . . . . . . . . . . . 73

5.2 Teme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

5.3 Pagini master . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

5.4 Navigare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

Page 5: 41759043-Curs-Aspnet

CUPRINS 5

6 Legarea la date 836.1 Legarea la date simple . . . . . . . . . . . . . . . . . . . . . . 846.2 Legarea la date multiple . . . . . . . . . . . . . . . . . . . . . 866.3 Controale de date “bogate” . . . . . . . . . . . . . . . . . . . . 886.4 Controale de surse de date . . . . . . . . . . . . . . . . . . . . 896.5 Ciclul de viata al unei pagini Web . . . . . . . . . . . . . . . . 896.6 Sursa de date SqlDataSource . . . . . . . . . . . . . . . . . . . 91

6.6.1 Selectarea de ınregistrari . . . . . . . . . . . . . . . . . 916.6.2 Dezavantaje ale SqlDataSource . . . . . . . . . . . . . 92

6.7 Sursa de date ObjectDataSource . . . . . . . . . . . . . . . . . 92

7 Controale de lucru cu datele 957.1 Controlul GridView . . . . . . . . . . . . . . . . . . . . . . . . 95

7.1.1 Formatare . . . . . . . . . . . . . . . . . . . . . . . . . 957.1.2 Stiluri . . . . . . . . . . . . . . . . . . . . . . . . . . . 967.1.3 Selectarea de linie din GridView . . . . . . . . . . . . . 967.1.4 Sortare . . . . . . . . . . . . . . . . . . . . . . . . . . . 967.1.5 Paginare . . . . . . . . . . . . . . . . . . . . . . . . . . 977.1.6 Template-uri . . . . . . . . . . . . . . . . . . . . . . . 97

7.2 Controalele FormView, DetailsView . . . . . . . . . . . . . . . 97

8 JavaScript si Ajax 998.1 Elemente de baza JavaScript . . . . . . . . . . . . . . . . . . . 998.2 Blocuri de script . . . . . . . . . . . . . . . . . . . . . . . . . 1018.3 Manipularea elementelor HTML . . . . . . . . . . . . . . . . . 1038.4 Utilizare de JavaScript pentru ıncarcare asincrona a paginilor . 1038.5 Includerea blocurilor JavaScript din code-behind . . . . . . . . 1068.6 Atacuri de injectare de script . . . . . . . . . . . . . . . . . . 1078.7 JavaScript pentru controale utilizator . . . . . . . . . . . . . . 1098.8 Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

8.8.1 Obiectul XMLHttpRequest . . . . . . . . . . . . . . . . 1158.8.2 Trimiterea cererii . . . . . . . . . . . . . . . . . . . . . 1158.8.3 Procesarea raspunsului . . . . . . . . . . . . . . . . . . 116

8.9 Un exemplu Ajax . . . . . . . . . . . . . . . . . . . . . . . . . 116

9 ASP.NET membership 1219.1 Configurarea autentificarii prin forme . . . . . . . . . . . . . . 1239.2 Crearea sursei de date . . . . . . . . . . . . . . . . . . . . . . 1249.3 Configurarea stringului de conexiune si a furnizorului de “membership”1249.4 Crearea de utilizatori . . . . . . . . . . . . . . . . . . . . . . . 1299.5 Crearea unei pagini de login . . . . . . . . . . . . . . . . . . . 130

Page 6: 41759043-Curs-Aspnet

6 CUPRINS

9.5.1 Controlul Login . . . . . . . . . . . . . . . . . . . . . . 1309.5.2 Controlul LoginStatus . . . . . . . . . . . . . . . . . . 1319.5.3 Controlul LoginView . . . . . . . . . . . . . . . . . . . 1319.5.4 Controlul PasswordRecovery . . . . . . . . . . . . . . 1319.5.5 Controlul ChangePassword . . . . . . . . . . . . . . . . 132

9.6 Gestiunea utilizatorilor prin API-ul de “membership” . . . . . 1329.6.1 Aducerea listei de utilizatori . . . . . . . . . . . . . . . 1329.6.2 Obtinerea detaliilor despre un utilizator . . . . . . . . 1339.6.3 Modificarea datelor unui utilizator . . . . . . . . . . . 1339.6.4 Crearea si stergerea unui utilizator . . . . . . . . . . . 1339.6.5 Validarea unui utilizator . . . . . . . . . . . . . . . . . 134

Page 7: 41759043-Curs-Aspnet

Capitolul 1

Aplicatii Web

1.1 Servere si aplicatii Web

In ingineria softului, o aplicatie Web1 este un program care este stocatpe un server Web si accesat prin intermediul unui browser folosind reteaua.

La un capat al acestei comunicatii se afla un server (program dedicat)care accepta interogari, formulate prin protocolul HTTP; serverul poate saserveasca pagini web statice (ficsiere scrise ın limbaj HTML) sau resursestatice (imagini, fisiere PDF etc). Exemple de servere folosite ın prezent:

• Apache - cel mai larg raspandit, la ora actuala; poate rula pe o mul-titudine de sisteme de operare; conform Netcraft, ın septembrie 2009,54.48% din site-uri rulau Apache

• IIS = Internet Information Services, creat de catre Microsoft pentru afi folosit pe sistemele de operare Windows; disponibil pe Windows 2000(IIS 5), Windows XP Professional (IIS 5.1), Windows Server 2003 (IIS6), Windows 2008 (IIS 7.0 si 7.5), Windows Vista anumite versiuni(IIS 7.0), Windows 7 anumite versiuni (IIS 7.5). IIS este folosit ındezvoltarea aplicatiilor ASP.NET. Conform Netcraft, ın luna precizatamai sus 19.91% din site-uri rulau o varianta de IIS.

Varianta cea mai simpla este aceea ın care se servesc doar resurse statice- cum ar fi un site de prezentare a unei institutii, prezentari de rezultatesau statistici etc, deci situatii ın care continutul se schimba relativ rar. Pa-ginile Web sunt scrise ıntr–un limbaj numit HTML. Figura 1.1 ilustreazaarhitectura unui web server si legatura cu browserul.

Exista ınsa situatii ın care continutul se modifica foarte des – de exemplupentru pagina unui magazin de carti, ın care apar permanent noi publicatii,

1In original: Web application sau webapp.

7

Page 8: 41759043-Curs-Aspnet

8 CAPITOLUL 1. APLICATII WEB

Figura 1.1: Arhitectura unui server web simplu

altele se epuizeaza, se introduc noi categorii de literatura, se stabilesc si semodifica preturi, se introduc promotii etc. A crea pagini web statice nu esteo solutie, deoarece atat de multe modificari nu pot fi operate ın timp real cucosturi reduse. Ca atare, serverul de Web poate de asemenea sa gazduiascao aplicatie scrisa ıntr-un limbaj (alegeri populare: PHP, Java, ASP.NET cuC#/VB.NET etc), aplicatie care produce pagini Web dinamice; ea poate sapreia date dintr-o sursa de date - de regula, o baza de date relationala - si saproduca pagini HTML actualizate. Datele actualizate vor fi afisate dupa ce s-a facut modificarea, la o noua cerere a paginii respective. Intrucat continutulpaginilor se genereaza dinamic, acestea se mai numesc “pagini dinamice”.Dinamicitatea se refera la continutul care se actualizeaza automat, pe bazaunor calcule sau preluari din surse de date.

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 pro-duse; utilizatorul poate sa cumpere, sa ısi alcatuiasca un cos de cumparaturietc; exemplu: Amazon, eBay;

• forumuri – permit membrilor unei comunitati sa comunice; mesajelesunt vizibile de catre toti membrii comunitatii si pot sa primeascaraspuns, de asemenea tot pe forum; exemplu: Comunitatea SQL Server,stackoverflow;

• motoare de cautare: Google, Clusty;

Page 9: 41759043-Curs-Aspnet

1.1. SERVERE SI APLICATII WEB 9

• site-uri ce ofera informatii sau predictii: mersul trenurilor, predictiidespre evolutia pretului la bilete de avion.

La celalalt capat se afla un browser (fie el Internet Explorer, MozillaFirefox, Safari, Google Chrome sau Opera - cele mai utilizate la ora actuala).Tot ceea ce trebuie sa faca utilizatorul este sa indice care este adresa de Webla care se afla pagina de interes.

Acest tip de comunicare este numit client–server: clientul este browse-rul, serverul este cel care raspunde prin furnizarea unei pagini web (daca sepoate). Browserul este de fapt un asa numit thin client (client subtire); el nunecesita instalare locala a unor componente (cu exceptia browserului, utiliza-bil pentru toatre site-urile), nici drepturi de administrator pe masina pe carelucreaza2; tot ceea ce trebuie sa faca este sa formuleze cereri catre server, pebaza actiunilor utilizatorului uman si sa primeasca raspunsul de la server,pentru a-l ınfatisa sub forma unei pagini. Simplitatea modului de operareprecum si lipsa unor manevre complicate de instalare de catre utilizator facaceast tip de aplicatii foarte populare. Se mai considera aici si omniprezentabrowserelor – un aspect care a contribuit decisiv la acceptarea pe scara largaa aplicatiilor web.

Tot ca un avantaj al acestor aplicatii web ar fi faptul ca daca se doresteschimbarea unei parti din aplicatii, aceasta modificare se face ıntr-un singurloc — pe server. Clientul (browserul) este insensibil la aceasta manevra si nutrebuie actualizat ın niciun fel. Este o uriasa diferenta fata de tehnologia thick

client (client gras) prin care utilizatorul primea un kit de instalare pentrucalculatorul lui, iar aplicatia nou instalata se conecta la sever; modificareaaplicatiei putea sa ınsemne dezinstalarea versiunii vechi si instalarea celeinoi, cu potentiale pericole: versiuni incorecte de fisiere DLL (asa numitulDLL hell), dificultatea distribuirii si a mentenantei.

In sfarsit, trebuie spus ca nu conteaza pe ce fel de platforma sau sistem deoperare ruleaza browserul, deoarece paginile Web reprezinta doar text caresunt ıntelese de catre orice sistem. In paranteza fie spus, exista totusi micidiferente ıntre modul ın care browserele deseneaza pagina pe ecran, datoritafaptului ca HTML reprezinta niste specificatii despre cum ar trebui sa fiedesenat un anumit cod HTML, dar cei care creeaza browsere nu iau asta cape o obligatie.

Ca un neajuns al acestui tip de aplicatii: daca reteaua devine nedispo-nibila, aplicatia web nu poate fi accesata. Rezolvarea acestei situatii se faceprintr-ul al treilea tip de aplicatii (pe langa cele thin si thick): smart applica-

2Cu exceptia cazurilor ın care este nevoie de instalarea unor plugin-uri pentru rulareacontinutului pe client, cum ar fi Silverlight sau Adobe Flash. Dupa instalarea acestora,drepturile de administrator nu mai sunt necesare.

Page 10: 41759043-Curs-Aspnet

10 CAPITOLUL 1. APLICATII WEB

tions. De exemplu, un client de email de tipul Outlook sau Mozilla Thunderbirdcare poate sa lucreze si deconectat de la retea (citire de emailuri, stergere,pregatire de emailuri pentru a fi trimise, catare etc). Subiectul nu este tratatın acest curs.

1.2 Modele clasice de realizare a aplicatiilor Web

Modelul de realizare a aplicatiior Web a cunoscut o intreaga evolutie atehnologiilor de programare la nivel de server. Putem enumera astfel:

1. solutia CGI (Common Gateway Interface) reprezinta o serie de script-uri executate pe serverul web. Acestea pot fi scrise ın orice limbajde programare (interpretat sau compilat) cu respectarea urmatoarelorrestrictii: programul scrie datele la iesirea standard si genereaza an-tete care permit browserului sa interpreteze corect iesirea scriptului,conform specificatiilor HTTP. Se pot folosi limbaje precum bash, Perl,C/C++, Delphi. Neajunsul CGI-urilor ıl reprezinta faptul crearii unuinou proces pe serverul Web pentru fiecare cerere, ceea ce la un numarmare de cereri este prohibitiv.

2. solutia ISAPI (Internet Server API) reprezinta o alternativa CGI peplatforma Windows. Dezvoltatorii Win32 pot scrie un program care sacomunice direct cu aceasta interfata pentru a face orice lucru posibil cuCGI, pot folosi ISAPI pentru a obtine date din formulare si pentru atrimite continut HTML la client. Codul la nivel de server poate fi scrisın oricare limbaj cu suport pentru DLL-uri Windows, precum C/C++,Visual Basic, rezultatul compilarii fiind un fisier .dll. Fata de CGI,ISAPI ruleaza ın acelasi spatiu de adrese cu serverul HTTP, are accesla toate resursele serverului HTTP, pot fi incluse mai multe task-uriıntr-un .dll si nu creeaza procese aditionale pentru rezolvarea cererilorclientilor Web.

3. solutia PHP (1994) sau ASP (1996) marcheaza un salt ın dezvoltareaaplicatiilor Web. Desi difera din punct de vedere al sintaxei, ambelelimbaje sunt interpretate, codul lor fiind stocat ın fisiere externe cuextensia .php/.asp. De fapt, ASP nu ofera un limbaj nou, ci se ba-zeaza pe limbajele VBScript si JScript. Un fisier PHP/ASP poate ficombinat cu date de tip text, marcatori HTML si comenzi script, ınmomentul executiei, ın urma cererii unui client Web, fisierul este pro-cesat, fiecare script din cadrul lui este interpretat si rezultatul executieieste ıntrodus ınapoi ın fisierul static HTML ınainte ca rezultatul sa fie

Page 11: 41759043-Curs-Aspnet

1.2. MODELE CLASICE DE REALIZARE A APLICATIILOR WEB 11

trimis catre browser. Mai mult, ın sprijinul programatorului, limbajelepun la dispozitia acestuia o serie de metode si obiecte care usureaza lu-crul cu cookie-uri, cu bazele de date, care preiau elegant intrarile unuiformular HTML si le proceseaza pe server, care preiau informatii des-pre utilizator (clientul Web), care trimit informatii la utilizator, carestocheaza informatii despre sesiunea unui utilizator, care partajeazainformatii ıntre utilizatorii unei aplicatii etc.

4. JSP (Java Server Pages) face parte din familia Java si reprezinta otehnologie care permite crearea de aplicatii Web independente de plat-forma. JSP separa interfata utilizator de continutul generat dinamicpermitand schimbarea ıntregului sablon al site-ului WEB fara a al-tera informatiile afisate. Tehnologia utilizeaza marcatori XML si scrip-turi scrise ın limbajul de programare Java pentru a incapsula logicaaplicatiei care genereaza continutul paginilor WEB. JSP-urile sunt oextensie a tehnologiei Java Servlet. Servlet-ele sunt independente deplatforma 100% si reprezinta module la nivel de server care se integreazaın cadrul unei aplicatii Web si care pot fi utilizate pentru a extindecapabilitatile unui server WEB. Tehnologia JSP si servlet-urile oferao alternativa pentru crearea aplicatiilor WEB fata de alte limbaje descripting/programare a aplicatiilor WEB, oferind independenta de plat-forma, performanta, separarea logicii aplicatiei de partea de interfatautilizator, administrare usoara si extensibilitate.

Punctele de mai sus au ın comun faptul ca serverul Web prezinta ointerfata de comunicare cu procese externe. Separarea software-ul ın diferiteprocese ofera avantajul de modularizare si usureaza procesul de integrare,ın acelasi timp extinzand functiile web server-ului. Aceste procese externerealizeaza componenta logica a activitatii. Configuratia descrisa este redataın figura 1.2.

Figura 1.3 arata modul ın care Serverul IIS utilizeaza ASP.NET pentru aservi pagini web dinamice; mai departe, codul ASP.NET este responsabil dea lua legatura cu surse de date pentru a furniza continutul actual al paginilordinamice.

1.2.1 Comunicarea cu serverul

Paginile web sunt de obicei transmise si primite prin intermediul Inter-netului via HTTP3 (nesecurizat) sau HTTPS4 (securizat). Dezvoltarea pro-

3Hypertext Transfer Protocol.4Secure HTTP.

Page 12: 41759043-Curs-Aspnet

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 Webdinamice

Page 13: 41759043-Curs-Aspnet

1.2. MODELE CLASICE DE REALIZARE A APLICATIILOR WEB 13

tocolului 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 de comunicare ce permite vehicularea de cererisi raspunsuri ıntre un client si un server. Clientul - de regula un browser, darpoate sa fie si un robot de descarcare a paginilor sau o aplicatie utilizator- face o cerere catre un sever, folosind o adresa web. De regula, aceastacerere 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 cerutaeste disponibila); o lista a codurilor este data ın [1], [4];

• un mesaj care este resursa ceruta (pagina web sau imagine sau docu-ment etc), sau un mesaj de eroare sau alta informatie.

Browserul primeste aceste raspunsul de la server si ıl afiseaza; e de la sineınteles ca browserul trebuie sa implementeze cat mai fidel acest protocol.

Mai ın detaliu, o cerere arata astfel:

• linie de cerere, precum GET /images/logo.gif HTTP/1.1, care cere oresursa 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 dela server sunt: GET si POST. Acestea vor fi exemplificate ın sectiunea 1.3.

Un aspect esential al comunicarii prin HTTP este ınsa faptul ca HTTP

este un protocol fara stare. Asta ınseamna ca ori de cate ori un client efec-tueaza o cerere catre un server, acesta raspunde cererii dupa care “uita” ceeace a comunicat cu clientul; serverul nu mentine nicio legatura cu browserulsi nu mentine resursele necesare pentru a raspunde clientului (cu o exceptieminora, mecansimul de keep-alive care permite reutilizarea unei conexiunipentru alte cereri); daca apar modificari ale paginii sau a surselor de date pebaza 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 fie utilizat de cat mai multi clienti simultan. Trasatura mentionatatrebuie privita ca o caracteristica voita a protocolului si nu ca o lipsa.

Page 14: 41759043-Curs-Aspnet

14 CAPITOLUL 1. APLICATII WEB

Mentinerea starii dintre cereri consecutive venite de la acelasi client estetotusi dorita de catre utilizatori sau programatori ın majoritatea cazurilorsi acest lucru se poate emula prin utilizarea de cookie–uri, campuri ascunse,sesiuni.

1.2.2 Limbajul HTML

Limbajul HTML5 este limbajul predominant folosit pentru crearea pa-ginilor Web. El descrie structura, continutul si modul de aparitie al uneipagini; 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 undocument de tip text – se creeaza pe baza unor elemente (<p>, <a> etc)care sunt definite de catre limbaj. Un element are de regula o eticheta dedeschidere si una de ınchidere (dar ın HTML acest lucru nu e ıntotdeaunacerut); elementele pot avea atribute specificate prin nume si carora li asociazavalori:

<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 exem-plu, pentru includerea unei imagini se foloseste secventa:

<img src="boat.gif" alt="Big Boat">

Browserul, dupa primirea fisierului HTML va efectua o parsare a codului;la ıntalnirea elementului img se face o cerere de tip GET pentru a obtineimaginea de pe server.

5Hypertext Markup Language.

Page 15: 41759043-Curs-Aspnet

1.2. MODELE CLASICE DE REALIZARE A APLICATIILOR WEB 15

1.2.3 Limbajul XHTML

Una din criticile care s–au adus lui HTML este favorizeaza combinareacontinutului efectiv al unei pagini cu indicatii despre cum sa arate acestcontinut ın pagina. Suplimentar, faptul ca ın HTML nu se respecta nistereguli de buna formare face parsarea continutului greoaie si poate duce ladiferente de afisare ın browsere. S-a dorit obtinerea unui limbaj pentru careinterpretarea sa fie mai usoara, sa se poata separa structura de continut side asemenea sa semene ınca cu limbajul HTML cu care creatorii de paginiweb erau obisnuiti. Prin preluarea trasaturilor limbajului XML s-a ajuns larealizarea unui limbaj hibrid — XHTML6. Chiar daca mai exista pagini scriseın limbaj HTML, exista o presiune constanta de a produce numai continutXHTML; chiar si uneltele de dezvoltare se conformeaza acestei tendinte.

Implicit, continutul generat de ASP.NET este de tip XHTML. Asta ınseamnaca elementele de marcare satisfac regulile:

• etichetele si numele de atribute trebuie sa fie scrise cu litere mici

• toate elementele trebuie sa fie ınchise, fie cu un tag (eticheta) de ınchiderededicat (<p></p>) fie folosind un tag gol care se ınchide singur (<br />).

• toate atributele trebuie sa aibe valorile incluse ıntre ghilimele sau apos-troafe (id="errorLabel").

• atributul id trebuie sa fie folosit ın locul atributului name (dar controa-lele ASP.NET generate vor avea amandoua aceste atribute, din motivede compatibilitate cu codul JavaScript existent).

• elementele trebuie sa fie imbricate corect: <p><a href="...">..</a></p>

si nu <p><a href="...">..</p></a>.

• documentele XHTML trebuie sa aibe un unic element radacina; acestaeste dat de eticheta html.

XHTML de asemenea ınlatura suportul pentru cateva mecanisme exis-tente ın HTML, precum frame-urile sau precizari stilistice care nu utilizeazaCSS, sau folosirea atributului target pentru link-uri7.

Orice document XHTML trebuie sa ınceapa cu o declaratie de tip de do-cument (vezi [3], sectiunea de DTD), care defineste tipul de XHTML folosit.Pentru a specifica varianta XHTML 1.1 se foloseste:

6Extensible HTML.7Pentru deschiderea paginii indicate prin link ıntr-o noua fereastra se poate folosi cod

JavaScript: onclick="window.open(this.href,’_blank’);return false;".

Page 16: 41759043-Curs-Aspnet

16 CAPITOLUL 1. APLICATII WEB

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"

"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

iar elementul radacina are forma:

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

...

</html>

adica se cere declararea unui spatiu de nume.

Exista posibilitatea de a nu urma specificatiile stricte ale lui XHTML 1.1si a folosi ın schimb niste canoane mai relaxate. De exemplu, se poate utilizaXHTML 1.0 tranzitional care impune regulile structurale din XHTML dar deasemenea 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 ımpiedicautilizarea frame-urilor. Daca se doreste utilizarea acestora cu regulile datede 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 pagini de catre ASP.NET estedependent de tipul de browser care a facut cererea.

1.3 Formulare

Formularul reprezinta modalitatea cea mai utilizata de trimitere de informatiidinspre browser spre server. Formularul contine elemente care de regula su-porta specificarea de valori de catre utilizator (cum ar fi numele si parola peun formular de loginare, sau raspunsurile la un test grila). In momentul ıncare se doreste, formularul – adica setul de input-uri utilizator – este trimiscatre server. Demn de mentionat este ca daca formularul contine si alte ele-mente (imagini, link–uri, text etc) acestea nu sunt trimise la server, deoareceele nu poarta informatie de la utilizator.

Un formular este definit cu eticheta form:

Page 17: 41759043-Curs-Aspnet

1.3. FORMULARE 17

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

2 id="myForm">

3 Nume: <input name="txtNume" type="text"

4 id="txtNume" />

5 <br />

6 Parola: <input name="txtParola" type="password"

7 id="txtParola" />

8 <br />

9 <input type="submit" name="butonTrimitere"

10 value="Trimite" id="butonTrimitere" />

11 </form>

(elementele de tip input sunt prezentate ın cele ce urmeaza).Pagina desenata ın browser arata ca ın figura 1.4.

Figura 1.4: Pagina web cu formular

Atributul action arata care este pagina catre care se va trimite continutulformularului. In exemplul de mai sus este vorba de pagina default.aspx

aflata 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 sipost (nu conteaza daca se scrie cu litere mari sau mici). Cu get toate dateledin formular sunt adaugate la URL-ul specificat de atributul action, astfelca 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 deutilizator sunt trimise ın clar. Acelasi mecanism este folosit de exemplu decatre pagina prin care se acceseaza motorul de cautare Google. Avantajul

Page 18: 41759043-Curs-Aspnet

18 CAPITOLUL 1. APLICATII WEB

acestei metode este ca se poate pune un bookmark, sau poate fi folosit calegatura ıntr-un document.

http://www.google.ro/search?hl=ro&q=data+mining&btnG=

C%C4%83utare+Google&meta=

Partea de dupa semn de ıntrebare din URL se numeste query string.Trebuie spus aici ca exista situatii ın care folosirea metodei get este con-

traindicata; lungimea maxima a URL-ului este limitata de catre browsere, ınprincipal8. De exemplu, pentru Internet Explorer lungimea maxima a URL-ului 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 proxy-uri intermediare pot sa limiteze lungimea maxima a unui URL – vezi figura1.5; detalii suplimentare si teste - aici.

Figura 1.5: Eroare semnalata de serverul Web: URL-ul este prea lung.

Daca se specifica metoda post, atunci setul de date din formular se in-clude ın corpul formularului si trimis mai departe la server; URL-ul nu vafi modificat. Mai exista o diferenta semantica ıntre get si post: get esteconsiderat “idempotent”, adica nu modifica starea serverului la trimiteri re-petate ale aceleiasi interogari, pe cand post e gandit pentru a produce efectecolaterale pe server – tranzactii financiare sau modificari de date.

In interiorul unui formular pot fi folosite urmatoarele elementele de tipinput:

8Specificatia nu impune o lungime maxima pentru un URL

Page 19: 41759043-Curs-Aspnet

1.3. FORMULARE 19

• text

• password

• checkbox

• radio

• submit

• reset

• file

• hidden

• image

• button

Se folosesc cu forma generala: <input type="..." .../>. Sunt prezentatepe 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 fi furnizatde utilizator:

1 <html>

2 <body>

3 <form action="default.aspx">

4 First name:

5 <input type="text" name="firstname">

6 <br />

7 Last name:

8 <input type="text" name="lastname">

9 <br />

10 <input type="submit" />

11 </form>

12 </body>

13 </html>

Page 20: 41759043-Curs-Aspnet

20 CAPITOLUL 1. APLICATII WEB

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

Iesirea este data ın figura 1.6. Query string-ul ın acest caz arata astfel:firstname=Rafael&lastname=Popescu.

Poate fi calificat ca fiind readonly (readonly="readonly") si i se poatespecifica lungimea maxima a sirului acceptat: maxlength="35". De aseme-nea poate sa reactioneze la evenimente. O lista completa a atributelor sievenimentelor poate fi gasita aici.

1.3.2 Password

Seamana cu cele de tip text, cu diferenta ca ın momentul ın care cinevascrie ın interiorul lui, caracterele sunt suprascrise cu un caracter inert – vezilistingul de la pagina 16 si figura 1.4. De retinut ca desi parola nu apare ınclar pe ecran, ea este trimisa totusi asa cum este scrisa; o eventuala criptaresau folosire de protocol securizat (HTTPS) ramane sarcina celui care creeazaaplicatia.

Asa cum s–a 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 specificedintr-un set de optiuni ne–mutual excluzive.

1 <form>

2 I have a bike:

3 <input type="checkbox" name="vehicle" value="Bike">

4 <br />

5 I have a car:

6 <input type="checkbox" name="vehicle" value="Car">

7 <br />

8 I have an airplane:

9 <input type="checkbox" name="vehicle" value="Airplane">

Page 21: 41759043-Curs-Aspnet

1.3. FORMULARE 21

10 <input type="submit" />

11 </form>

Iesirea este data ın figura 1.7. Daca se bifeaza Car si Airplane atunci peserver 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 simodul ın care arata sunt date mai jos.

1 <form>

2 <input type="radio" name="sex" value="male">Male

3 <br />

4 <input type="radio" name="sex" value="female">Female

5 <br />

6 <input type="submit" />

7 </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 aceeasivaloare a atributului name. Daca se bifeaza una din ele, se trimite querystring-ul: sex=male. Documentatia completa se gaseste aici.

1.3.5 Butonul de Submit

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

Page 22: 41759043-Curs-Aspnet

22 CAPITOLUL 1. APLICATII WEB

1 <form>

2 ...

3 <input type="submit" />

4 </form>

Implicit, textul de pe el apare ca “Submit Query”. Daca se doreste, textul sepoate modifica folosind atributul value. Detalii se gasesc aici.

1.3.6 Butonul de reset

Se obtine cu input-ul de forma: <input type="reset" /> si realizeazaun buton pe care scrie textul “Reset” si care va repune valorile din formularla cele cu care au venit de pe server; nu se face trimiterea formularului laserver. Vizual, arata ca si un buton de tip Submit.

1.3.7 File

Cu secventa:

1 <form action="default.aspx">

2 <input id="myFile" type="file"/>

3 <br />

4 <input type="submit" value="Incarca">

5 </form>

rezulta un formular de ıncarcare de fisier care arata precum cel din figura1.9. Detalii se gasesc aici.

1.3.8 Campuri ascunse

Deseori este nevoie ca ın cadrul formularului sa existe niste date care savina de pe server si sa fie trimise ınapoi odata cu restul datelor din formular.Aceste campuri sunt considerate ascunse, ın sensul ca nu au o aparitie vizualape 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 memora valori auxiliare pe client(browser). Detalii se gasesc aici.

Page 23: 41759043-Curs-Aspnet

1.3. FORMULARE 23

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

1.3.9 Image

Input-ul de tip imagine creeaza un control imagine care, atunci cand esteapasat trimite formularul catre server. Locatia imaginii este definita prinatributul src:

1 <form action="default.aspx">

2 <input id="adresa" type="text" />

3 <br />

4 <input type="image" alt="text alternativ"

5 src="btn.png" height="20px"/>

6 </form>

cu iesirea data ın figura 1.10

Figura 1.10: Input de tip imagine

Detalii despre acest tip de input se gasesc aici.

Page 24: 41759043-Curs-Aspnet

24 CAPITOLUL 1. APLICATII WEB

1.3.10 Butoane

Exista un control de tip buton, care arata precum cel de Submit sauReset, a carui apasare va fi procesata exclusiv prin cod JavaScript, ın brow-ser. In exemplul de mai jos la apasarea butonului se depune o valoare ıntextbox-ul formularului, se afiseaza o fereastra pe ecran si apoi se face sub-miterea formularului, totul prin cod JavaScript (dar oricare din actiuni esteoptionala):

1 <html>

2 <head>

3 <script type="text/javascript">

4 function myJSFunction() {

5 var hiddenElement = document.getElementById("adresa");

6 if (hiddenElement != null) {

7 hiddenElement.value = "valoare setata din myJSFunction";

8 }

9 window.alert("functia myJSFunction s-a terminat");

10 document.getElementById("formular").submit();

11 }

12 </script>

13 </head>

14 <body>

15 <form id="formular" action="HTMLPage.htm">

16 <input id="adresa" type="text" size="40" />

17 <br />

18 <input id="myButton" type="button" value="button"

19 onclick="myJSFunction();"/>

20 </form>

21 </body>

22 </html>

Rezultatul este dat ın figura 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 folosielementul textarea:

1 <form id="myForm">

2 <textarea id="zonaText" cols="20" rows="4"></textarea>

Page 25: 41759043-Curs-Aspnet

1.3. FORMULARE 25

Figura 1.11: Input de tip buton. Este aratata starea dupa apasarea butonu-lui.

3 <br />

4 <input type="submit" />

5 </form>

cu reprezentarea din figura 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 amai multor optiuni. Lista de optiuni este formata din perechi de forma cheie-valoare, cheia (invizibila ın pagina desenata de browser) fiind cea care setrimite catre server, iar valoarea este folosita pentru a face alegerea efectiva.Se poate specifica care este eleemntul implicit selectat:

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

2 <select name="judete">

3 <option value="33">Vrancea</option>

4 <option value="14" selected="selected">Brasov</option>

Page 26: 41759043-Curs-Aspnet

26 CAPITOLUL 1. APLICATII WEB

5 <option value="18">Sibiu</option>

6 <option value="21">Teleorman</option>

7 </select>

8 <br />

9 <input type="submit"/>

10 </form>

Query string-ul asociat este judete=14, iar reprezentarea este data ın figura1.13.

Figura 1.13: Reprezentarea controlului de selectare.

Este posibila si selectarea mai multor optiuni simultan, daca ın cadrulelementului select se specifica si atributul multiple:

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

2 <option value="33">Vrancea</option>

3 <option value="14">Brasov</option>

4 <option value="18">Sibiu</option>

5 <option value="21">Teleorman</option>

6 </select>

Daca se specifica acest atribut si niciuna din optiuni nu este selectata,atunci reprezentarea din browser este cea din figura 1.14, iar query string-ulva arata astfel: judete=33&judete=18.

Figura 1.14: Element option cu selectare multipla.

Detalii - aici.

Page 27: 41759043-Curs-Aspnet

Capitolul 2

ASP.NET

2.1 Generalitati

ASP.NET este o platforma pentru aplicatii web dezvoltata si distribuitade catre Microsoft, pe care dezvoltatorii o folosesc pentru a contrui site-uriweb dinamice si servicii web. A fost lansat ın ianuarie 2002 cu versiunea 1.0a .NET Framework si este succesorul tehnologiei Active Server Pages (ASP)dezvoltata tot de Microsoft. ASP.NET a fost construit pe Common LanguageRuntime (CLR), ceea ce permite programatorilor sa scrie cod folosind oricelimbaj suportat de .NET.

Merita mentionat ca ASP.NET este o tehnologie freeware de la Microsoft.ASP.NET poate fi folosit pentru a crea orice tip de aplicatie web, ıncepand dela mici site-uri personale pana la cele de tip business. Strictul necesar pentrua programa cu ASP.NET este reprezentat de .NET Framework, care estegratuit, si de Visual Web Developer Express Edition, de asemenea gratuit.

Aplicatiile ASP.NET sunt aplicatii web .NET complete care se executaca si cod compilat gestionat de .NET runtime. ASP.NET foloseste de ase-menea capabilitatile complete a .NET Framework-ului – o gama de clase lafel de usor de ınteles ca si cele pentru o aplicatie Windows obisnuita. Inesenta, ASP.NET ıncearca sa estompeze linia ıntre dezvoltarea de aplicatiisi dezvoltarea web prin preluarea instrumentelor si a tehnologiilor folosite deprogramatorii de aplicatii desktop.

2.1.1 Ce e gresit la ASP-ul clasic?

Spagetti code

Consideram urmatorul exemplu, ın care un dropdown list HTML estepopulat cu rezultatul unei interogari a unei baze de date:

27

Page 28: 41759043-Curs-Aspnet

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 afisa un controlHTML simplu. Dar ceea ce este mai grav e modul ın care stilul de codi-ficare diminueaza performantele aplicatiei deoarece amesteca codul HTMLcu cod Visual Basic. Cand pagina este procesata de catre ASP ISAPI (In-ternet Server Application Programming Interface), motorul de scripting depe server trebuie sa se activeze si sa se dezactiveze de mai multe ori pentrua gestiona chiar si o singura cerere. Acest lucru creste cantitatea de timpnecesara pentru a procesa ıntreaga pagina si a o trimite la client. Mai mult,paginile web scrise ın acest stil pot atinge usor dimensiuni dificil de stapanit.Daca se mai adauga si propriile componente COM (necesare pentru a furnizafunctionalitatea pe care ASP nu o poate asigura) cosmarul managementuluicodului creste.

Indiferent ce abordare se foloseste, codul devine ıncurcat, lung si greude depanat. In ASP.NET, aceste probleme sunt reduse ca posibilitate deaparitie. Paginile de web sunt scrise folosind conceptele programarii orientatepe obiecte traditionale. Paginile de web ASP.NET contin controalele carepot fi programate ın mod similar cu aplicatiile desktop. Aceasta ınseamnaca nu mai este nevoie de combinarea unui set de marcaje HTML si codinline. Daca se opteaza pentru abordarea code behind atunci cand se creazapaginile ASP.NET, atunci codul si marcajul sunt de fapt plasate ın doua

Page 29: 41759043-Curs-Aspnet

2.1. GENERALITATI 29

fisiere diferite, ceea ce simplifica ıntretinerea codului si permite separareasarcinii de design a paginii web de cea destul de dificila a programarii.

Limbajele de scriptare

La momentul crearii sale, ASP parea o solutie perfecta pentru dezvol-tatorii de aplicatii desktop care vroiau sa treaca la dezvoltare web. Maidegraba decat sa necesite ınvatarea unui limbaj de programarea cu totulnou, ASP a permis dezvoltatorilor sa foloseasca limbaje familiare cum ar fiVBScript. Folosind deja popularul COM (Component Object Model) ca ocoloana vertebrala, aceste limbaje au actionat ca un vehicul pentru accesareacomponentelor si resurselor de pe server. Dar desi ASP era usor de ıntelespentru dezvoltatorii care erau deja obisnuiti cu limbaje precum VBScript,aceasta familiaritate a avut un pret. Deoarece ASP a fost bazat pe tehno-logii vechi, ce au fost initial create pentru aplicatii desktop, acestea nu auputut sa functioneze la fel de bine ın noul mediu de dezvoltare web.

Performanta nu a fost singura problema. Fiecare obiect sau variabila uti-lizata ın ASP clasic era creata ca un tip de data variant. Asa cum mareparte din programatorii in Visual Basic stiu, tipul de data variant este slabtipizat, avand nevoie de cantitati mari de memorie, iar tipul exact este cu-noscut doar la momentul rularii. De aici rezulta ca au performante mult maislabe decat variabilele explicite. De asemenea, cu acest tip de variabile eraimposibil de creat un IDE1 care sa ofere facilitati de debugging, IntelliSense(recunoasterea elementelor lexicale) si verificarea erorilor.

2.1.2 Ce aduce ASP.NET?

Majorele diferente dintre ASP.NET si platformele de dezvoltare existenteinclud 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 componenteleASP.NET sunt compilate (fie la prima cerere, fie la instalarea site-uluipe server), ın loc de a fi interpretate de fiecare data cand acestea suntutilizate; a se vedea figura 2.1.

1Integrated Development Environment, mediu integrat de dezvoltare.

Page 30: 41759043-Curs-Aspnet

30 CAPITOLUL 2. ASP.NET

• modul de programare este orientat pe obiecte; orice pagina este vazutaca un obiect, derivat din clasa pusa la dispozitie de .NET Framework;

• are un mecanism ıncorporat care permite pastrarea starii paginii (chiardaca 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 beneficii notabileprecum: managementul automat al memoriei prin garbage collection;tipuri de date sigure, verificabile; manipularea structurata a erorilor;fire de executie - pentru fiecare cerere facuta de catre un client, selanseaza un fir de executie separat;

• usor de distribuit2 si configurat.

2.2 Despre ASP.NET 3.5

2.3 Tipuri de fisiere ın ASP.NET

Intr–o aplicatie web sunt disponibile urmatoarele tipuri de fisiere:

• fisiere cu extensia aspx — pagini web asp.net; ele contin interfata uti-lizator si optional cod (JavaScript, C#);

• fisiere cu extensia ascx — controale utilizator ASP.NET; reprezintacontroale personalizate, dezvoltate de programatori, prin care se ex-tinde paleta de controale cu care vine ASP.NET; aceste controale potfi adaugate ın pagini aspx;

• fisiere cu extensia asmx sau svc — servicii web ASP.NET (prima exten-sie) sau servicii implementate prin Windows Communication Founda-tion (WCF);

• web.config — fisier de configurare a aplicatiei Web pentru ASP.NET;contine stringuri de conexiune catre baza de date, configurari relativ lamanagementul starii, al securitatii etc;

2In sens de: deploy.

Page 31: 41759043-Curs-Aspnet

2.3. TIPURI DE FISIERE IN ASP.NET 31

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

Page 32: 41759043-Curs-Aspnet

32 CAPITOLUL 2. ASP.NET

• global.asax — fisier global al aplicatiei; se foloseste pentru a implementacod de reactie la evenimente ale aplicatiei, precum pornirea sau oprireaei;

• fisiere cu extensia cs — (daca este vorba de o aplicatie ASP.NET cuC#), este partea de “code–behind” care prelucreaza pe server eveni-mentele survenite pe partea de browser si ciclul de viata al paginilor.Se obtine astfel separarea partii de interfata utilizator de cea de codexecutat pe server;

• fisiere cu extensia ashx — HTTP handlers, pentru returnarea de continutcare sa nu fie pagina web;

• fisiere cu extensia axd — folosite pentru urmarirea aplicatiei (tracing);

• fisiere cu extensia master — pentru master pages;

• fisiere cu extensia resx — pentru internationalizarea si localizarea aplicatiilorASP.NET;

• fisiere cu extensia sitemap — pentru crearea structurii site-ului;

• fisiere cu extensia skin — pentru crearea de teme (“skin–uri”).

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 prefixulasp:, 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 HTMLcare este inteligibil pentru un browser.

• cod C# sau VB.NET

Page 33: 41759043-Curs-Aspnet

2.4. MODELUL DE COD 33

Acest ultim cod este executat pe server (deci browserul nu trebuie sa aibeniciun tip de suport pentru executarea de cod .NET); relativ la locatia ıncare se poate depune acest cod, avem posibilitatile:

1. cod inline, adica scris ın interiorul paginii aspx; utilizat pentru paginiweb simple;

2. cod “ın spate”3, ıntr-un document separat cu extensia cs (daca este codC#). Este modelul preferat pentru dezvoltarea de pagini.

Alegerea ıntre aceste doua modalitati este posibila la crearea unei noi paginiweb, prin checkbox-ul “Place code in separate file”.

Pentru primul caz, codul paginii aspx este:

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

2

3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

5

6 <script runat="server">

7

8 protected void myButton_Click(object sender, EventArgs e)

9 {

10 myLabel.Text = "Buton apasat la: " +

11 DateTime.Now.ToLongTimeString();

12 }

13 </script>

14

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

16 <head runat="server">

17 <title></title>

18 </head>

19 <body>

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

21 <div>

22 <asp:Button ID="myButton" runat="server" Text="Apasati"

23 onclick="myButton_Click" />

24 <asp:Label ID="myLabel" runat="server"></asp:Label>

25 </div>

26 </form>

27 </body>

3In original: code behind.

Page 34: 41759043-Curs-Aspnet

34 CAPITOLUL 2. ASP.NET

28 </html>

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

si fisierul sursa DemoCodeBehind.aspx.cs.

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

2 CodeFile="DemoCodeBehind.aspx.cs" Inherits="DemoCodeBehind" %>

3

4 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

5 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

6

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

8 <head runat="server">

9 <title></title>

10 </head>

11 <body>

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

13 <div>

14 <asp:Button ID="myButton" runat="server" Text="Apasati"

15 onclick="myButton_Click" />

16 <asp:Label ID="myLabel" runat="server"></asp:Label>

17 </div>

18 </form>

19 </body>

20 </html>

Partea de code behind este scrisa astfel:

1 using System;

2 using System.Collections.Generic;

3 using System.Linq;

4 using System.Web;

5 using System.Web.UI;

6 using System.Web.UI.WebControls;

7

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

9 {

10 protected void Page_Load(object sender, EventArgs e)

11 {

12

13 }

14 protected void myButton_Click(object sender, EventArgs e)

Page 35: 41759043-Curs-Aspnet

2.4. MODELUL DE COD 35

15 {

16 myLabel.Text = "Buton apasat la: " +

17 DateTime.Now.ToLongTimeString();

18 }

19 }

Browserul va primi acelasi cod, deoarece interpretarea partii de C# siASP.NET se face de catre server. Este indicata folosirea variante de code–behind, deoarece asta permite separarea partii de layout (ce este ın sarcinaunui designer) de cea de cod (sarcina de programator). In restul lucrarii nevom referi doar la modelul de code–behind.

Conectarea dintre pagina aspx si code–behind se face prin intermediuldirectivei Page de pe primul rand. Remarcam ca se specifica unde se aflapagina de code–behind (atributul CodeFile); de asemenea faptul ca paginaaspx este de fapt un obiect, derivat din clasa care contine code-behind (atri-butul Inherits). Controalele declarate ın pagina aspx vor fi create automat,ıntr-o clasa partiala, care completeaza ın mod transparent codul din fisierulDemoCodeBehind.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 catredesigner ın fisierul de code behind; pentru versiunea ASP.NET 2.0 sau mainoua, aceasta declaratie este generata automat de catre server4. Se remarcaaici calificarea cu protected a campului, pentru a fi disponibil si ın paginaaspx derivata. O vedere a acestui cod se poate obtine din Visual Studio,meniul View→Wiew Code Gen File.

Evenimentele (precum apasarea de buton, schimbarea itemului curentselectat dintr-o lista de optiuni, ıncarcarea paginii) sunt tratate prin metodeın partea de code–behind. In exemplul dat mai sus se observa ca evenimentulde apasare a butonului este procesat prin metoda (ın acest context: eventhandler, manipulator de metoda) myButton_Click, iar legatura se specificaprin atributul onclick din pagina aspx. Se poate face si atasarea eventhandler–ului prin cod:

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

Page 36: 41759043-Curs-Aspnet

36 CAPITOLUL 2. ASP.NET

myButton.Click += myButton_Click;

Se remarca de asemenea si metoda Page_Load care este mostenita dinclasa de baza System.Web.UI.Page. Apelul automat al metodei face partedin 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 fi utilizata pe parte de code–behind; are un aspect vizual, ge-nerandu–se cod HTML de catre server, cod care poate fi interpretat de brow-ser; are de asemenea aspect comportamental – evenimente – si proprietati –de exemplu un obiect de tip Label poate sa suporte modificari prin latime,text, culoare, vizibilitate. Avantajul acestor controale este ca permit genera-rea de cod HTML complex, fara ca programatorul sa fie 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 sauforma de login. In plus, se creeaza programatorului iluzia ca modul de dezvol-tare al aplicatiilor web este foarte asemanator cu cel folosit pentru aplicatiilede tip Windows Forms, unde exista o abundenta de controale.

Din exemplul <asp:Label...> de mai sus, se observa atributul runatcu valoarea server care este mandatoriu (ca prezenta si valoare) pentrucontroalele web. Valoarea atributului id reprezinta numele variabilei cu carese acceseaza controlul pe parte de server.

La cealalta extrema se afla codul HTML simplu, care este direct interpre-tat de catre browser. Problema cu acest cod este ca nu poate fi accesat decatre code behind. Pentru a se permite accesarea programatica, s–a introdusconceptul de control HTML. Un control HTML se obtine din codul HTMLprin adaugarea a doua atribute: runat cu valoarea server si id avand dreptvaloare 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 peserver, deoarece codul din browser nu prezinta atributul runat; runat esteinterpretat de catre mediul ASP.NET si este eliminat la trimiterea spre brow-ser.

Page 37: 41759043-Curs-Aspnet

2.6. FORME WEB 37

2.6 Forme Web

O foma web (denumirea consacrata sub care sunt cunoscute paginile webaspx) reprezinta partea centrala a unei aplicatii ASP.NET. Exista doua partiale unei astfel de forme web:

• partea care se afiseaza pe client – cod HTML, rezultat prin executareacodului ASP.NET

• partea care se afla pe server, adica pagina aspx, clasa de code behindsi cod .NET apelat de catre programator

Evident, trebuie sa existe o comunicare ıntre aceste doua parti. Spre exem-plu, daca este vorba de o pagina care permite unui utilizator sa ısi facacont, datele specificate ın pagina web sunt trimise prin formular (a se ve-dea 1.3) ınapoi catre server; acesta este numit ın jargon “postback”; serverulreceptioneaza acest formular si poate sa execute o secventa de pasi: vali-darea datelor din formular, crearea contului. Pagina apelata va formula unraspuns (cod HTML) pe care ıl va trimite browserului. Dupa aceasta, ciclulse poate relua. Trimiterea formularului ete un mecanism de baza specificatde protocolul HTTP; ASP.NET nu aduce nimic nou aici.

Unul din mecansimele esentiale pentru o usoara dezvoltare a unui for-mular este pastrarea starii. Desi foloseste mecanism clasic (campuri as-cunse), modul transparent ın care este integrat ın framework duce la re-ducerea substantiala a codului. In lipsa acestui mecansim, ın Java sau PHPtrebuie 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 primestecererea, determina faptul ca este o pagina aspx si invoca motorul ASP.NETpentru a o executa. Motorul creeaza pagina si controalele continute, seexecuta codul de initializare – detalii la sectiunea 2.6.4 – apoi paginaeste creeata ca sir de caractere HTML si returnata clientului. Obiectulpagina si controalele incluse sunt distruse (adica devin neutilizabile; sane amintim ca protocolul de comunicare este fara stare, deci pe servernu e obligatoriu sa mentina resursele folosite anterior).

Page 38: 41759043-Curs-Aspnet

38 CAPITOLUL 2. ASP.NET

2. O data pagina trimisa catre browser, este randul utilizatorului sa pro-duca actiunea de trimitere ınapoi a paginii, de exemplu prin apasareaunui buton de tip Submit.

3. Formularul din pagina este trimis ınapoi la server, catre pagina defa-ult.aspx (acesta este comportamentul implicit pentru ASP.NET, dar sepoate modifica). Motorul ASP.NET primeste iarasi cerere si recreeazapagina (deoarece pagina anterioara, de la pasul 1 a fost dealocata) depe server; aceasta refacere va restabili totusi valorile controalelor lastarea 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 modifi-care a continutului formei web (myLabel.Text=...), eventual apelandla cod pentru extragere de date de pe un server de baze de date, etc.

5. Pagina default.aspx cu continutul astfel modificat este transformataın cod HTML si trimisa serverului. Obiectele folosite pentru creareaacestui raspuns sunt disponibilizate. Ciclul se reia de la pasul 2.

Postback-ul poate fi declansat si de o alta actiune decat apasarea unui bu-ton de tip submit; de exemplu, la adaugarea de control web de tip dropdownlist, se poate specifica ın Visual Studio, prin proprietatea de tip booleanAutoPostback daca modificarea itemului curent selectat duce la trimitereaautomata a formularului catre server. Acest mecanism este util pentru cazulın care exista un dropdown list cu judete; alegerea unui anumit judet necesitamodificarea unui alt dropdown list care contine localitatile din judetul curentselectat. Efectul se obtine prin cod JavaScript care actioneaza pe client, codeste injectat automat de catre framework–ul ASP.NET, sub forma:

1 <script type="text/javascript">

2 //<![CDATA[

3 var theForm = document.forms[’form1’];

4 if (!theForm) {

5 theForm = document.form1;

6 }

7 function __doPostBack(eventTarget, eventArgument) {

8 if (!theForm.onsubmit || (theForm.onsubmit() != false)) {

9 theForm.__EVENTTARGET.value = eventTarget;

10 theForm.__EVENTARGUMENT.value = eventArgument;

11 theForm.submit();

Page 39: 41759043-Curs-Aspnet

2.6. FORME WEB 39

12 }

13 }

14 //]]>

15 </script>

Se observa ca avem tot o trimitere de formular, dar dictata de cod. __EVENTTARGETsi __EVENTARGUMENT sunt doua campuri ascunse ce sunt populate cu detaliidespre cine a produs acest postback si eventualele detalii aferente. Dropdownlist-ul este generat ın cod HTML astfel:

1 <select name="DropDownList2"

2 onchange="javascript:setTimeout

3 (’__doPostBack(\’DropDownList2\’,\’\’)’, 0)"

4 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 capostback-ul este disponbil doar pentru controale web.

Pentru a determina pe parte de code behind daca cererea e postback saunu, se poate folosi proprietatea de tip boolean Page.IsPostBack; aceastaare valoarea true daca este un postback, false altfel. Mecanismul este utilpentru ca de regula la postback se face umplerea controalelor cu valori dintr-o sursa de date, ın timp ce la postback acest lucru (de regula costisitor) sepoate evita daca se foloseste mecanismul de viewstate.

2.6.2 Mentinerea starii prin Viewstate

In lipsa mecanismului de Viewstate (care poate fi inhibat la nivel decontrol), la fiecare postback s-ar reface pagina la starea initiala, pierzandu–se valorile depuse anterior ın controale. De exemplu, daca la procesareaanterioara (a doua cerere catre pagina) s–a setat continutul unei etichetela o anumita valoare, la a treia cerere aceasta valoare s–ar pierde. Esteexplicabil, deoarece HTTP este protocol fara stare, iar serverul nu mentinede la o cerere la alta valorile actuale ale controalelor. De regula, asemeneaefect este nedorit.

Mecansimul prin care se pastreaza ultima valoare a unui control (fie elweb sau HTML) este viewstate. Pentru fiecare web control se poate setavaloarea EnableViewState la true (de fapt, valoarea implicita), prin astasemnalandu–se ca se va mentine starea. Mentinerea se face prin intermediulunui camp ascuns numit __VIEWSTATE ın cod HTML si accesat cu variabilaViewState pe parte de code behind. Pentru un control HTML trebuie sa sespecifice enableviewstate=“true”.

Page 40: 41759043-Curs-Aspnet

40 CAPITOLUL 2. ASP.NET

In codul HTML generat pentru browser contine un string cu o codificareBase64 a starii controalelor (contine starea tuturor controalelor care au ex-primata optiunea de viewstate). Acest camp este procesat de catre server pepartea de code behind, ın mod automat, o data la postback, apoi ınainte detrimitere a raspunsului catre client.

Modul ın care lucreaza viewstate–ul pentru prima cerere si pentru postback–urile ulterioare este redat ın figurile 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 procesa-rea paginii pot fi eliberate fara problema; apare ınsa cazul unui camp ascunscare va fi plimbat permanent ıntre client si server, ceea ce duce la ıngreunareacomunicarii (pagina mai mare → trimitere mai lenta). De regula, pentru opagina Web se folosesc o multime de controale, care implicit au partea deviewstate neinhibata, deci se poate ajunge la dimeniuni mari pentru campulascuns; se mai ia aici ın calcul si expandarea intrinseca indusa de codificareaBase64.

Pentru contracararea acestui efect, reamintim ca sunt controale a carorstare nu se schimba ın timp (e.g. butoane), sau a caror stare este refacuta defiecare data, pentru care dezactivarea optiunii de viewstate poate ınsemnao economie importanta de spatiu. De asemenea, evitarea stabilirii valoriipentru controale prin cod (si precizarea lor la designul paginii aspx) reduceviewstate-ul.

Exista chiar situatii cand pagina cu o dimensiune prea mare a campurilorascunse sunt blocate de catre proxy-uri. Pentru aceasta, viewstate–ul poatefi spart ın mai multe bucati; detalii se gasesc ın [2], pagina 81 (View State

Page 41: 41759043-Curs-Aspnet

2.6. FORME WEB 41

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

Chunking).In final, mentionam ca viewstate se poate folos nu doar de catre con-

troalele din pagina, ci si de catre programator, permitandu–se adaugarea siregasirea unor perechi de forma (cheie, valoare).

2.6.3 Utilitatea conceptului de controale

Sa consideram forma web:

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

2 CodeFile="UtilitateControale.aspx.cs"

3 Inherits="UtilitateControale" %>

4

5 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

6 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

7

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

9 <head runat="server">

10 <title></title>

11 </head>

12 <body>

13 <form id="form1" runat="server" method="get">

Page 42: 41759043-Curs-Aspnet

42 CAPITOLUL 2. ASP.NET

14 <div>

15 <asp:Label ID="Lable1" runat="server" Text="Nume">

16 </asp:Label>

17 <asp:TextBox ID="txtName" runat="server">

18 </asp:TextBox>

19 <br />

20 <asp:CheckBox ID="chkApples" runat="server"

21 Text="Vreau mere" />

22 <br />

23 <asp:CheckBox ID="chkPears" runat="server"

24 Text="Vreau pere" />

25 <br />

26 <asp:Button ID="btnSend" runat="server"

27 onclick="btnSend_Click"

28 Text="Trimite" />

29 </div>

30 </form>

31 </body>

32 </html>

La trimiterea conform selectiei din figura 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 code–behind, valoarea controalelor se poate accesa cu5:

1 if (Request.Form["chkApples"] == "on"

2 && Request.Form["chkPears"] != "on") ...

5Daca transmiterea de parametri se face cu metoda get si nu cu post, atunci ın loc deRequest.Form se foloseste Request.QueryString.

Page 43: 41759043-Curs-Aspnet

2.6. FORME WEB 43

Este ınsa mai natural a se interpreta cele doua casute de checkbox ca nistecomponente care au o proprietate, Checked, de tip boolean; de asemenea,casuta de text poate sa fie accesata foarte usor:

1 string name = txtName.Text;

2 if (chkApples.Checked && !chkPears.Checked)

3 {

4 txtName.Text += " vrea doar mere";

5 }

Astfel, consultarea valorilor de pe formular este simpla, ın maniera de reali-zare a aplicatiilor de tip Windows Forms. In cele de mai sus, Request esteun 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 Nume<input id="txtName2" type="text" runat="server" /><br />

2 <input name="chkApples2" type="checkbox" runat="server"

3 id="chkApples2" /> Vreau mere<br />

4 <input name="chkApples2" type="checkbox" runat="server"

5 id="chkPears2" /> Vreau pere

cu procesarea pe code behind (atentie la modul de accesare a textului dininput–ul de tip text):

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

2 {

3 txtName2.Value += " vrea doar mere";

4 }

2.6.4 Ciclul de viata al unei pagini (varianta sumara)

Pasii parcursi de la primirea unei cereri pentru o forma web pana lafurnizarea 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

Page 44: 41759043-Curs-Aspnet

44 CAPITOLUL 2. ASP.NET

Initializarea paginii

La acest pas se creeaza pagina ASP.NET (se instantiaza atat clasa co-respunzatoare portiunii de code–behind, cat si cea corespunzatoare paginiiaspx); controalele sunt instantiate. Daca pagina nu este prima data ceruta decatre acest browser (adica daca este un postback), atunci se face restaurareastarii 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 ıncode behind). Aici de regula se scrie cod care face ıncarcarea datelor ınpagina.

Validarile

Uneori se cere ca valorile furnizate de catre utilizator ın browser sa satis-faca anumite cerinte. Procesul de validare (care se poate efectua si de catrecodul JavaScript de pe client, dar nu obligatoriu) trebuie sa fie ındeplinit pen-tru a se asigura ca valorile cu care urmeaza sa se lucreze au relevanta. In cazcontrar, 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 postbackautomat

• rspuns de tip schimbare: daca s–a stabilit un event handler pentru unanumit control, dar nu s-a precizat AutoPostback=true, si ın plus sedetecteaza (prin comparatie cu valorile din viewstate) ca a aparut oschimbare ın starea controlului, atunci se exectua acest event handler.

Procesarea evenimentelor de tip schimbare se face ınainte de procesarea eve-nimentelor de tip raspuns imediat.

Legare automata la date

Fenomenul se va detalia ıntr–un capitol ulterior. Este vorba de con-troale care se leaga la surse de date. Acestea ısi pot reımprospata automatcontinutul, dupa ce eventualele modificari / adaugari / stergeri de date.

Page 45: 41759043-Curs-Aspnet

2.6. FORME WEB 45

Disponibilizarea resurselor

Se genereaza pagina HTML car eva fi trimisa catre browser. Obiecteleinstantiate pentru aceasta cerere devin neutilizabile.

Page 46: 41759043-Curs-Aspnet

46 CAPITOLUL 2. ASP.NET

Page 47: 41759043-Curs-Aspnet

Capitolul 3

Forme Web, gestiunea starii

3.1 Forme Web (continuare)

3.1.1 Colectia de controale din pagina

O pagina reprezinta un container pentru controalele dispuse pe ea; uncontrol poate de asemenea sa fie de tip container (e.g. Panel, MultiView).Regasirea unui control “copil” continut se face fie prin iterarea peste colectiaControls, fie prin folosirea metodei FindControl(string id). Proprietateasi metoda amintita sunt mostenite din clasa System.Web.UI.Control, bazaa tot ceea ce ınseamna controale server.

3.1.2 Request

Proprietatea Request reprezinta obiect de tipul System.Web.HttpRequestasociat cererii HTTP efectuate de browser. Exista urmatoarele metode siproprietati (lista este incompleta):

• Browser — permite accesarea descrierii proprietatilor browserului folo-sit 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 pringet;

• URL, URLReferrer — adresa curenta, respectiv adresa paginii din cares–a facut cererea curenta;

47

Page 48: 41759043-Curs-Aspnet

48 CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

• UserHostName, UserHostAddress — adresa si numele calculatoruluide pe care s–a facut interogarea;

• UserLanguages — lista de limbi pe care o are setata browserul clientu-lui; utila pentru internationalizare.

Pentru o lista completa a metodelor si proprietatilor, invitam consultareaMSDN–ului.

3.1.3 Response

Desi rar folosit, acest obiect, instanta a clasei System.Web.HttpResponseda acces la cateva mecanisme, printre care:

• setarea de cookie-uri ce sunt trimise spre client – via proprietateaCookies;

• saltul la o pagina noua – via metoda Redirect; ın felul acesta, de peserver se trimite un mesaj browserului prin care este instruit sa cearapagina indicata de server; se poate face redirectare la orice fel de pagina(chiar si la una de tip htm), aflata oriunde (chiar si pe un alt server);

• determinarea starii de conectare a clientului – prin interogarea pro-prietatii boolene IsClientConnected; daca raspunsul este “false”,atunci se poate renunta la o procesare consumatoare de resurse pepartea de server;

• trimiterea de continut, altceva decat sir de caractere – via proprieta-tea ContentType; tipurile posibile de continut sunt prevazute de catrespecificatiile MIME type.

• lucrul direct cu fluxul de iesire catre client, prin proprietatea OutputStream.

3.1.4 Server

Obiectul Server, de tip System.Web.HttpServerUtility da acces la me-tode auxiliare pentru procesarea de cereri web. Deosebit de utile sunt me-todele HtmlEncode si duala ei HtmlDecode. Daca codul ASP.NET posteazacontinut de tip sir de caractere ın pagina, este obligatoriu a se face codificarealor conform canoanelor HTML, altfel caractere precum < sau > pot produceravagii ın pagina; ele trebuie codificate ca fiind &lt; respectiv &gt;.

Similar, substituirea corecta a caracterelor ın adree, se folosesc metodeleUrlEncode si UrlDecode. Pentru determinarea caii fizice corespunzatoare

Page 49: 41759043-Curs-Aspnet

3.2. TIPURI DE CONTROALE SERVER 49

unui fisier de pe site se foloseste metoda MapPath(). In sfarsit, pentrutransferarea la o alta pagina, fara a se face redirectare prin browser (ca laResponse.Redirect), se poate folosi Server.Transfer(), cu restrictia catransferul 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 specificat si ın 2.5:controale server HTML si controale server Web. Acestea din urma cunoscspecializarile: 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 potprocesa ca obiecte pe server, avand deci un tip de date reprezentat pe plat-forma .NET. Clasa de baza pentru orice control este clasa System.Web.UI.Control,care e derivata de clasa System.Web.UI.WebControls.WebControl, repre-zentand baza pentru controalele de tip server si System.Web.UI.HtmlControls.HtmlControls,baza pentru controalele server HTML. Clasa Control contine si transmitederivatilor proprietatile si metodele:

• ClientID – proprietate ce returneaza identificatorul fiecarui control dinpagina HTML; acesta va putea fi utilizat ın JavaScript, prin functiadocument.getElementById();

• Controls – proprietate care returneaza o colectie de controale copil aleobiectului curent. De exemplu, un control declarat cu asp:TextBox

este copil al formularului;

• EnableViewState – returneaza sau seteaza o valoare logica specificanddaca ultima stare setata pentru un control va fi sau nu salvata ınViewState (proprietate a paginii, care va fi transformata ın campulascuns __VIEWSTATE).

• ID – este identificatoru controlului, adica numele de variabila cu carese 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, specificand daca controlul estevizibil sau nu;

• DataBind() – se face popularea controlului la surse de date;

Page 50: 41759043-Curs-Aspnet

50 CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

• FindControl() – se cauta recursiv un control cu un anumit nume ıncontrolul curent;

• HasControl() – returneaza true sau false, aratand daca controlulcurent are sau nu controale copil;

• Render() – se scrie codul HTML asociat controlului curent; metodase apeleaza de regula de catre motorul de ASP.NET si nu direct deprogramator.

3.2.1 Controale server HTML

Sunt din trei categorii mari: controale de tip input (e.g. butoane, check-box, casute de text etc), controale de tip container (formular, tabel, textareaetc) si grupul format din HtmlImage, HtmlLink, HtmlTitle. Clasa de bazaeste HtmlControl, iar proprietatile expuse sunt:

• Attributes – proprietate care permite accesarea sau adaugarea de atri-bute;

• Disabled – returneaza sau seteaza starea de inhibare a controlului;daca are valoarea true, va fi afisat pe pagina, dar cu culoare gri deschis;

• Style – permite accesarea sai modificarea stilurilor CSS pentru con-trolul curent;

• TagName – returneaza numele controlului.

Un control de tip HtmlContainerControl reprezinta un control HTMLcare are atat eticheta de deschidere, cat si de ınchidere, cum ar fi a sau img.Pe langa cele mostenite din HtmlControl, mai avem proprietatile:

• InnerHtml – returneaza sau seteaza textul HTML dintre etichetele dedeschidere si ınchidere. Toate caracterele sunt lasate asa cum se dau;facilitatea este folosita de regula pentru includerea de continut HTML;

• InnerText – ca mai sus, cu deosebirea ca textul setat sufera modificareacaracterelor care au semnificatie HTML predefinita (<, >, ghilimele etc)sunt ınlocuite cu codificari corespunatoare (&lt;, &gt;, &quot; etc).

Clasa HtmlInputControl este folosita ca baza pentru controalele care per-mit interactiunea cu utilizatorul, cum ar fi <input type="text">, <inputtype="submit">. Fata de cele mostenite din HtmlInputControl, se mai punla dispozitie proprietatile:

Page 51: 41759043-Curs-Aspnet

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 protected void Page_Load(object sender, EventArgs e)

2 {

3 myTextBox.Style["font-size"] = "30px";

4 myTextBox.Style["color"] = "red";

5

6 myTextBox.Value = "Introduceti numele";

7 myTextBox.Attributes["onfocus"] =

8 "alert(’numele de familie’)";

9 }

La rulare codul HTML generat va fi (fagment):

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

2 style="font-size:30px;color:red;" value="Introduceti numele"

3 onfocus="alert(’numele de familie’)" />

cu efectul din figura 3.1.

Figura 3.1: Setarea de proprietati pentru controale server HTML

Controalele server HTML pot manipula doua evenimente pe parte deserver:

• ServerClick – este un click procesat de partea de code-behind; deexemplu, pentru codul:

Page 52: 41759043-Curs-Aspnet

52 CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

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

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

si implementarea ın partea de code-behind:

1 protected void MyServerClick(object sender, EventArgs e)

2 {

3 Response.Redirect("http://www.clusty.com");

4 }

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 catrebrowser ın modul natural, ci are loc trimiterea formularului ınapoi catreserver, asa cum se poate deduce din codul HTML rezultat:

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

2 apasa aici</a>

Acest tip de eveniment este disponibil doar pentru o parte din controa-lele server HTML.

• ServerChange – se declanseaza atunci cand se modifica continutul unuicontrol poate avea stari diferite: text, checkbox etc. De exemplu:

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

2 runat="server" onserverchange="MyServerChange"/>

3 <br />

4 <asp:Label ID="myLabel" runat="server" Text=""></asp:Label>

5 <br />

6 <input type="submit" id="btnSubmit"/>

cu partea de code-behind (fragment):

1 protected void MyServerChange(object sender, EventArgs e)

2 {

3 myLabel.Text = myCheckbox.Checked.ToString();

4 }

La apasarea butonului de tip Submit se va executa pe server metodaMyServerChange. In acest caz, schimbarea starii casutei de optiune nuduce automat la trimiterea formularului catre server, dupa cum se poateconstata din inspectarea codului HTML obtinut - lipseste procesareaunui eveniment de tip JavaScript.

Page 53: 41759043-Curs-Aspnet

3.3. GESTIUNEA STARII IN ASP.NET 53

3.2.2 Controale Web server

Reprezinta clase din spatiul de nume System.Web.UI.WebControls, ganditepentru a extinde gama de controale HTML; un control de tip Web server arenu doar o reprezentare grafica mai bogata – datorita unui cod bogat de HTMLcare se genereaza automat – ci si un comportament mai orientat catre comu-nicarea cu serverul. Clasa de baza este WebControl, care expune mult maimulte proprietati si metode decat analoagele lor de tip HTML server control.Spre exemplu, se pune la dispozitie proprietatea Font prin care se specificaproprietatile fontului curent: corp de litera, culoare, decorare, marime etc.Se elimina astfel necesitatea de a sti foarte bine numele atributelor CSS sivalorile lor, deoarece clasele folosite sunt facute astfel ıncat sa furnizeze doarvalorile acceptabile.

Toate controalele se declara ın pagina aspx cu sintaxa <asp:numeControl>,au automat proprietatea runat cu valoarea setata pe server – mai mult, dacaatributul lipseste, se declara eroare de compilare.

Spre deosebire de controalele HTML server, fiecare control server Webdispune de metoda Focus() care poate fi utilizata pe parte de code-behindpentru a selecta acel control ca fiind cel curent. Pentru o casuta de textcu identificatorul myTextbox, apelul myTextbox.Focus() duce la injectareaurmatoarei sectiuni ın codul paginii HTML rezultate:

1 <script type="text/javascript">

2 <!--

3 WebForm_AutoFocus(’myTextbox’);// -->

4 </script>

unde functia JavaScript WebForm_AutoFocus provine dintr-un fisier de re-surse pus la dispozitie de catre ASP.NET, numit WebResource.axd.

Daca pe un formular sunt dispuse mai multe butoane, este posibila spe-cificarea unui buton ca fiind implicit – adica apasarea lui tastei Enter sa fieinterpretata ca apasarea pe acest buton. Specificarea lui se face prin interme-diul formularului, care prin atributul DefaultButton poate specifica ID-ulbutonului care va fi considerat ca implicit. De asemenea, daca se folosescpanouri (<asp:Panel>), acestea putand grupa mai multe butoane, se poatespecifica la nivel de panou care e butonul implicit.

3.3 Gestiunea starii ın ASP.NET

HTTP este un protocol care nu pastreaza starea. Motorul de ASP.NETdistruge obiectele pe care le-a format pentru a raspunde cererii clientului. De

Page 54: 41759043-Curs-Aspnet

54 CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

multe ori, ınsa, este nevoie ca ıntre doua cereri succesive o anumita informatiesa fie pastrata si recuperata dace este nevoie de ea. Exemplul clasic este cosulde 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 fi inspectat sau modificatde 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. Profilul

7. Caching

Vom prezenta doar primele cinci metode. O comparatie a lor se gaseste ıntabelele 3.1 si 3.2.

Tabela 3.1: Optiuni de management al starilor (1).

View State Query String Cookie-uri utilizator

Tipuri de date Tot ce e Un numar limitat Siruri de caracterepermise serializabil de caractereStocare Un camp ascuns Adresa URL din Memoria (RAM/HDD)

ın pagina browser a calc. clientuluiDurata de Permanent retinut se pierde cand se Setat de programatorviata la postback-uri introduce o noua

adresa

Vizibilitate Pagina curenta Pagina tinta Intreaga aplicatieASP.NET

Securitate Usor de citit, Vizibil ın clar, Nesigur, poate firelativ greu de modif. usor de modificat modificat de utiliz.poate fi criptat

Performanta Nu afecteaza serverul Buna, deoarece datele Buna, deoarecedar poate ıngreuna sunt putine datele sunt putinecomunicatia

Page 55: 41759043-Curs-Aspnet

3.3. GESTIUNEA STARII IN ASP.NET 55

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

Sesiune Application

Tipuri de date Orice tip serializabil Orice tip .NETpermiseStocare Memoria serverului sau Memoria serverului

baza de dateDurata de Expira dupa un ∆t de la Durata de viataviata ultima accesare a serverului a aplicatiei

Vizibilitate In toata aplicatia, In toata aplicatia,ın cadrul unei sesiuni global

Securitate Sigur, deoarece datele nu Foarte sigure, deoarece datele nusunt trimise la client sunt trimise la client

Performanta Sesiuni mari → server lent Multe date → server lentUtilizare Stocare de cumparaturi Variabile globale

3.3.1 ViewState

Stocheaza datele ın interiorul paginii curente, sub forma unui camp as-cuns. La orice trimitere de formular c’u atre server, acest camp este proiectatınapoi. Este de regula folosit pentru a stoca ultima valoare a unui control (sise include aici si setare privind stilul controlului, nu doar continutul); poatefi de asemenea ımbogatit cu perechi de forma “cheie–valoare”, care ulteriorpot fi modificate sau sterse.

1 ViewState["Counter"] = 1;

2 ...

3 int counter;

4 if (ViewState["Counter"] != null)

5 {

6 counter = (int)ViewState["Counter"];

7 }

Cheia este de tip sir de caractere; se poate folosi drept valoare orice tip dedate serializabile (care are atributul [Serializable] definit atat pentru elcat si pentru clasele din care este wderivat, direct sau nu).

Exemplu: clasa Customer definita de programator precum:

1 [Serializable]

2 public class Customer

3 {

Page 56: 41759043-Curs-Aspnet

56 CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

4 public string FirstName;

5 public string LastName;

6 public Customer(string firstName, string lastName)

7 {

8 FirstName = firstName;

9 LastName = lastName;

10 }

11 }

poate fi instantiata si stocata ın ViewState:

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

2 ViewState["CurrentCustomer"] = cust;

respectiv refacut cu:

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

Aici este important faptul ca campurile FirstName si LastName sunt seriali-zabile (proprietate implicita a clasei String). Daca sunt campuri dintr-un tipneserializabil, sau daca nu se doreste serializarea lor, atunci acestea trebuiesa fie prefixate cu atributul [NonSerializable].

Situatiile ın care nu se recomanda folosirea ViewState-ului pentru mentinereadatelor sunt:

• datele au caracter confidential; codificarea prin Base64 este reversibilasi usor de citit; mai mult, se poate modifica acest continut cu un efortmediu (vezi [2]);

• se foloseste o informatie care trebuie sa fie accesibila pentru mai multepagini; ın acest caz sunt mai indicate sesiunea, query string-ul saucookie-urile;

• datele ce trebuie stocate sunt voluminoase, ceea ce ıngreuneaza comunicatiaspre si dinspre server (ca parte a formularului, acest camp este plimbatpermanent).

Pentru ımbunatatirea timpilor de raspuns, se poate elimina acest views-tate atunci cand nu este cu adevarat nevoie de el. Asemenea cazuri sunt:

• controlul nu ısi modifica niciodata starea (continut, caracteristici vizu-ale);

• controlul este repopulat la fiecare postback;

Page 57: 41759043-Curs-Aspnet

3.3. GESTIUNEA STARII IN ASP.NET 57

• este un control de tip input, a carui valoare este setata de utilizator,deci oricum serverul le primeste.

Pentru a se omite salvarea automata ın ViewState pentru starea unuicontrol, se poate specifica proprietatea EnableViewState cu valoarea false,sau se poate specifica la nivel de pagina, fie prin modificarea ei ca anteriorla nivel de pagina, fie la directiva:

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

Securitatea ViewState-ului poate fi privita din 2 perspective: ne intere-seaza sa nu se poata face modificarea continutului (chiar daca acest continutpoate fi usor descifrat), sau chiar sa nu se poata descifra ce s–a salvat.

Primul aspect este automat rezolvat, deoarece o data cu valorile pere-chilor cheie–valoare serializata se salveaza si o suma de control asociatacontinutului. Cand se reprimeste la server campul ascuns, se recalculeazaaceasta suma de control; daca nu coincide cu valoarea din ViewState, ınseamnaca s–a intervenit ın el.

Daca se vrea ca ViewState-ul sa fie codificat, atunci se va specifica ındirectiva Page:

1 <%@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, qu-ery string-ul este partea de dupa semnul de ıntrebare. Reprezentarea se facesub forma variabila=valoare, iar mai multe astfel de perechi pot fi separateprin caracterul &.

Exista urmatoarele limitari ale unui query string:

• Informatia este limitata la siruri de caractere, care trebuie sa continecaractere valide pentru un URL.

• Informatia este vizibila pentru oricine;

• Pot aparea modificari 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 fi folosit din partea de code behind astfel:

Page 58: 41759043-Curs-Aspnet

58 CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

1 Response.Redirect("newpage.aspx?recordID=" + recordID.ToString());

Trebuie permanent avut grija ca adresa astfel formata sa contina mereu ca-ractere valide pentru un URL, adica un set destul de redus. Acest lucru seobtine 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 fisiere care sunt mentinute de catre cli-ent (browser) fie ın memoria sa (si deci disponibile doar pe durata cat brow-serul este deschis), fie pe harddisk (si deci pot fi valabile la repornirea brow-serului). Reprezinta perechi de forma cheie–valoare, 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 HttpCookie cookie = new HttpCookie("Preferences");

2 cookie["LanguagePref"] = "English";

3 cookie["Country"] = "US";

4 Response.Cookies.Add(cookie);

Mai sus s-a definit un cookie care va fi stocat doar ın browser; dacase doreste ca acesta sa fie stocat pe HDD, se va specifica o data limita devalabilitate:

1 cookie.Expires = DateTime.Now.AddYears(1);

Redobandirea unui cookie se face prin:

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

2 string language;

3 if (cookie != null)

4 {

5 language = cookie["LanguagePref"];

6 }

Page 59: 41759043-Curs-Aspnet

3.3. GESTIUNEA STARII IN ASP.NET 59

3.3.5 Sesiunea

Sesiunea nu este parte a HTTP-ului, dar este un concept implementat decatre orice framework pentru crearea de pagini web dinamice ıl implemen-teaza. O sesiune este caracteristica unui browser, reprezinta un container deelemente structurate ca si “cheie–valoare”, unde cheia este de tip string iarvaloarea orice obiect serializabil. De regula, se mentine ın memoria serveruluicate o sesiune, instantiata la fiecare inceput de sesiune. Alternativ, se poatespecifica faptul ca sesiunile sa fie memorate ıntr–o baza de date.

Fiecare sesiune este identificata de un sir de 120 de biti lungime, carese salveaza de regula ıntr–un cookie pe browser; la orice cerere efectuata decatre browser, se trimite automat si acest cookie, ceea ce permite serveruluisa determine care este sesiunea atasata browserului; pe partea de code behindse poate accesa continutul sesiunii. Daca se suspecteaza ca clientul nu aremecansimul de cookie permis (sau browserul nu permite asa ceva), atunci sepoate face codificarea acestui identificator de sesiune prin intermediul URL–ului, setare disponibila din fisierul de configurare web.config; sau se poatefolosi autodetectare, deci sa se decida automat care din variante sa se aplice.

Adaugarea (sau suprascriere) si accesarea continutului din sesiune se facprecum urmeaza (exemplu):

1 Session["ProductsDataSet"] = dsProducts;

2 dsProducts = Session["ProductsDataSet"] as DataSet;

Sesiunea este pierduta ıntr–una din urmatoarele situatii:

• utilizatorul ınchide browserul; aceasta duce la pierderea cookie-ului carecontine indentificatorul de sesiune;

• sesiunea expira; implicit, ın ASP.NET dupa 20 de minute de la ultimaaccesare dinspre clientul care a determinat crearea sesiunii, se dealocaautomat aceasta sesiune de catre server, pentru a nu irosi resursele; va-loarea de timeout se poate specifica ın fisierul de configurare web.config;

• daca programatorul apeleaza ın code behind Session.Abandon().

Daca cineva urmaresste comunicatia pe retea, poate sa obtina acest co-okie, si deci acces la sesiune. Pentru aceasta se poate folosi Secure SocketLayer (SSL).

3.3.6 Application

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

Page 60: 41759043-Curs-Aspnet

60 CAPITOLUL 3. FORME WEB, GESTIUNEA STARII

utilizatori curent loginati – sau seturi de date care nu se modifica – dictionarede traducere.

1 protected void Page_Load(Object sender, EventArgs e)

2 {

3 // Acquire exclusive access.

4 Application.Lock();

5 int count = 0;

6 if (Application["HitCounterForOrderPage"] != null)

7 count = (int)Application["HitCounterForOrderPage"];

8 count++;

9 Application["HitCounterForOrderPage"] = count;

10 // Release exclusive access.

11 Application.UnLock();

12 lblCounter.Text = count.ToString();

13 }

Page 61: 41759043-Curs-Aspnet

Capitolul 4

Validatoare, manipulatoare de

HTTP, controale utilizator

4.1 Controale de validare a intrarii

In cazul formularelor, o parte considerabila o reprezinta controalele depreluare a datelor de la utilizator. Pentru aceste date preluate un minim dereguli se cere, de obicei, sa fie respectat. De exemplu, pentru un nume deutilizator, se cere ca acesta sa fie nevid; pentru o adresa de email sau unnumar de telefon, acesta trebuie sa aibe un anumit format.

Validarea se poate face ın doua locuri: pe server (la postback) sau peclient, ınainte de trimiterea formularului care le contine. A doua variantaeste, evident, preferata, deoarece se scuteste un drum pana la server, pentruca acolo sa se constate ca datele sunt invalide. Am prefera deci ca ın codulHTML care se trimite clientului sa existe invocare de cod JavaScript caresa verifice, pe cat posibil, daca regulile de validare a datelor de intrare suntsatisfacute.

Pentru a evita scrierea acestui cod de validare manual, s–au introdusurmatoarele controale de validare:

• <asp:RequiredFieldValidator> - verifica daca un camp de intrare arecontinut;

• <asp:RangeValidator> - determina daca valoarea specificata ıntr–uncontrol de intrare are valoarea cuprinsa ıntre doua margini precizate;

• <asp:CompareValidator> - verifica daca valoarea unui control este ıntr–o relatie anume cu alta valoare;

61

Page 62: 41759043-Curs-Aspnet

62CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE

• <asp:RegularExpressionValidator> - verifica daca valoarea unui controlsatisface o anumita expresie regulata;

• <asp:CustomValidator> - pentru cazurile ın care logica de validare nuse regaseste printre controalele enumerate anterior;

• <asp:ValidationSummary> - arata un sumar al erorilor de validarepentru controalele carora li s-a asociat validator

Pentru un control se poate specifica mai mult de un validator; de exemplu,pentru un textbox se poate asocia un validator de tip RequiredFieldValidator

care verifica daca continutul casutei de text este nevid; suplimentar, se poateasocia un validator de expresie regulata, pentru a vedea daca continutul sa-tisface un anumit format. Este chiar cerut a se asocia “validatorul de campcerut”, deoarece pentru un RegularExpressionValidator (ca de altfel sipentru RangeValidator si CompareValidator), testul de validare se consi-dera trecut daca intrarea este lasata goala.

Controalele de preluare a datelor care sunt validate sunt: TextBox, Lis-tBox, DropDownList, RadioButtonList, HtmlInputText, HtmlTextArea, Ht-mlSelect. 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 linksau ImageButton) care determina trimiterea formularului catre server. Fie-care componenta pomenita are o proprietate numita CausesValidation detip boolean care daca are valoarea true atunci se va face validarea paginii.Validarea se face iterand peste controale si verificand daca sunt ındepliniteconditiile specificare. Pentru validatoarele care nu sunt respectate, se re-trimite pagina, cu indicarea cazurilor care nu au fost respectate. Scenariuldescris corespunde situatiei ın care ın browserul folosit pentru afisare nu sepermite executare de cod JavaScript; daca se permite si validatoarele nu suntrespectate, atunci pagina nici macar nu mai ajunge sa fie trimisa catre server,ci se va afisa direct mesajul de eroare pentru fiecare validator nevalidat ınparte.

4.1.2 Clasa BaseValidator

Toate validatoarele sunt derivate din clasa BaseValidator. Proprietatileesentiale propagate ın derivati sunt:

Page 63: 41759043-Curs-Aspnet

4.1. CONTROALE DE VALIDARE A INTRARII 63

• ControlToValidate – id-ul controlului pentru care se aplica validarea;este necesar a fi specificat;

• Display – cum anume se afiseaza mesajul de eroare; daca este specifi-cata valoarea Static, atunci spatiul necesar afisarii este prealocat; dacaeste specificata valoarea Dynamic, atunci la afisarea acestui continutse va produce deplasarea elementelor ce-i urmeaza pentru a face loccontinutului;

• EnableClientScript – pentru valoarea true, se va permite apelareade cod JavaScript pe client, pentru a verifica validitatea;

• Enabled – specifica daca este o validare activata sau nu;

• ErrorMessage – mesajul de eroare care va fi afisat ıntr–un controlValidationSumary, daca exista asa ceva;

• Text – textul de eroare care se va afisa daca validatorul nu este respec-tat;

• ValidationGroup – se refera la posibilitatea de grupare de validatoriın mai multe grupuri;

4.1.3 Validatorul RequiredFieldValidator

Verifica daca un control are sau nu continut introdus. Implicit, se vaverifica daca textul este vid (sau contine doar spatii); daca se doreste caaceasta comparatie sa se faca cu un sir de caractere specificat de utilizator,atunci valoarea aceasta se poate da ın propietatea InitialValue. Dacacontinutul textbox-ului coincide cu aceasta valoare initiala (dupa aplicareaunei operatii de Trim pe continutul controlului), atunci se raporteaza eroarede validare.

Exemplu:

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

2 <asp:RequiredFieldValidator ID="RequiredFieldValidatorUserName"

3 runat="server" ControlToValidate="txtUserName"

4 ErrorMessage="Numele lipseste">

5 *

6 </asp:RequiredFieldValidator>

Daca se trimite formularul prin apasarea de buton iar casuta de text estegoala, atunci se va afisa o steluta rosie ın dreptul casutei – figura 4.1. Textul

Page 64: 41759043-Curs-Aspnet

64CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE

specificat ın proprietatea ErrorMessage este vizibil doar daca pe pagina semai adauga si un control de tip ValidationSummary, cu rezultatul din figura4.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 verifica daca o valoare specificata este intr-un inter-val specificat prin intermediul proprietatilor MinimumValue si MaximumValue;tipul de date pentru care se face comparatie este specificat ın proprietateaType. Se pot specifica tipurile:

• Currency

Page 65: 41759043-Curs-Aspnet

4.1. CONTROALE DE VALIDARE A INTRARII 65

• Date

• Double

• Integer

• String

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

2 <asp:RangeValidator runat="server" Display="dynamic"

3 ControlToValidate="DayOff" Type="Date"

4 ErrorMessage="Day Off is not within the valid interval"

5 MinimumValue="08/05/2008" MaximumValue="08/20/2008">*

6 </asp:RangeValidator>

4.1.5 Validatorul CompareValidator

Se folosete pentru a verifica daca valoarea specificata ıntr-un control esteıntr-o relatie (mai mare, mai mic etc) cu o valoare specificata, sau chiar cuvaloarea unui alt control.

Prin proprietatea Operator se specifica relatia pe care trebuie sa o aibecontrolul la care este atasata validarea (vazut aici ca membru stang al relatieibinare) cu o alta valoare. Optiunile sunt: Equal, NotEqual, GreaterThan,GreaterThanEqual, LessThan, LessThanEqual si DataTypeCheck. Ultimavaloare este utila pentru a verifica daca valoarea din control se poate repre-zenta ın tipul de date specificat via Type.

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

2 <asp:CompareValidator runat="server" Display="dynamic"

3 ControlToValidate="Age" ValueToCompare="18"

4 ErrorMessage="You must be at least 18 years old"

5 Type="Integer" Operator="GreaterThanEqual">*

6 </asp:CompareValidator>

O alta situatie des ıntalnita este cand trebuie specificat ıntr–un tex-tbox o valoare care sa coincida cu cea scrisa ın alt textbox, de exemplula validarea unei parole alese. Pentru aceasta, se va specifica proprietateaControlToCompare cu referinta la celalalt textbox de comparatie:

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

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

3 <asp:CompareValidator runat="server"

Page 66: 41759043-Curs-Aspnet

66CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE

4 ControlToValidate="Password2" ControlToCompare="Password"

5 ErrorMessage="The passwords don’t match"

6 Type="String" Display="dynamic">

7 <img src="imgError.gif" alt="The passwords don’t match" />

8 </asp:CompareValidator>

4.1.6 Validatorul RegularExpressionValidator

Este utilizat ın cazul ın care se doreste specificarea unei expresii regulatefata de care sa se faca validarea. Exemplul cel mai des invocat este cel alunei adrese de email, cu reprezentarea (acceptabila, dar si alte variante maiinspirate se pot da) .*@.{2,}.{2,}1.

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

2 <asp:RegularExpressionValidator runat="server"

3 ControlToValidate="Email"

4 ValidationExpression=".*@.{2,}\..{2,}"

5 ErrorMessage="E-mail is not in a valid format"

6 Display="dynamic">*

7 </asp:RegularExpressionValidator>

4.1.7 Controlul CustomValidator

Exista situatii care validarea nu poate fi facuta cu ce s–a prezentat maisus; fie se invoca resurse de pe server (verificarea unor date din baza de date,sau logica specifica domeniului), fie este vorba de un sir de pasi care definescvalidarea. Pentru aceasta situatie se foloseste CustomValidator. Codul sepoate executa pe parte doar de server sau de server + client.

Numele functiei JavaScript care se apeleaza pentru validarea ın browser sespecifica ca valoarea a proprietatii ClientValidationFunction, iar metodadin code-behind se refera cu atributul asp.net onservervalidate. Pentruambele functii, ca prim argument se specifica validatorul care a declansatevenimentul de verificare, iar al doilea parametru este un argument careda acces la valoarea controlului pentru care se face validarea, ımpreuna cuposibilitatea de a seta validitatea starii.

Pentru JavaScript, funtia de validare a faptului ca numarul este divizibilcu 5 este:

1 <script type="text/javascript">

2 function myFunction(ctl, args) {

1A se vedea Regular Expression Library.

Page 67: 41759043-Curs-Aspnet

4.1. CONTROALE DE VALIDARE A INTRARII 67

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

4 }

5 </script>

iar pe partea de code-behind:

1 protected void CustomValidator1_ServerValidate(object source,

2 ServerValidateEventArgs args)

3 {

4 if (int.Parse(args.Value) % 5 == 0)

5 {

6 args.IsValid = true;

7 }

8 else

9 {

10 args.IsValid = false;

11 }

12 }

referirea lor ın cadrul controlului fiind:

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

2 <asp:CustomValidator ID="myValidator" runat="server"

3 ErrorMessage="Numarul nu e divizibil cu 5"

4 ClientValidationFunction="myFunction"

5 ControlToValidate="TextBox1" Display="Dynamic"

6 onservervalidate="CustomValidator1_ServerValidate">*

7 </asp:CustomValidator>

4.1.8 Controlul ValidationSummary

Acest control nu este prevazut pentru validare, ci pentru a strange unsumar al erorilor din pagina. De la fiecare validator care semnaleaza eroare sepreia continutul proprietactii ErrorMessage si se arata fie ın pagina, fie ıntr-o fereastra JavaScript, daca proprietatea ShowMessageBox are valoarea true.Modul de afisare a erorrilor este specificat de proprietatea DisplayMode, cuvalorile: 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

Page 68: 41759043-Curs-Aspnet

68CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE

poate specifica la nivel de control de validare, sub forma unui sir de caractere;de asemenea, fiecare buton care produce postback poate sa specifice o valoarepentru aceeasi proprietate; la apasarea lui, se face verificarea validatoarelordoar pentru cele care au acelasi grup ca si butonul actionat. Pentru toatecelelate validatoare care nu fac parte din grup, se omite partea de verificarea corectitudinii.

4.2 Manipulatoare HTTP

Manipulatoarele HTTP (ın original: HTTP handlers) sunt modalitatide a produce un raspuns de catre motorul de ASP.NET pentru o cererevenita. In sectiunea <httpHandlers> a fisierului web.config se afa o suita desubelemente <add> care specifica cine anume va raspunde la o cerere pentruun anumit tip de fisier (aspx, axd etc). De exemplu, cererile catre fisiere cuextensia config sau cs sunt manipulate de catre HttpForbiddenHandler caregenereaza o exceptie.

Pentru crearea unui manipulator HTTP se scrie o clasa care implemen-teaza interfata IHttpHandler; interfata obliga la implementarea metodeiProcessRequest() si a proprietatii read–only IsReusable. Metoda efec-tueaza ıntreaga munca (consultare de resurse, implementare de logica aaplicatiei, verificari), iar proprietatea comunica motorului de ASP.NET dacaobiectul de manipulare de HTTP este reutilizabil sau trebuie neaparat distrussi refacut de la 0 pentru o alta cerere.

Exemplu:

1 using System;

2 using System.Web;

3 namespace TestHTTPHandler

4 {

5 public class SimpleHandler : IHttpHandler

6 {

7 public void ProcessRequest(System.Web.HttpContext context)

8 {

9 HttpResponse response = context.Response;

10 response.Write("<html><body><h1>Rendered by the SimpleHandler");

11 response.Write("</h1></body></html>") ;

12 }

13

14 public bool IsReusable

15 {

16 get {return true;}

Page 69: 41759043-Curs-Aspnet

4.2. MANIPULATOARE HTTP 69

17 }

18 }

19 }

In fisierul web.config, ın sectiunea httpHandlers se adauga intrarea:

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

Daca ın adresa se specifica "fisier.fis", atunci se va apela o instanta a claseiTestHTTPHandler.SimpleHandler care va produce documentul HTML:

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

Pentru IIS 5.x sau 6, serverul nu va recunoaste extensia “fis” (mai corect: nuva invoca handlerul definit de noi) ci va cauta fisierul cu numele “fisier.fis”;negasindu-l, va returna o eroare. Pentru a obtine comportamentul descrismai sus, trebuie facuta o mapare la nivel de extensie de fisier din panoul decontrol al serverului IIS (comanda inetmgr.exe).

O alta posibilitate de a lucra cu aceste manipulatoare de HTTP este de-finirea unor fisiere cu extensia ashx care pot fi apelate de catre utilizator saude browser. Potentialul acestei abordari este mare: se poate servi continutprovenind din cereri atipice, de exemplu se pot cere imagini sau alte resursecare sunt stocate ın baza de date. Pe langa forma de stocare diferita, sepoate sa se implementeze niste pasi – autorizare, decorare a datelor, filtrare– care sa permita accesarea datelor avand ın vedere o politica complexa.

Exemplul dat mai jos implementeaza urmatorul scenariu: ıntr–o paginaHTML dorim sa avem referinte catre imagini care se afla undeva pe harddisk,dar nu neaparat ın directoare gasite sub directorul aplicatiei web. Deoarecereferita la o imagine se face cu o adresa relativa la radacina aplicatiei web, estenevoie de a specifica o cale catre fisiere prin intermediul unui manipulatorde HTTP. Construim un HTTP handler sub forma de fisier ashx care, lametoda ProcessRequest va interoga query string-ul “fp” (cheie stabilita decatre noi) care va copia fisierul imagine referit de query string ın fluxul celuicare a facut cererea. In felul acesta, o imagine poate avea atributul src

cu valoarea “ImageLoader.ashx?fp=d:\images\winter.jpg” (dupa fp se poatescrie orice permite determinarea unica a caii catre fisier).

1 using System;

2 using System.Collections.Generic;

3 using System.Linq;

4 using System.Web;

5 using System.IO;

6 using System.Web.Services;

Page 70: 41759043-Curs-Aspnet

70CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE

7

8 namespace AlbumFoto

9 {

10 /// <summary>

11 /// loads an image from the disk

12 /// </summary>

13 [WebService(Namespace = "http://cs.unitbv.ro/")]

14 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

15 public class ImageLoader : IHttpHandler

16 {

17

18 /// <summary>

19 /// Enables processing of HTTP Web requests by a custom

20 /// HttpHandler that implements the

21 /// <see cref="T:System.Web.IHttpHandler"/> interface.

22 /// </summary>

23 /// <param name="context">An

24 /// <see cref="T:System.Web.HttpContext"/>

25 /// object that provides references to the intrinsic

26 /// server objects

27 /// (for example, Request, Response, Session, and Server)

28 /// used to service HTTP requests.</param>

29 public void ProcessRequest(HttpContext context)

30 {

31 string fileFullPath = context.Request.QueryString["fp"];

32 if (String.IsNullOrEmpty(fileFullPath))

33 {

34 return;

35 }

36 int posLasDot = fileFullPath.LastIndexOf(".");

37 string fileType = fileFullPath.Substring(posLasDot + 1)

38 .ToLower().Trim();

39 if (fileType == "jpg")

40 {

41 fileType = "jpeg";

42 }

43 context.Response.ContentType = "image/" + fileType;

44

45 BinaryReader br = new BinaryReader(

46 File.OpenRead(fileFullPath));

47 int bufferLength = 1024;

Page 71: 41759043-Curs-Aspnet

4.3. CONTROALE UTILIZATOR 71

48 byte[] buffer;

49 while ((buffer = br.ReadBytes(bufferLength)).Length > 0)

50 {

51 context.Response.OutputStream.Write(

52 buffer, 0, buffer.Length);

53 }

54 br.Close();

55 }

56

57 public bool IsReusable

58 {

59 get

60 {

61 return true;

62 }

63 }

64 }

65 }

4.3 Controale utilizator

Va urma...

Page 72: 41759043-Curs-Aspnet

72CAPITOLUL 4. VALIDATOARE, MANIPULATOARE, CONTROALE

Page 73: 41759043-Curs-Aspnet

Capitolul 5

Teme, pagini master, navigare

Temele permit specificarea de detalii vizuale pentru paginile web. Sepermite astfel completarea facilitatilor CSS. Pentru un site se pot defini maimulte teme, care se pot aplica individual, pentru fiecare utilizator in parte.

5.1 Cascading Style Sheets

Folosind Cascading Style Sheets (CSS) reprezinta modalitatea de separarea aspectului vizual de partea de continut; mai mult decat atat, permitecentralizarea acestor reguli de stil si reutilizarea lor. Regulile CSS se referala modul ın care vor fi decorate vizual elementele HTML de catre browser.Regulile sunt aplicate de catre browser asupra codului HTML primit de laserver.

O regula se poate referi ın cazul cel mai simplu la numele de elementcaruia i se va aplica:

1 body

2 {

3 font-family: Verdana, Arial, Sans-Serif;

4 font-size: small;

5 }

De exemplu, pentru codul de mai sus se arata ca regula se aplica elementuluibody, fontul fiind: Verdana, sau daca acesta nu este disponibil ın browser,atunci Arial, sau daca nici acesta nu este disponibil, atunci se va folosifontul Sans-Serif implicit al browserului1. Alternativ, pentru un anumit(sau orice) element, stilul se poate aplica doar daca elementul respectiv are

1Despre fonturi sans serif: aici.

73

Page 74: 41759043-Curs-Aspnet

74 CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE

definita o clasa anume. De exemplu, ın listing–ul de mai jos, stilul se aplicaoricui are clasa heading1, precum ın <p class="heading1">continut</p>:

1 .heading1

2 {

3 font-weight: bold;

4 font-size: large;

5 color: lime;

6 font-family: Verdana, Arial, Sans-Serif;

7 }

O foaie de stiluri – un fisier CSS – poate specifica un set de reguli, caresunt invocate ın pagina HTML prin intermediul unui link din cadrul ele-mentului head:

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

2 type="text/css" />

Stilurile se aplica cu predilectie elementelor HTML, dar se pot specificasi 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 fix, specific HTML-ului: dimensiunea fontului,culoarea fundalului etc. Se pune ıntrebarea: cum anume se poate aplica ideeade stil si pentru proprietatile unui control ASP.NET? avand ın vedere ca unasemenea control poate veni cu proprietati al caror nume nu se regaseste ınceea ce pune la dispozitie CSS–ul, avem nevoie de o modalitate de a completafacilitatile acestuia din urma. Spre exemplu ne propunem sa setam stilul unuicontrol de tip Calendar; avand ın vedere ca acest control este particularizatprin proprietati specifice claselor ASP.NET, vrem sa completam facilitatileCSS–ului.

Diferentele ıntre stilurile CSS si temele ASP.NET sunt:

1. Temele sunt asociate controalelor, nu CSS-uluil; dar temele preiau ideeade baza a CSS-ului, definirea de stil si reutilizarea lui pentru obtinereaunui layout unitar;

2. Temele sunt aplicate de catre server; fisierul CSS mentionat pentru opagina HTML este descarcat de catre browser si interpretat tot de catreel;

Page 75: 41759043-Curs-Aspnet

5.2. TEME 75

3. Temele pot fi aplicate prin intermediul fisierelor de configurare; aceastapermite aplicarea unei teme paginilor dintr-un ıntreg folder fara a finevoie sa se modifice paginile aspx

4. Temele nu se aplica ın aceeasi ordine ca si stilurile CSS; daca se specificao proprietate ıntr–o tema si ıntr-un control, atunci setarea din tema estecea care se aplica

Toate temele se definesc ın cate un director din directorul numit App_Themesaflat direct ın radacina aplicatiei web. La un moment dat, pentru o anumitapagina cel mult o tema este activa. Pentru a defini o tema, este nevoie sase defineasca cel putin un fisier text cu extensia skin. Un fisier skin continedeclaratii de controale ASP.NET, pentru care se pot specifica proprietatiledorite:

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

2 BackColor="Orange"/>

Spre deosebire de declaratiile asemanatoare din paginile aspx, atributulid nu se poate specifica; atributul runat trebuie sa fie prezent, iar ın rest oricealt atribut poate sa lipseasca. Se pot crea mai multe fisiere skin, de exemplufiecare continand declaratii pentru controale ınrudite. Exista posibilitatea dea defini fisiere de skin si la nivel global, dar acest lucru este nerecomandat,din cauza ca ıngreuneaza instalarea aplicatiei pe alte servere.

Exemplu de fisier skin:

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

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

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

Pentru a aplica o tema anume unei pagini, se poate proceda ın mai multefeluri: se poate folosi atributul Theme ın cadrul directivei Page, avand valoa-rea numele directorului de tema dorit:

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

O alta varianta este specificarea proprietatii Theme a paginii curente ın codebehind:

1 protected void Page_PreInit(object sender, EventArgs e)

2 {

3 Theme = "FunkyTheme";

4 }

Page 76: 41759043-Curs-Aspnet

76 CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE

Mentionam ca tema se poate seta ın code behind doar ın evenimentul dePage_PreInit, eveniment care se declanseaza ınainte de Page_Load. In am-bele cazuri, efectul este acelasi.

Daca se doreste ca un anumit control sa nu fie “ ımbracat” conform setarilorde tema, se poate specifica ın cadrul paginii aspx atributul EnableThemingcu valoarea false.

Pentru un acelasi control se pot specifica mai multe skin-uri, precum maijos:

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

2 BackColor="Orange" />

3 <asp:TextBox runat="server" ForeColor="White"

4 BackColor="Orange" />

5 <asp:Button runat="server" ForeColor="White"

6 BackColor="Orange" />

7 <asp:TextBox runat="server" ForeColor="White"

8 BackColor="DarkOrange"

9 Font-Bold="True" SkinID="Dramatic" />

10 <asp:Button runat="server" ForeColor="White"

11 BackColor="DarkOrange" Font-Bold="True"

12 SkinID="Dramatic" />

Specificarea skin-ului cu nume, va trebui specificata pentru controlul ıncauza din pagina aspx proprietatea SkinID avand valoarea identificatorul deskin:

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

2 SkinID="Dramatic" />

In cadrul unui director de tip tema, se poate de asemenea crea un fisier detip CSS. Daca o pagina foloseste tema curenta, atunci se va aplica automatsi stilul CSS din directorul temei. Acest lucru este util daca:

• se doreste aplicarea de CSS pentru elemente HTML care nu corespundcontroalelor server;

• se considera ca CSS-urile, fiind standardizate, ar trebui folosite maimult;

• aceste fisiere CSS deja exista si se doreste utilizarea lor, fara a fi nevoieca sa fie rescrise sub forma de teme

Exista o oarecare problema: pentru a putea schimba tema la momentulrularii, deci pentru a aplica CSS-ul din directorul noii teme, este nevoie

Page 77: 41759043-Curs-Aspnet

5.3. PAGINI MASTER 77

ca sa se poata modifica elementul link din interiorul portiunii de head.Modificarea se face automat daca elementul head are precizat atributul runatcu valoarea server.

Temele se pot aplica si prin intermediul fisierului de configurare, ın sectiuneasystem.web:

1 <configuration>

2 <system.web>

3 <pages theme="FunkyTheme" />

4 </system.web>

5 </configuration>

Daca o pagina are specificata tema, atunci aceasta din urma specificare areprioritate fata de ceea ce apare ın fisierul web.config.

Dupa cum s–a aratat mai sus, temele pot fi aplicate dinamic, prin interventiedin code behind:

1 protected void Page_PreInit(object sender, EventArgs e)

2 {

3 if (Session["Theme"] == null)

4 {

5 // No theme has been chosen. Choose a default

6 // (or set a blank string to make sure no theme

7 // is used).

8 Page.Theme = "";

9 }

10 else

11 {

12 Page.Theme = Session["Theme"] as String;

13 }

14 }

unde depunerea ın sesiune s–ar face prin alegerea dintr-o lista de optiuni (uncontrol de tip DropdownList).

5.3 Pagini master

Pentru crearea unei structuri unitare a unui site, se pot folosi variantele:

• controale utilizator; pot fi utilizate pentru a implementa principiul“don’t repeat yourself”, dar nimeni nu poate sa sa garanteze ca acestcontinut, chiar daca e identic, este si dispus identic;

Page 78: 41759043-Curs-Aspnet

78 CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE

• frame–uri HTML; nu mai sunt suportate de standardul XHTML; moti-vele pentru care frame-urile sunt considerate o alegere nepotrivita suntdezbatute ın peste 7000 de tratari ale subiectului aici.

• pagini master – varianta standard ın ASP.NET.

O pagina master permite crearea unui sablon care va fi aplicat peste nistepagini de tip “continut”. Utilizarea unei pagini master pentru tot site-uldetermina o aparitie consistenta a acestor pagini. Folosind pagini master,s–a raspuns urmatoarelor probleme:

• se defineste o singura data o portiune de pagina care poate fi reutilizataori de cate ori se doreste

• se definesc regiunile editabile, adica acele zone ın care o pagina cefoloseste sablonul are voie sa adauge continut;

• suport din partea unei unelte precum Visual Studio

• se permite particularizarea unor aspecte din pagina master, din paginide continut

O pagina master este un fisier cu extensia master. Foloseste un modelde declarare similar cu cel al paginilor aspx, adica pagina pe care se potdepune controale si parte de code-behind. Adaugarea unei pagini master seface asemanator cu adaugarea unei pagini obisnuite de tip aspx. Rezultatulva fi:

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

2 CodeBehind="MyMasterPage.master.cs"

3 Inherits="WebApplication1.MyMasterPage" %>

4

5 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

6 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

7

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

9 <head runat="server">

10 <title></title>

11 <asp:ContentPlaceHolder ID="head" runat="server">

12 </asp:ContentPlaceHolder>

13 </head>

14 <body>

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

Page 79: 41759043-Curs-Aspnet

5.3. PAGINI MASTER 79

16 <div>

17 <asp:ContentPlaceHolder ID="ContentPlaceHolder1"

18 runat="server">

19

20 </asp:ContentPlaceHolder>

21 </div>

22 </form>

23 </body>

24 </html>

Controlul de tip ContentPlaceHolder nu are proprietati deosebite, doarca specifica locul ın care o pagina care vrea sa aplice acest sablon ısi va depunecontinutul. Altfel zis, aceasta este partea ın care se va afisa continutul vari-abil dat de diverse pagini. Remarcam ca pagina master defineste partea deınceput a fisierului HTML (elementele html, head, body). Se remarca faptulca elementul head apare ın interiorul unui control de tip ContentPlaceHolder,ceea ce are sens, deoarece astfel se poate specifica ulterior continut supli-mentar: elemente link, script-uri Java, tag-uri meta etc, cu valori specificefiecarei pagini continut.

O pagina care foloseste un master page se numeste pagina continut2;legatura dintre ea si pagina master trebuie specificata explicit, ın directivaPage:

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

Specificarea caii cu ~ la ınceput se refera la radacina site-ului; daca se folosestedirect numele fisierului de master, atunci se va cauta ıntr–un director alcarui nume este MasterPages; daca fisierul nu este gasit, atunci se cauta ınradacina site-ului.

O pagina continut nu va mai defini partea de html, head, body, deoareceacestea sunt deja date de catre master page; va avea ın schimb un control detip asp:Content, care prin intermediul atributului ContentPlaceHolderIDspecifica ın ce control de tip ContentPlaceHolder va fi asezat:

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

2 MasterPageFile="~/MyMasterPage.Master" AutoEventWireup="true"

3 CodeBehind="WebForm1.aspx.cs"

4 Inherits="WebApplication1.WebForm1" %>

5 <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">

6 </asp:Content>

7 <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1"

2In original: content page.

Page 80: 41759043-Curs-Aspnet

80 CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE

8 runat="server">

9 </asp:Content>

Se remarca atributul Title din directiva Page, care permite stabilireaunui titlu pentru pagina, chiar daca elementul title este prezent ın paginamaster.

Un master page tipic arata precum ın figura 5.1 ([2]). Design-ul se poateface mai evoluat folosind CSS, ca ın listing-ul urmator:

1 .leftPanel

2 {

3 position: absolute;

4 top: 70px;

5 left: 10px;

6 width: 150px;

7 }

8 .rightPanel

9 {

10 position: absolute;

11 top: 70px;

12 right: 10px;

13 width: 150px;

14 }

15 .centerPanel

16 {

17 margin-left: 151px;

18 margin-right: 151px;

19 padding-left: 12px;

20 padding-right: 12px;

21 }

invocat de catre div–uri prin:

1 <div class="leftPanel">...</div>

2 <div class="centerPanel">

3 <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">

4 </asp:ContentPlaceHolder>

5 </div>

6 <div class="rightPanel">...</div>

O problema care poate aparea este calea relativa catre diferite resurse(imagini, fisiere cod JavaScript) invocata ın master page. De exemplu, dacase creeaza un folder numit MasterPages si ın el se depune o pagina master,care invoca o imagine precum:

Page 81: 41759043-Curs-Aspnet

5.3. PAGINI MASTER 81

Figura 5.1: Structura unei pagini de tip master

1 <img src="banner.jpg" />

atunci la design in VS 2008 pagina se vede bine; daca se foloseste o paginacontinut ıntr–un alt folder, atunci la afisare va lipsi imaginea, deoarece eaeste cautata relativ la pagina continut. Codul de imagine de mai sus fiindde tip HTML, serverul nu ıl proceseaza, iar browserul nu gaseste imagineaın directorul unde se afla pagina de continut.

O rezolvare rapida este transformarea codului HTML al imaginii ın con-trol de tip server HTML, iar ın aceasta situatie calea catre imagine esteinterpretata de catre server (si nu de browser) ca o cale relativa la paginamaster. O a doua varianta este specificarea caii pentru acest control de tipserver 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 facili-tatea de Trace din pagini ca se executa prima data partea de Page.PreInitdin master page, apoi Page.PreInit din content page; Page.Load din masterpage, apoi Page.Load din content page; astfel se asigura faptul ca codul dinpagina continut are ultimul cuvant.

Exista situatii ın care din pagina de continut se doreste accesarea paginiimaster, de exemplu penqtru a accede la ceva publicat de catre pagina master:

Page 82: 41759043-Curs-Aspnet

82 CAPITOLUL 5. TEME, PAGINI MASTER, NAVIGARE

1 public string BannerText

2 {

3 get { return lblTitleContent.Text; }

4 set { lblTitleContent.Text = value; }

5 }

Se poate obtine acces la aceasta proprietate prin proprietatea Master:

1 protected void Page_Load(object sender, EventArgs e)

2 {

3 SiteTemplate master =

4 Master as SiteTemplate;

5 master.BannerText = "Content Page #1";

6 }

Conversia cu as este necesara, deoarece proprietatea Master este de tipMasterPage. Pentru a se evita conversia, se poate folosi o directiva ın cadrulpaginii continut:

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

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

1 protected void Page_Load(object sender, EventArgs e)

2 {

3 Master.BannerText = "Content Page #1";

4 }

Spargand ıncapsularea, se poate accesa direct continutul din masterpage:

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

2 if (lbl != null)

3 {

4 lbl.Text = "hello from content page;

5 }

Daca se doreste modificarea de master page dinamic, se poate, prinactionarea asupra proprietatii Page.MasterPageFile ın cadrul evenimen-tului Page.Init. Mecansimul e util daca se doreste adaptarea de masterpage la tipul de vizitator, sau se doreste a se face co-branding.

5.4 Navigare

Va urma...

Page 83: 41759043-Curs-Aspnet

Capitolul 6

Legarea la date

Legarea la date1 reprezinta capacitatea unui control ASP.NET de a-siprelua continutul din diverse surse: baze de date clasice, proprietati, metode,servicii web etc. Dupa ce continutul este preluat, e afisat conform specificuluicontrolului.

Un rol la fel de important ıl au sursele de date, controale prin intermediulcarora se determina care este provenienta datelor; ele actioneaza ca o puntede legatura ıntre datele afisate si controalele ASP.NET; suplimentar, maipermit si specificarea modului de manipulare a lor: datele se sterg, se adauga,se modifica. Este remarcabila flexibilitatea de utilizare a lor, permitandspecificarea legaturii ıntre controale si date fie exclusiv declarativ (fara saucu foarte putin cod pe parte de code–behind), fie prin cod, daca se dorestepersonalizare.

Modul ın care functioneaza acest mecanism este declarativ, folosind codscris ın pagina aspx, acolo unde se precizeaza care e controlul de afisare. Sesepara partea de code–behind de cea de specificare a sursei de date.

Exista doua feluri de legari de date: pentru date simple (unice) si pentrudate multiple. In primul caz este vorba de controale de tip eticheta, buton,LinkButton, Image pentru care se poate specifica o singura valoare care vafi folosita. Se folosesc aici expresiile de legare.

Alte controale suporta afisarea de mai multe valori – sau legarea cu valorirepetate. De exemplu, putem avea o lista de butoane radio, un tabel, saucombobox-uri. Toate acestea expun o proprietate DataSource, care acceptaun obiect de sursa de date. Cand se specifica valoare pentru aceasta propri-etate (fie declarativ, adica ın pagina aspx, fie prin code–behind), se creeazao legatura de la controlul de afisare la datele ce urmeaza a fi prezentate; maitrebuie apelata doar metoda DataBind() la nivel de control sau de pagina

1In original: data binding.

83

Page 84: 41759043-Curs-Aspnet

84 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 careau o singura valoare si nu o multime de valori – se foloseste o expresie delegare. Expresia apare ın partea de cod aspx; este delimitata de portiunile<%# si %>:

1 <%# expresie %>

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

ın pagina, atunci se poate ca expresia de legare la date sa fie:

1 <%# NumeUtilizator %>

Pentru evaluarea unei expresii de legare trebuie sa se apeleze metodaDataBind pentru pagina sau pentru controlul respectiv, altfel nu se va afisanicio valoare. Daca este vorba de o metoda sau proprietate sau camp dinclasa de code behind, pentru ca sa se poata utiliza ın expresie de legarede date, e nevoie ca gradul de accesibilitate sa fie public, protected sauinternal.

Urmatoarele exemple de expresii sunt valide:

1 <%# GetUserName() %>

2 <%# 1 + (2 * 20) %>

3 <%# "John " + "Smith" %>

4 <%# Request.Browser.Browser %>

O expresie de legare la date se poate scrie oriunde ın pagina, dar de regulase precizeaza pentru o proprietate a unui control:

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

2 ImageUrl=’<%# FilePath %>’ />

3 <br />

4 <asp:Label ID="label1" runat="server"

5 Text=’<%# FilePath %>’ />

6 <br />

7 <asp:TextBox ID="textBox1" runat="server"

8 Text=’<%# GetFilePath() %>’ />

9 <br />

10 <asp:HyperLink ID="hyperLink1" runat="server"

11 NavigateUrl=’<%# LogoPath.Value %>’

Page 85: 41759043-Curs-Aspnet

6.1. LEGAREA LA DATE SIMPLE 85

12 Text="Show logo" />

13 <br />

14 <b><%# FilePath %></b>

15 <br />

16 <img src="<%# GetFilePath() %>">

Expresiile pot fi 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 fi trimis catre browser se face printr-un apel precum:

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

2 {

3 this.DataBind();

4 }

Se poate apela metoda DataBind() si ın alte metode, nu doar ın event han-dlerul de ıncarcare de pagina.

Un alt tip de expresie ce s–a introdus odata cu .NET Framework 2.0 este:

1 <%$ AppSettings:numeSetare %>

referindu–se la un nume de setare care se specifica ın fisierul de configurareın sectiunea appSettings:

1 <appSettings>

2 <add key="numeSetare" value="valoare din fisierul de configurare"/>

3 </appSettings>

Un exemplu de utilizare este:

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

Exista cateva diferente ıntre aceasta expresie de legare de date si ceaprecedenta:

• Nu e nevoie sa se apeleze metoda DataBind() pentru evaluarea expre-siei, aceasta din urma facandu–se automat;

• Expresiile cu $ nu se pot insera oriunde ın pagina, spre deosebire decele cu #; ele se aplica numai controalelor pentru a specifica o valoarede proprietate; daca se doreste doar sa se afiseze valoarea expresiei, seva folosi un control de tip Literal, precum s–a exemplificat mai sus;

Page 86: 41759043-Curs-Aspnet

86 CAPITOLUL 6. LEGAREA LA DATE

• prima parte a expresiei cu $ indica numele entitatii care e folosita pen-tru evaluare; avem la dispozitie AppSettings, ConnectionStrings sauResources.

Expresia este des utilizata pentru referirea la un string de conexiune pentruo sursa de date:

1 <asp:SqlDataSource

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

6.2 Legarea la date multiple

Sunt cazuri ın care un control este conceput nu pentru afisarea unei datesimple, ci a unei ıntregi colectii; colectia poate sa fie un vector de elemente,set de ınregistrari din baza de date etc. Controalele care pot afisa colectii deelemente sunt:

• HtmlSelect, ListBox, DropDownList

• CheckBoxList si RadioButtonList

• BulletedList care creeaza o lista cu buline sau numerotata

Fiecare va afisa o singura valoare care provine dintr-o proprietate a unuielement ce se afiseaza. Proprietatile care se specifica la nivelul controalor deafisare sunt:

• DataSource se refera la un obiect de date care contine o colectie dedate ce se vor afisate;

• DataSourceID reprezinta identificatorul unui control de tip sursa dedate; se specifica fie valoare pentru ea, fie pentru DataSource;

• DataTextField reprezinta numele proprietatii din fiecare element carese vrea a fi afisat, ce va aparea vizibil ın pagina HTML;

• DataTextFormatString specifica modul de formatare pentru ceea cese va afisa;

• DataValueField - reprezinta un nume de proprietate, a carui valoarese evalueaza pentru fiecare element care va fi afisat; deosebirea fatade DataTextField este ca valoarea nu se afseaza ın browser, ci estetransmisa prin formular; de regula, reprezinta o cheie de identificare afiecarui element.

Page 87: 41759043-Curs-Aspnet

6.2. LEGAREA LA DATE MULTIPLE 87

Exemplu: setam o colectie de perechi de forma cheie-valoare, stocate ıntr–un dictionar; se face popularea pentru diferite controale de tip multivaloare.

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

2 <div>

3 <select id="Select1" name="Select1" runat="server"

4 datatextfield="Key" datavaluefield="value">

5 <option></option>

6 </select>

7 <select id="Select2" multiple="true" name="Select2"

8 runat="server" datatextfield="Key"

9 datavaluefield="Value">

10 <option></option>

11 </select>

12 <asp:ListBox ID="ListBox1" runat="server"

13 DataTextField="Key" DataValueField="Value">

14 </asp:ListBox>

15 <asp:DropDownList ID="DropDownList1" runat="server"

16 DataTextField="Key" DataValueField="Value">

17 </asp:DropDownList>

18 <asp:CheckBoxList ID="CheckBoxList1" runat="server"

19 DataTextField="Key" DataValueField="Value">

20 </asp:CheckBoxList>

21 <asp:RadioButtonList ID="RadioButtonList1" runat="server"

22 DataTextField="Key" DataValueField="Value">

23 </asp:RadioButtonList>

24 </div>

25 </form>

Pe partea de code behind avem:

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

2 myDictionary.Add("key1", "aa");

3 myDictionary.Add("key2", "ab");

4 myDictionary.Add("key3", "ac");

5

6 Select1.DataSource = myDictionary;

7 Select2.DataSource = myDictionary;

8 ListBox1.DataSource = myDictionary;

9 DropDownList1.DataSource = myDictionary;

10 CheckBoxList1.DataSource = myDictionary;

11 RadioButtonList1.DataSource = myDictionary;

Page 88: 41759043-Curs-Aspnet

88 CAPITOLUL 6. LEGAREA LA DATE

12

13 Page.DataBind();

Efectul este cel din figura 6.2.

Determinarea pe partea de code-behind a elementelor selectate din con-troale se face folosind proprietatea SelectedIndex pentru fiecare control ınparte.

Legarea la date multiple poate avea ca sursa orice tip de date care imple-menteaza interfata ICollection, exemplele notabile fiind: 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 con-troale de date de tip tabelar, anume introduse pentru afisarea de date. Elepermit afisarea mai multor proprietati din fiecare element, de exemplu listatuturor valorilor campurilor dintr–o ı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 tabelacu o linie pentru fiecare camp afisat; permite editarea datelor;

• FormView: ca precedentul, dar permite definirea unor sabloane ce oferamai multa flexibilitate

Pentru un GridView, o declaratie suficient de buna este:

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

Page 89: 41759043-Curs-Aspnet

6.4. CONTROALE DE SURSE DE DATE 89

iar legarea de date se face prin specificarea unei valori adecvate pentru pro-prietatea DataSource, ce se leaga la un obiect de tip DataReader sau de tipDataTable.

Legarea la un obiect DataReader duce la un consum mic de memorie, dareste ineficienta pentru multe scenarii, deoarece nu permite filtrare pe serverulde aplicatii, sau sortare. De asemenea, nu poate fi folosit pentru legare la maimulte controale, simultan. Se poate folosi un set de date deconectat (clasaDataSet), care ın plus are si avantajul de a fi agnostica relativ la tipul deserver de date folosit.

Aceste aspecte vor fi prezentate ıntr–un curs urmator.

6.4 Controale de surse de date

Reprezinta puntea de legatura ıntre o coletie de date si controalele care leafiseaza. Ele implementeaza interfata IDataSource. Sunt oferite urmatoarele:

• SqlDataSource: pentru legaturi la servere de baze de date sau la sursede date precum ODBC;

• ObjectDataSource: pentru legaturi la clase;

• AccessDataSource: pentru baze de date Access (fisiere cu extensiamdb);

• XmlDataSource: pentru legaturi catre documente XML;

• SiteMapDataSource: pentru legaturi catre fisier Web.sitemap care continestructura 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: verificarea proprietatii IsPostBack,creare/recreare de controale dinamice, setarea paginii master, setareatemei, setarea sau citirea valorilor din profil;

2. Init – se poate folosi pentru initializarea sau citirea proprietatilor con-troalelor;

3. InitComplete – pentru apelarea de cod care asigura efectuarea tuturorinitializarilor;

Page 90: 41759043-Curs-Aspnet

90 CAPITOLUL 6. LEGAREA LA DATE

4. PreLoad – se poate scrie cod care sa se apeleze ınainte de apelareametodei Load;

5. Load – apeleaza metoda OnLoad a fiecarui control din pagina, recursiv;se pot seta proprietati si stabili conexiuni la baza de date;

6. evenimente de control – precum apasarea de buton, schimbarea inde-xului activ dintr-un dropdownlist;

7. LoadComplete – cod care trebuie executat dupa ce s–a facut initializareatuturor controalelor din pagina;

8. PreRender – dupa el se apeleaza metoda DataBind pentru fiecare con-trol care are proprietatea DataSourceID setata; la acest eveniment sespecifica cod care trebuie executat pentru setari finale asupra controa-lor din pagina;

9. SaveStateComplete – ınainte de acest eveniment, ViewState-ul a fostsalvat pentru pagina curenta; orice schimbare de stare de la acest puncteste ignorata;

10. Render – se apeleaza metoda Render pentru fiecare control continut;

11. Unload – se apeleaza aceasta metoda pentru fiecare control ın parte;ın fiecare control aceasta metoda poate fi folosita pentru a face dispo-nibilizari de resurse (altceva decat memorie);

Legarea la date se petrece ın urmatorii doi pasi:

1. controlul de sursa de date efectueaza toate modificarile cerute - update,insert, delete. Fiecare din aceste trei modificari are cate doua eveni-mente asociate, procesate prin metode al caror nume se termina cu“ing” si “ed”: Inserting, Inserted; acest moment apare imediat duparularea handlerelor de eveniment pentru controale;

2. se apeleaza interogarile de date iar datele aduse sunt injectate ın con-troalele de afisare; aici se apeleaza metodele Selecting si Selected; pasuleste efectuat imediat dupa evenimentul PreRender

Ultimul pas de mai sus poate aduce a redundanta si apel ne-necesar ıncazul ın care nu s–a facut nicio modificare pe baza de catre utilizator; chiarasa si este, iar acest aspect poate fi ımbunatatit prin folosirea mecanismelorde caching.

Page 91: 41759043-Curs-Aspnet

6.6. SURSA DE DATE SQLDATASOURCE 91

6.6 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. Sepot deci folosi urmatoarele variante de furnizori:

• System.Data.SqlClient

• System.Data.OracleClient

• System.Data.OleDb

• System.Data.Odbc

Tipul de furnizor se specifica prin proprietatea ProviderName:

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

6.6.1 Selectarea de ınregistrari

Pentru un control SqlDataSource trebuie sa se specifice care este co-manda ce aduce elementele selectate. Suplimentar, se pot seta comenzide stergere, modificare, inserare. Proprietatile se numesc: SelectCommand,InsertCommand, UpdateCommand, DeleteCommand, toate de tip string. Valo-rile lor pot fi fraze SQL sau denumiri de proceduri stocate aflate pe server.

Crearea unui control care aduce setul tuturor angajatilor - a se arata lacurs;

De aratat:

• crearea de comenzi parametrizate de tip select; alegerea valorii se facedintr-un dropdownlist

• ca mai sus, cu alegerea din QueryString (2 pagini aspx); varianta: laSelecting se seteaza valoarea parametrului din clauza where;

• update pe gridview; atentie la numele de parametri;

• optimistic lock;

• stergere pentru tabela; de precizat rolul proprietatii DataKeyNamespentru gridview; de procesat exceptie, de aratat pe o tabela nelegatade altele;

• inserare folosind DetailsView

Page 92: 41759043-Curs-Aspnet

92 CAPITOLUL 6. LEGAREA LA DATE

6.6.2 Dezavantaje ale SqlDataSource

Desi usor de utilizat, exista cateva probleme care fac folosirea lui SqlDataSourceneinspirata pentru proiecte de anvergura mare:

1. logica de acces la date este continuta ın pagina ASP.NET; este greu defacut calibrare pentru aceste interogari, profiling-ul e dificil;

2. mentenanta dificila: fiecare pagina care foloseste legarea la date artrebui sa aibe propriul set de date; reutilizarea este inexistenta; dacatrebuie modificata o interogare scrisa ca si cod SQL direct ın pagina,atunci trebuie schimbat peste tot la fel; problema are o ımbunatatireusoara (dar nu totala) prin folosirea de proceduri stocate, care duc ınsala o alta problema - scrierea logicii de business ın codul SQL;

3. lipsa de flexibilitate - fiecare control care se populeaza ar avea nevoiede propriul control de date; daca pentru o pagina se prevad mai multevariante de afisare a datelor, atunci pagina se va umple rapiud de con-troale de date;

4. daca se iese din scenariul “interogare/update-delete-insert” pe aceeasibaza de date, codul devine incurcat si greu de mentinut; o bibliotecade implementare a logicii aplicatiei sau chiar si numai de acces la datesimplifica enorm codul.

6.7 Sursa de date ObjectDataSource

Nu se foloseste un furnizor de date SQL ca la cazul precedent, ci se faceconexiunea cu o clasa sau un obiect care implementeaza logica de furnizare adatelor; poate fi o componenta de tip business logic, sau o biblioteca de accesla date care se bazeaza pe un data mapper care creeaza obiecte din domeniulaplicatiei – flexibilitate maxima.

Conditii impuse de acest mod de lucru (dar restrictiile sunt suportabile):

• Pentru fiecare interogare, logica trebuie sa fie integrata ıntr–o singurametoda a unei clase; asta favorizeaza modelul simplu de “transactionscript” sau crearea unei clase de tip “business facade”. lucru de altfe sirecomandat;

• Trebuie sa returneze rezultatul cerut sau sa duca la efectuarea respec-tivei operatii;

Page 93: 41759043-Curs-Aspnet

6.7. SURSA DE DATE OBJECTDATASOURCE 93

• Rezultatul unei interogari de tip select trebuie sa fie o colectie deelemente, precum un DataSet, DataTable, DataView sau colectie deobiecte; fiecare astfel de obiect ar trebuie sa ısi expuna valorile prinproprietati publice;

• se pot folosi metode instante sau statice; ın primul caz trebuie sa existeun constructor implicit pentru clasa care furnizeaza serviciul, ın celalaltnu se mai poate folosi polimorfismul;

• obiectul trebuie sa fie fara stare.

Page 94: 41759043-Curs-Aspnet

94 CAPITOLUL 6. LEGAREA LA DATE

Page 95: 41759043-Curs-Aspnet

Capitolul 7

Controale de lucru cu datele

7.1 Controlul GridView

Pasi:

1. definirea 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, Ht-mlEncode, NullDisplayText, ConvertEmptyStringToNull

7.1.1 Formatare

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

95

Page 96: 41759043-Curs-Aspnet

96 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: sepoate folosi proprietatea CssClass; se poate alege dintr-o serie de stiluri pre-definite; demo: GridStyles.aspx

Formatare la momentul incarcarii, prin tratarea evenimentului RowDa-taBound - 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 ObjectDataSo-urce - 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 segaseste pe pozitia selectata anterior; repunerea pe aceeasi inregistrare sortatase poate face, dar trebuie mentinuta valoarea selectata in viewstate si apoiparcurs intregul grid;

Important: proprietatea EnableSortingAndPagingCallbacks.

Page 97: 41759043-Curs-Aspnet

7.2. CONTROALELE FORMVIEW, DETAILSVIEW 97

7.1.5 Paginare

Demo; modul in care se face paginare in SQL Server 2005+, folosindCommon 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 campu-rile care se editeaza; se poate modifica modul in care arata controlul deeditare - e.g. control dropdown; demo: EditTemplate1.aspx; data bin-ding bidirectional = metoda Bind(); folosire de dropdownlist pentruTitleOfCourtesy = EditTemplate2.aspx;

7.2 Controalele FormView, DetailsView

Page 98: 41759043-Curs-Aspnet

98 CAPITOLUL 7. CONTROALE DE LUCRU CU DATELE

Page 99: 41759043-Curs-Aspnet

Capitolul 8

JavaScript si Ajax

Factorul esential ce faciliteaza comunicarea dintre client (browser) si ser-ver (codul ASP.NET) este trimiterea formularului dispre browser catre ser-ver, de regula catre aceeasi pagina – postback. Evident, acest postback estedependent de existenta unui cod de reactie pe server, cod care sa produca omodificare a starii paginii.

Exista ınsa destule situatii ın care reactia poate avea loc doar pe client,fara a fi nevoie sa se faca trimiterea formularului catre server. Se scuteste ast-fel o deplasare catre si dinspre server, ceea ce creeaza impresia unei interfeteutilizator care raspunde rapid clientului. De exemplu, expandarea elemente-lor dintr-un meniu sau expandarea nodurilor dintr-un arbore, sau ascundereaunor elemente de pe ecran (tabele, randuri, imagini) se poate efectua de re-gula doar cu resurse locale – se actioneaza asupra portiuni din pagina. Toateaceste efecte sunt obtinute prin utilizarea codului JavaScript care este exe-cutat de catre browserul clientului.

Cursul prezinta tehnici de integrare a codului JavaScript cu ASP.NET.

8.1 Elemente de baza JavaScript

JavaScript permite scrierea de cod client, executat de catre browser.JavaScript este vazut actualmente ca un dialect al ECMAScript1; este unlimbaj slab tipizat (variabilele nu ısi declara tipurile de date decat arare-ori), dinamic (permit modificarea codului si a tipurilor de date, ın timpulexecutiei), interpretat. Codul JavaScript este inclus direct ın documentulHTML 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:

1Standard definit de Ecma International, standard aprobat si de ISO/IECStandard ECMA-262, ECMAScript Language Specification.

99

Page 100: 41759043-Curs-Aspnet

100 CAPITOLUL 8. JAVASCRIPT SI AJAX

• se defineste tratarea unui eveniment pentru un control HTML directsub forma codului care va fi executat;

• se adauga un element <script> care contine cod JavaScript. Elementulcontine cod care se executa atunci cand browserul ajunge sa ıl ıncarcesau codul unei functii care poate fi apelata direct sau indirect ca partea procesarii unui eveniment.

Actionarea de catre codul JavaScript asupra componentelor din paginase face prin HTML DOM (Document Object Model), adica DHTML. Eveni-mentele care pot declansa apelul unui cod JavaScript sunt:

• onchange - apare atunci cand se schimba starea unui control - selecta-re/deselectare a unui checkbox, mutarea focusului din textboxul curentpe 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 fi descarcatadin browser (chiar dupa ce s-a dat clic pe un link sau s-a introdus onoua adresa pentru browser)

Aceste evenimente pot fi setate declarativ:

1 <form>

2 <input id="myText" type="text"

3 onmouseover="window.alert(’mouse over’);"/>

4 <input type="button"

5 onclick="window.confirm(’esti sigur(a)?’);"); />

6 </form>

In cazul ın care este vorba de un buton definit ca Web server control,numele onclick este deja utilizat pentru a face corespondenta cu metoda dincode-behind care face procesarea evenimentului pe server; ca atare, numelede eveniment de pe client se defineste folosesind OnClientClick. Tratareaevenimentelor poate fi specificata si din code-behind, folosind proprietateaAttributes; de exemplu:

Page 101: 41759043-Curs-Aspnet

8.2. BLOCURI DE SCRIPT 101

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

2 <div>

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

4 </div>

5

6 <asp:Button ID="Button1" runat="server" onclick="Button1_Click"

7 Text="Ataseaza eveniment JavaScript" />

8 </form>

9

10 protected void Button1_Click(object sender, EventArgs e)

11 {

12 TextBox1.Attributes.Add("onmouseover",

13 "window.alert(’Mouse plutind peste textbox’);");

14 }

8.2 Blocuri de script

Daca bucata de cod JavaScript care se scrie pentru tratarea de evenimenteste de dimensiuni mai mari sau se reutilizeaza, atunci este mai practic cascrierea sa se faca ıntr–o sectiune dedicata, cuprinsa ın interiorul elementului<script>. Elementul preia un atribut prin care se specifica limbajul ın caresunt scrise instructiunile. Daca browserul nu accepta scripturi JavaScript,atunci aceasta sectiune este ignorata:

1 <script type="text/javascript">

2 <!--

3 var i = 7;

4 window.alert(’Mesaj afisat cand browserul ajunge

5 cu incarcarea in acest loc’);

6 //-->

7 </script>

Comentariile sunt necesare pentru browserele care nu inteleg codul JavaScript,iar comentariul // era util pentru cazul in care se folosea anumite versiuni deNetscape. Cele mai multe browsere actuale ınteleg codul JavaScript, chiardaca 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 fi vizibila ın ıntreaga pagina. Apoi browserulexecuta instructiunea de afisare a unei ferestre de mesaj. Comportamentuleste util pentru cazul ın care la o anumita portiune din pagina html estenevoie sa se execute un anumit cod.

Page 102: 41759043-Curs-Aspnet

102 CAPITOLUL 8. JAVASCRIPT SI AJAX

Daca se doreste ca un bloc de instructiuni sa nu fie executat de ındata cebrowserul ıl ıncarca, se poate folosi o functie definita de programator:

1 <script type="text/javascript">

2 function showMessage(message){

3 window.alert(message);

4 }

5 </script>

Un loc des folosit pentru scrierea de functii este sectiunea <head> a paginiiweb, ceea ce permite o regasire mai usoara. Apelarea functiei definite anterioreste posibila prin:

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

2 onmouseover="showMessage(’mouse peste textbox’);">

3 </asp:TextBox>

iar efectul este redat ın figura 8.2.

Figura 8.1: Rezultatul apelarii functiei JavaScript.

Se observa ca pentru o functie JavaScript nu se declara tipul de retur. Ovarianta des folosita este scrierea codului JavaScript ıntr-un fisier cu extensiaconsacrata js care este ıncarcat de catre browser. Adresa fisierului este datasub prin atributul src al elementrului script:

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

2 </script>

Page 103: 41759043-Curs-Aspnet

8.3. MANIPULAREA ELEMENTELOR HTML 103

8.3 Manipularea elementelor HTML

Schimbarea continutului paginii se face prin identificarea elementului/e-lementelor de pagina ce trebuie schimbat/schimbate; ın cazul unui element alcarui id se cunoaste, fiind specificat ca valoare a atributului id, identificarease face prin intermediul metodei document.getElementById():

1 var myElement = document.getElementById(’textbox1’);

Daca este vorba de regasirea unei familii de elemente ınrudite, se poate fo-losi document.getElementsByTagName sau document.getElementsByName.Odata recuperate elementele de interes, se schimba starea lor tot prin instructiuniJavaScript. Proprietatile uzuale sunt:

• innerHTML - reprezinta continutul HTML dintre eticheta de deschideresi de ınchidere;

• style - permite referirea elementelor de stil din elementul curent; deexemplu, myElement.style.fontSize se foloseste pentru schimbareadimensiunii fontului unui element;

• value - reprezinta starea curenta a controlului; de exemplu, starea unuicheckbox sau textul dintr-o casuta de text;

• parentElement - da acces la elementul parinte; util pentru a muta sausterge elementul curent;

8.4 Utilizare de JavaScript pentru ıncarcare asin-

crona 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 poatesa ia mult timp daca sunt multe date sau daca pozele se ıncarca greu; se poatefolosi un truc care pacaleste rabdarea persoanei care asteapta ıncarcarea pa-ginii: ca poza se ıncarca o imagine neutra, pe post de placeholder; deoareceeste una singura pentru tot gridul, o data ıncarcata pentru o celula, devineinstantaneu afisabila pentru toate celelate celule (facilitate oferita de brow-ser). Ulterior, pentru fiecare carte se cere de catre browser imaginea efectiva,prin cod JavaScript. Timpul necesar pentru ıncarcarea completa a griduluicu tot cu imaginile respective nu scade, dar utilizatorul poate sa ınceapa saciteasca pagina si sa defileze pe ecran.

Gridul poate sa fie declarat astfel:

Page 104: 41759043-Curs-Aspnet

104 CAPITOLUL 8. JAVASCRIPT SI AJAX

1 <asp:GridView id="GridView1" runat="server"

2 AutoGenerateColumns="False">

3 <Columns>

4 <asp:BoundField DataField="Title" HeaderText="Title"/>

5 <asp:BoundField DataField="isbn" HeaderText="ISBN"/>

6 <asp:BoundField DataField="Publisher" HeaderText="Publisher"/>

7 <asp:TemplateField>

8 <HeaderTemplate>

9 Book Cover

10 </HeaderTemplate>

11 <ItemTemplate>

12 <img src="UnknownBook.gif"

13 onerror="this.src=’Unknownbook.gif’;"

14 onload=

15 "GetBookImage(this, ’<%# DataBinder.Eval(

16 Container.DataItem, "isbn") %>’);"

17 </ItemTemplate>

18 </asp:TemplateField>

19 </Columns>

20 </asp:GridView>

Accentul cade pe ultimul camp de pe fiecare linie, care este ın prima faza oreferinta catre o imagine neutra, aflata ın aplicatia web, iar cand se terminade ıncarcat (lucru de altminteri rapid), se face apel de functie JavaScript careva cere ıncarcarea imaginii aferente fiecarui ISBN. Aceasta a doua ıncarcarepoate fi lenta, motivul pentru care se foloseste mecanismul prezentat.

Functia GetBookImage este:

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

2 function GetBookImage(img, url)

3 {

4 // Detach the event handler (the code makes just one attempt

5 // to get the picture).

6 img.onload = null;

7 // Try to get the picture from the GetBookImage.aspx page.

8 img.src = ’GetBookImage.aspx?isbn=’ + url;

9 }

10 </script>

Pagina GetBookImage.aspx (se putea folosi si un manipulator de HTTP,adica cod ashx) este cea care face ıncarcarea imaginii respective, fie dintr-unserviciu extern aplicatiei web curente, fie din baza de date. Etapele ıncarcariisunt date ın figurile 8.2 si 8.3.

Page 105: 41759043-Curs-Aspnet

8.4. UTILIZARE DE JAVASCRIPT PENTRU INCARCARE ASINCRONA A PAGINILOR105

Figura 8.2: Aparitia initiala a paginii [2]

Figura 8.3: Incarcarea imaginilor ın pagina [2]

Page 106: 41759043-Curs-Aspnet

106 CAPITOLUL 8. JAVASCRIPT SI AJAX

8.5 Includerea blocurilor JavaScript din code-

behind

Uneori este mai flexibil ca includerea de cod JavaScript sa se faca la ru-lare, daca se ındeplinesc anumite condtii. Pentru aceasta se poate folosi pro-prietatea Page.ClientScript care expune cateva metode pentru gestiuneablocurilor de script. Metodele sunt:

1. RegisterClientScriptBlock() - scrie un bloc de script la ınceputulformularului 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 specifica un nume de script; acesta trebuiesa fie un string unic, rolul lui este de a se asigura ca nu se adauga acelasiscript de doua ori. De exemplu, pentru includerea repetata de controale carefolosesc JavaScript, mecanismul duce la inserarea doar a unui singur script.

De exemplu, codul de mai jos produce includerea unui script care afiseazao fereastra de confirmare la trimiterea formularului - vezi si figura 8.4:

1 protected void Page_Load(object sender, EventArgs e)

2 {

3 string script = @"

4 <script type=’text/javascript’>

5 function myConfirm()

6 {

7 return confirm(’Vrei trimiterea datelor?’);

8 }

9 </script>

10 ";

11 Page.ClientScript.RegisterClientScriptBlock(this.GetType(),

12 "confirmare", script);

13 Page.Form.Attributes.Add("onsubmit", "return myConfirm();");

14 }

Mecanismul este util ın situatia ın care exista controale utilizator care folosescJavaScript.

O alta varianta este includerea unui bloc de script care face referinta catreun fisier JavaScript:

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

2 Page.ClientScript.RegisterClientScriptInclude("myInclude",

3 includeScript);

Page 107: 41759043-Curs-Aspnet

8.6. ATACURI DE INJECTARE DE SCRIPT 107

Figura 8.4: Executarea de cod JavaScript adaugat prin inregistrare de blocde script

care duce la includerea ın codul HTML, ın interiorul formularului, a codului:

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

2 </script>

8.6 Atacuri de injectare de script

Unul din fenomenele la care este vulnerabila o pagina web este atasareade cod JavaScript de catre utilizator. De exemplu, ın interiorul unui textboxse poate scrie cod JavaScript, ceea ce duce la executarea lui pe client; saufolosirea de elemente HTML ın text poate duce la modificarea afisarii ınpagina. Daca datele sunt preluate pur si simplu de la utilizator si introduseın baza de date, la reafisarea lor pentru un alt utilizator, executand–se peclient, 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 codificarea caracterelorfolosind metoda Server.HtmlEncode.

Implicit, ASP.NET poate sa determine daca continutul unei casute detext are potential de injectare de script. Pentru o pagina cu un textbox siun buton ce produce postback - figura 8.5, comportamentul dictat de servereste cel dat ın figura 8.6 - adica framework–ul ASP.NET depisteaza automatintroducerea de elemente HTML si reactioneaza prin respingere:

Se poate inhiba comportamentul de respingere al ASP.NET-ului, prinspecificarea proprietatii ValidateRequest din cadrul directivei Page, de laınceputul paginii aspx:

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

Page 108: 41759043-Curs-Aspnet

108 CAPITOLUL 8. JAVASCRIPT SI AJAX

Figura 8.5: Incercare de trimitere de cod JavaScript prin textbox

Figura 8.6: Respingere de catre ASP.NET

In aceasta situatie, reafisarea naiva a stringului din textbox ıntr-un labelduce la injectarea unui cod JavaScript ın pagina, cod care va fi executat decatre browser - vezi figura 8.7.

1 protected void Page_Load(object sender, EventArgs e)

2 {

3 myLabel.Text = TextBox1.Text;

4 }

Figura 8.7: Inhibarea respingerii de cod JavaScript

Validarea stringurilor trimise de catre utilizator poate fi inhibata pentruıntregul site, prin specificarea ın fisierul web.config a elementului pages, cu

Page 109: 41759043-Curs-Aspnet

8.7. JAVASCRIPT PENTRU CONTROALE UTILIZATOR 109

atributul ValidateRequests avand valoarea false:

1 <configuration>

2 <system.web>

3 <pages validateRequest="false" />

4 </system.web>

5 </configuration>

Pentru a preveni executarea de cod JavaScript pentru pagini care au speci-ficata inhibarea validarii cererilor, se poate folosi metoda de codificare a strin-gurilor HTML data de Server.HtmlEncode sau de HttpUtility.HtmlEncode:

1 protected void Page_Load(object sender, EventArgs e)

2 {

3 myLabel.Text = Server.HtmlEncode(TextBox1.Text);

4 }

modalitate care de fapt se recomanda ori de cate ori se face afisare de textpreluat dintr-o sursa de date oarecare.

8.7 JavaScript pentru controale utilizator

In cazul dezvoltarii de controale utilizator, este indicat ca produsul reali-zat sa poata fi folosit ca un modul ın pagina, fara a fi nevoie sa se cunoascadetaliile de implementare; implicit, toata partea de cod JavaScript necesarafunctionarii controlului trebuie sa fie ascunsa ın control. Exemplificarea ceurmeaza este preluata din [2].

Sa peresupunem ca se vrea crearea de ferestre popup pentru incarcareadiferitelor mesaje (reclame sau ajutor contextual). Acest lucru se face prinJavaScript, pe baza codului:

1 <script type="text/javascript">

2 window.open(’http://www.apress.com’, ’myWindow’,

3 ’toolbar=0, height=500, width=800, resizable=1, scrollbars=1’);

4 window.focus();

5 </script>

Metoda JavaScript Open primeste ca prim parametru adresa paginii caretrebuie deschisa, numele ferestrei care se deschide – util daca se doreste re-utilizarea ferestrei popup, pentru incarcarea de continut nou – apoi un sirde perechi de forma nume=valoare, specificand diferite aspecte vizuale aleferestrei de popup: dimensiuni, daca este sau nu redimensionabila, daca sa

Page 110: 41759043-Curs-Aspnet

110 CAPITOLUL 8. JAVASCRIPT SI AJAX

arate sau nu barele de derulare, sau daca se afiseaza ın prim plan sau ınfundal.

Putem crea un control ascx care sa poata fi inclus ın orice pagina; as-pectele vizuale pot fi setate prin proprietati. Controlul va putea fi utilizatıntr–o pagina web precum cele uzuale - etichete, casute de text etc. Avanta-jul controlului este ca permite reutilizarea usoara a codului, ıntr-o manieradeclarativa.

Codul pentru pagina de popup (controlul ascx) este:

1 using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using 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(); ");

Page 111: 41759043-Curs-Aspnet

8.7. JAVASCRIPT PENTRU CONTROALE UTILIZATOR 111

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

Page 112: 41759043-Curs-Aspnet

112 CAPITOLUL 8. JAVASCRIPT SI 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"];

}

Page 113: 41759043-Curs-Aspnet

8.7. JAVASCRIPT PENTRU CONTROALE UTILIZATOR 113

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 fi:

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

2 CodeBehind="UseCustomPopup.aspx.cs"

3 Inherits="DemoCurs8.UseCustomPopup" %>

4

5 <%@ Register src="CustomPopup.ascx" tagname="CustomPopup" tagprefix="uc1" %>

6

7 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

8 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

9

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

11 <head runat="server">

12 <title></title>

13 </head>

14 <body>

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

16 <div>

17 <uc1:CustomPopup ID="myCustomPopup" runat="server" PopUnder="true"

18 Url="http://localhost/index1.html" Resizable="true"/>

19 <uc1:CustomPopup ID="CustomPopup1" runat="server" PopUnder="false"

20 Url="http://localhost/index2.html" Resizable="true"/>

21 </div>

22 </form>

Page 114: 41759043-Curs-Aspnet

114 CAPITOLUL 8. JAVASCRIPT SI AJAX

23 </body>

24 </html>

O alta varianta de implementare este cea ın care controlul se dezvolta caun 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 for-mularului catre server si reafisarea paginii. Ca efect, se observa activitateasacadata "click si asteapta", precum si faptul ca pagina este reıncarcata, cusaltul la ınceputul ei. Desi pentru ASP.NET exista posibilitatea de a spe-cifica atributul MaintainScrollPositionOnPostback cu valoarea true ıncazul directivei de pagina, comportamentul vizual este acceptabil pe Inter-net Explorer, dar nesatisfacator pe Mozilla Firefox.

Ajax = Asynchronous JavaScript and XML este un grup de tehnici webinter-relationate care permit dezvoltarea de aplicatii web interactive sau cuun aspect asemanator cu cel al aplicatiilor ce ruleaza folosind doar resurselocale. Prin Ajax se pot aduce date de la server, ın mod asincron, fara a finecesara trimiterea propriu-zisa a formularului catre server; pagina ramaneıncarcata ın browser, dar anumite portiuni din ea sufera modificari pe bazacontinutului adus de la server.

JavaScript este de ajutor aici deoarece, presupunand problema preluariiasincrone a datelor rezolvata, permite identificarea fragmentelor de docu-ment care trebuie sa fie modificate si permite schimbarea lor. Totusi, doarJavaScript nu este suficient, deoarece el se descurca cu resurse locale, ın timpce pentru anumite actiuni utilizator este nevoie de preluare de date pe caredoar un server le poate furniza. Paginile care utilizeaza Ajax comunica ınfundal cu serverul; de ındata ce raspunsul este primit ın ıntregime, se efec-tueaza activitati aditionale. Din cauza caracterului asincron al comunicarii,pagina nu este ıntrerupta, iar utilizatorul poate sa efectueze si alte actiuniın ea. Raspunsul poate fi furnizat sub forma unui document XML sau caun simplu text. Este responsabilitatea codului Ajax scris de programator saparcurga raspunsul si sa actioneze ın consecinta.

Un aspect neplacut al programarii cu Ajax este faptul ca exista diferentemari ıntre browsere, ıncepand chiar de la formularea cererii. Exista bibliotecicross-browser care pot fi folosite ın acest sens.

2In original: custom server control.

Page 115: 41759043-Curs-Aspnet

8.8. AJAX 115

8.8.1 Obiectul XMLHttpRequest

Pentru a face comunicarea cu serverul dinspre pagina web, trebuie formu-lata o cerere catre server iar raspunsul trebuie sa fie preluat. Ambele actiunisunt efectuate de obiectul XMLHttpRequest. Obtinerea lui se face diferentiat,dupa browser: Internet Explorer 5 sau 6 foloseste ActiveX, iar IE7 si MozillaFirefox folosesc un obiect JavaScript nativ. Ca atare, codul de instantierea obiectului XMLHttpRequest trebuie sa fie scris luand ın considerare toatevariantele, deoarece nu se poate sti ce browser este folosit de catre client.Codul este:

1 var xmlRequest;

2 try

3 {

4 // Asta merge daca XMLHttpRequest face parte din JavaScript.

5 xmlRequest = new XMLHttpRequest();

6 }

7 catch(err)

8 {

9 // altfel, se cere serviciu de la ActiveX

10 xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");

11 }

12 //in acest punct obiectul XMLHttpRequest este instantiat

8.8.2 Trimiterea cererii

Pentru trimiterea unei cereri se folosesc metodele open() si send(). Primametoda seteaza datele de apel - adresa la care se face apelul si tipul de co-manda HTTP (GET, POST, PUT). Exemplu:

1 xmlRequest.open("GET" , myURL);

URL-ul apelat poate sa contina un query string cu perechi de atribute si va-lori; ceea ce se afla la adresa referita trebuie sa poata prelua acesti parametrisi sa formuleze raspunsul ın consecinta.

Se mai poate da un parametru optional care specifica daca cererea tre-buie sa fie trimisa asincron (implicit) si ınca doi care dau numele si parolautilizatorului (nerecomandat).

Metoda send() trimite efectiv comanda catre server:

1 xmlRequest.send(null);

Page 116: 41759043-Curs-Aspnet

116 CAPITOLUL 8. JAVASCRIPT SI AJAX

8.8.3 Procesarea raspunsului

Raspunsul se proceseaza prin intermediul unui manipulator de evenimentcare este apelat atunci cand soseste raspunsul catre browser. Manipulatoruleste o functie JavaScript care se apeleaza de catre browser:

1 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 fi accesat prin intermediul pro-prietactilor responseText si responseXML, proprietati ale obiectului XMLHttpRequest.Prima proprietate da raspunsul sub forma unui sir de caractere; a doua me-toda preia documentul ca un arbore de noduri. Se poate folosi si altcevadecat XML pentru crearea unui raspuns structurat, de exemplu JSON3 saucod 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 fie forma web(pagina aspx), poate fi o pagina HTML obisnuita;

• O alta pagina (aspx) sau manipulator de HTTP (cod ashx) care saprimeasca cererea si sa furnizeze un raspuns. Pagina sau handlerulpreia eventualii parametrii transmisi ca parte a adresei si formuleazaun 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 s–aefectuat calculul (cele doua valori - suma si momentul sunt despartite prinvirgula).

Codul pentru handlerul de HTTP care primeste cererea este:

1 using System;

2 using System.Collections.Generic;

3 using System.Linq;

4 using System.Web;

3JavaScript Object Notation.

Page 117: 41759043-Curs-Aspnet

8.9. UN EXEMPLU AJAX 117

5 using System.Web.Services;

6

7 namespace DemoCurs8

8 {

9 /// <summary>

10 /// Summary description for $codebehindclassname$

11 /// </summary>

12 [WebService(Namespace = "http://tempuri.org/")]

13 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

14 public class HandlerCalculator : IHttpHandler

15 {

16

17 public void ProcessRequest(HttpContext context)

18 {

19 HttpResponse response = context.Response;

20 HttpRequest request = context.Request;

21 //tipul de raspuns este text simplu

22 response.ContentType = "text/plain";

23 int value1, value2;

24 if (

25 int.TryParse(request.QueryString["value1"], out value1) &&

26 int.TryParse(request.QueryString["value2"], out value2)

27 )

28 {

29 int sum = value1 + value2;

30 response.Write(sum.ToString());

31 response.Write(",");

32 response.Write(DateTime.Now.ToString());

33 }

34 else

35 {

36 response.Write("-");

37 }

38 }

39

40 public bool IsReusable

41 {

42 get

43 {

44 return true;

45 }

Page 118: 41759043-Curs-Aspnet

118 CAPITOLUL 8. JAVASCRIPT SI AJAX

46 }

47 }

48 }

Pentru pagina web care folosesste Ajax se scrie codul:

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

2 CodeBehind="AjaxPage.aspx.cs" Inherits="DemoCurs8.AjaxPage" %>

3

4 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

5 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

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

7 <head runat="server">

8 <title>Pagina care foloseste Ajax</title>

9

10 <script type="text/javascript">

11 var xmlRequest;

12 function CreateXMLHttpRequest() {

13 try {

14 // Asta merge daca XMLHttpRequest face parte din JavaScript.

15 xmlRequest = new XMLHttpRequest();

16 }

17 catch (err) {

18 // altfel, se cere serviciu de la ActiveX

19 xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");

20 }

21 //in acest punct obiectul XMLHttpRequest este instantiat

22 }

23

24 function sendRequest()

25 {

26 xmlRequest.open("GET", "HandlerCalculator.ashx?value1=" +

27 document.getElementById(’TextBoxValue1’).value +

28 "&value2=" + document.getElementById(’TextBoxValue2’).value);

29 xmlRequest.onreadystatechange = UpdatePage;

30 xmlRequest.send(null);

31 }

32

33 function UpdatePage()

34 {

35 if (xmlRequest.readyState == 4)//primire completa de raspuns

36 {

Page 119: 41759043-Curs-Aspnet

8.9. UN EXEMPLU AJAX 119

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

38 {

39 var response = xmlRequest.responseText;

40 var lblResult = document.getElementById(’lblResult’);

41 if (response == ’-’)

42 {

43 lblResult.innerHTML = ’Nu se poate calcula suma’;

44 }

45 else

46 {

47 var tokens = response.split(’,’);

48 lblResult.innerHTML = ’Suma este: ’ + tokens[0] +

49 ’<br />Calculata la: ’ + tokens[1];

50 }

51 }

52 }

53 }

54 </script>

55

56 </head>

57 <body onload="CreateXMLHttpRequest();">

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

59 <div>

60 <img src="images/anilion1_e0.gif" alt="leu" /><br />

61 Primul numar:

62 <asp:TextBox ID="TextBoxValue1" runat="server"

63 onkeyup="sendRequest();"></asp:TextBox>

64 <br />

65 Al doilea numar:

66 <asp:TextBox ID="TextBoxValue2" runat="server"

67 onkeyup="sendRequest();"></asp:TextBox>

68 <br />

69 <asp:Label ID="lblResult" runat="server"></asp:Label>

70 </div>

71 </form>

72 </body>

73 </html>

Page 120: 41759043-Curs-Aspnet

120 CAPITOLUL 8. JAVASCRIPT SI AJAX

Page 121: 41759043-Curs-Aspnet

Capitolul 9

ASP.NET membership

ASP.NET pune la dispozitie un API pentru gestiunea utilizatorilor carepot sa acceseze o aplicatie. Se ofera suport pentru urmatoarele operatii, careın mod normal ar trebuie implementate de fiecare data ın cadrul unei aplicatiiweb:

• crearea si stergerea de utilizatori programatic sau prin interfata pusala dispozitie automat;

• abilitatea de a reseta parole, cu posibilitatea de a trimite noua parolaprin email, daca a fost specificata o adresa;

• posibilitatea de a se crea parole ın mod automat, daca se folosestecrearea programatica a utilizatorilor;

• determinarea listei de utilizatori, ımpreuna cu detaliile asociate;

• controale predefinite pentru loginare, creare de utilizator, resetare deparola;

O ierarhizare a acestor functionalitati este data ın figura 9.1.Exemplificarea 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 gestio-neaza utilizatorii, acest lucru este posibil prin implementarea unui furnizor de“membership”. API-ul furnizat este insenzitiv la modul de stocare al detalii-lor legate de utilizator - particularitatile de accesare a datelor sunt rezolvatela nivelul implementarii de furnizor de “membership”.

Pasii ce trebuie urmati pentru utilizarea unui API-ului de membershipsunt:

1. configurarea modului de autentificare ın fisierul web.config;

121

Page 122: 41759043-Curs-Aspnet

122 CAPITOLUL 9. ASP.NET MEMBERSHIP

Figura 9.1: Elementele utilizate ın lucrul cu “membership”-ul furnizat deASP.NET [2]

Page 123: 41759043-Curs-Aspnet

9.1. CONFIGURAREA AUTENTIFICARII PRIN FORME 123

2. setarea detaliilor relativ la stocarea datelor utilizatorilor;

3. configurarea stringului de conexiune si a furnizorului de membership;

4. crearea de utilizatori ai aplicatiei web;

5. crearea unei pagini de login.

9.1 Configurarea autentificarii prin forme

Trebuie mai ıntai structurata aplicatia ca resurse protejate prin nume siparola, grupate sub forma de directoare. De regula, ın radacina aplicatieiWeb trebuie sa fie lasate doar paginile care accepta accesare de utilizatoranononim (neautentificat), cum ar fi pagina de login sau cea ın care se creeazacontul. In rest, paginile sunt grupate ın directoare pentru care se specifica totprin fisier de configurare ca nu se accepta decat apel de utilizator autentificat.

Primul pas e deci de a specifica forma de autentificare. In fisierul web.configdin radacina aplicatiei se va scrie:

<system . web><authen t i c a t i on 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 nu-mai accesarea de catre utilizatori autentificati, atunci se va crea un fisierweb.config (comanda add new item din solution explorer) care sa contina:

<con f i gu ra t i on ><system . web><author i za t i on ><deny use r s="?" />

</author i za t i on ></system . web>

</con f i gu ra t i on >

Simbolul “?” refera un utilizator neautentificat. Datorita acestei setari, oriceutilizator care doreste sa acceseze o pagina aspx din directorul “protejat” vafi verificat: daca are tichetul furnizat de un proces de autentificare, atunci ise permite accesul; altfel, este redirectat automat la pagina de login.

Page 124: 41759043-Curs-Aspnet

124 CAPITOLUL 9. ASP.NET MEMBERSHIP

9.2 Crearea sursei de date

Daca se foloseste SQL Server Express Edition 2005 ın conjunctie cuASP.NET, furnizorul de “membership” va crea automat un fisier de date,cu o structura bine definita, care va putea fi folosit pentru memorarea date-lor utilizatorilor. Se va crea un fisier numit ASPNETDB.MDF ın directorulApp_Data al aplicatiei web. Desi functioneaza satisfacator pentru etapa dedezvoltare, este total neadecvat pentru un sistem aflat ın productie. Dacaeste o versiune de server diferita de ce s-a spus (de exemplu: SQL Server2000 sau 2005 non-express), atunci se poate interveni pentru a crea aceastasursa de date ın interiorul unui server, sau chiar ın interiorul unei baze dedate preexistente. Aceasta varianta (evitarea fisierului ASPNETDB.MDF) esugerata pentru sisteme de productie.

Pentru crearea structurii de tabele necesare pentru memorarea datelor deautentificare se poate folosi utilizatrul din linie de comanda aspnet_regsql.exe,pornit din varianta de command prompt realizata de instalarea lui .NET Fra-mework. Pornirea uneltei ın sistem “wizard” se face prin tastarea numeluiaplicatiei pomenite, dupa care va aparea fereastra din figura 9.2. Wizard-ulpermite fie adaugarea structurilor de date necesare la un server, fie stergerealor (figura 9.3). Ulterior, se specifica: serverul SQL ın care se va face sal-varea datelor si contul de acces pentru server (cont necesar utilitarului) -figura 9.4. In baza de date specificata se vor crea tabele – precum se vedeın figura 9.5 – care vor stoca datele legate de utilizatori, profiluri, roluri etc.Structura acestor tabele nu trebuie sa fie ınteleasa de catre programator, eava fi folosita de catre API-ul de “membership”.

Mentionam ca unealta de integrare poate fi folosita si exlusiv din linia decomanda cu parametri, fara a fi nevoie sa se utilizeze wizard–ul grafic dinfigurile 9.2 - 9.5.

9.3 Configurarea stringului de conexiune si a

furnizorului de “membership”

Daca s–a folosit utilitarul aspnet_regsql ca mai sus, atunci este nevoiesa se specifice ın fisierul de configurare web.config stringul de conexiune careva fi folosit pentru furnizorul de membership SQL. Acest lucru se face ca laorice string de conexiune, prin adagarea ın sectiunea connectionStrings aunei intrari:

<connec t i onSt r ings ><add name="myConStrMembership"

Page 125: 41759043-Curs-Aspnet

9.3. CONFIGURAREA STRINGULUI DE CONEXIUNE SI A FURNIZORULUI DE “MEMBERSHIP”

Figura 9.2: Utilitarul de configurare a sursei de date pentru autentificare

Figura 9.3: Specificarea modului de lucru pentru utilitarul aspnet_regsql

Page 126: 41759043-Curs-Aspnet

126 CAPITOLUL 9. ASP.NET MEMBERSHIP

Figura 9.4: Specificarea serverului, contului si bazei de date

Figura 9.5: Tabelele rezultate dupa utilizarea uneltei de integrare a serveruluide baze de date cu partea de SQL Membership din ASP.NET

Page 127: 41759043-Curs-Aspnet

9.3. CONFIGURAREA STRINGULUI DE CONEXIUNE SI A FURNIZORULUI DE “MEMBERSHIP”

connec t i onSt r ing="data source=( l o c a l )\ develop ;user id=sa ; password=1q2w3ei n i t i a l c a ta l og=t e s t " />

</connec t i onSt r ings >

Pentru a specifica apoi metoda de autentificare, se va adauga ın fisierulweb.config un element ce precizeaza modul de autentificare:

<system . web><authen t i c a t i on mode="Forms" />

<membership de f au l tProv ide r="MyMembershipProvider"><prov ider s><add name="MyMembershipProvider"connectionStringName="myConStrMembership"applicationName="/"enablePasswordRetr i eva l=" f a l s e "enablePasswordReset=" true "requiresQuestionAndAnswer=" true "requiresUniqueEmai l=" true "passwordFormat="Hashed"type="System .Web. Secu r i ty . SqlMembershipProvider " />

</prov ider s></membership>

</system . web>

In interiorul elementului membership pot exista mai multe elemente providers,dar cel specificat prin intermediul atributului defaultProvider este cel aflatın uz. La lansarea interfetei de administrare a aplicatiei – Project → ASP.NETConfiguration – se va putea alege dintre furnizorul implicit si cel definit an-terior – MyMembershipProvider – asa cum se vede ın figura 9.6.

Atributele elementului add din cadrul furnizorului definit sunt:

• name - defineste un nume unic asociat furnizorului curent;

• applicationName - numele aplicatiei web pentru care functioneaza fur-nizorul de securitate ales

• description - o descriere optionala

• passwordFormat - formatul ın care vor fi salvate parolele ın baza dedate; valori posibile: Clear, Encrypted, Hashed

• minRequiredNonalphanumericCharacters - care este numarul minim decaractere non-alfanumerice care sunt cerute ın parola

Page 128: 41759043-Curs-Aspnet

128 CAPITOLUL 9. ASP.NET MEMBERSHIP

Figura 9.6: Configurare din aplicatia de administrare a aplicatiei Web

• minRequiredPasswordLength - lungimea minima a parolei

• passwordStrengthRegularExpression - o expresie regulata care descrieformatul 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 fi recuperataprin apeluri de metode din API-ul de membership; posibil d.n.d nu s–afolosit varianta de “Hashed”

• maxInvalidPasswordAttempts - numarul maxim de ıncercari consecu-tive gresite suportate de sistem pentru un utilizator; daca se ajungela acest prag, contul utilizatorului este dezactivat pentru o anumitaperioada

• passwordAttemptWindow - cat timp este blocat un utilizator care faceprea multe ıncercari de introducere a unei parole;

• requiresQuestionAndAnswer - daca pentru recuperarea parolei utiliza-torul trebuie sa dea un raspuns la o ıntrebare;

Page 129: 41759043-Curs-Aspnet

9.4. CREAREA DE UTILIZATORI 129

• requiresUniqueEmail - specifica daca adresa de email trebuie sa fieunica 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 figura 9.7.

Figura 9.7: Adaugarea unui utilizator

Din acest moment se poate folosi ın partea de code–behind:

protected void LoginAction_Click ( object sender , EventArgs e ){i f (Membership . Val idateUser ( UsernameText . Text , PasswordText . Text ) ){FormsAuthentication . RedirectFromLoginPage ( UsernameText . Text , fa l se ) ;

}else{LegendStatus . Text = "Nume i n v a l i d ! " ;

Page 130: 41759043-Curs-Aspnet

130 CAPITOLUL 9. ASP.NET MEMBERSHIP

}}

cu sanse de autentificare 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 catreASP.NET sau prin pagini create de programator. Controalele ASP.NETsunt:

• Login - control compus care rezolva cele mai multe probleme legate deautentificare - afisarea unor casute de text ın care se pot scrie numelede utilizator si parola;

• LoginStatus - exprima starea de autentificare a unui utilizator; daca nue autentificat, utilizatorul va vedea un buton a carui apasare va ducela redirectarea catre pagina de login; altfel va afisa un buton de logout;

• LoginView - permite afisarea conditionala a diferitelor controale; dacautilizatorul este autentificat, atunci va vedeaun anumit continut, altfelun altul;

• PasswordRecovery - permite recuperarea parolei de catre utilizator;

• ChangePassword - cere parola veche si permite specificarea unei noiparole;

• CreateUserWizard - include un wizard complex care permite creareade conturi utilizator.

Avantajul acestor controale este minimul de cod care trebuie scris pentrua putea face uz de partea de membership.

9.5.1 Controlul Login

-demo liveFata de setarile implicite ale controlului, se mai poate interveni asupra

proprietatilor:

• CreateUserText - arata textul de pe un link care va fi folosit pentruredirectare catre o pagina care da posibilitatea de a crea un nou contde utilizator;

Page 131: 41759043-Curs-Aspnet

9.5. CREAREA UNEI PAGINI DE LOGIN 131

• 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 contsau parola

• DestinationPageUrl - adresa paginii catre care se face redirectare dacaautentificarea este reusita; este valabila ın cazul ın care utilizatorul nua fost redirectat catre pagina de login dintr-o pagina protejata;

• PasswordRecoveryUrl - adresa paginii de unde se poate face recupe-rarea parolei

Se pot trata urmatoarele evenimente:

• LoggingIn - apare ınainte ca utilizatorul sa se logineze;

• LoggedIn - apare dupa ce utilizatorului i s–au recunoscut numele siparola introduse;

• LoginError - daca numele si parola introduse nu sunt recunoscute

• Authenticate - gestioneza procesul de autentificare; daca se implemen-teaza un manipulator pentru eveniment, atunci ıntreaga responsabili-tate a verificarii identitatii sistemului este ın sarcina programatorului.

9.5.2 Controlul LoginStatus

-demo live

9.5.3 Controlul LoginView

Permite afisarea unor seturi diferite de controale, ın functie de autentifica-rea utilizatorului: autentificat sau nu; mai departe, se pot face particularizariın functie de rolul pe care ıl are utilizatorul. Controlul consta din template-uri, fiecare avand un anumit continut.

-demo live

9.5.4 Controlul PasswordRecovery

-demo live

Page 132: 41759043-Curs-Aspnet

132 CAPITOLUL 9. ASP.NET MEMBERSHIP

9.5.5 Controlul ChangePassword

-demo live

9.6 Gestiunea utilizatorilor prin API-ul de “mem-

bership”

Este posibil ca la un momemnt dat sa se doresca scrierea de cod care sapermita gestionarea prin cod a utilizatorilor. Plecand de la metodele oferitede clasa Membership, se pot face urmatoarele operatii:

• creare de noi utilizatori

• stergerea de utilizatori

• modificarea 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 tipMembershipUser 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 co-loanele: username, email si ınca o coloana ce contine link de selectare. Codulpentru crearea de grid ın pagina aspx este:

<asp : GridView ID="GridView1" runat=" s e r v e r "AutoGenerateColumns=" False " DataKeyNames="UserName">

<Columns><asp : CommandField ShowSelectButton=" true " /><asp : BoundField DataField="UserName"

HeaderText="username" /><asp : BoundField DataField="Email"

HeaderText=" emai l address " /></Columns>

</asp : GridView>

Legarea la date se poate face din partea de code-behind astfel:

Page 133: 41759043-Curs-Aspnet

9.6. GESTIUNEA UTILIZATORILOR PRIN API-UL DE “MEMBERSHIP”133

public p a r t i a l class Al lUser s : System .Web. UI . Page{

MembershipUserCol lect ion a l lU s e r s ;

protected void Page_Load( object sender , EventArgs e ){

a l lU s e r s = Membership . GetAl lUsers ( ) ;GridView1 . DataSource = a l lU 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 afla detalii de interes. Pentrucodul de mai sus, ın partea de code-behind se adauga metoda:

protected void GridView1_SelectedIndexChanged ( object sender ,EventArgs e )

{MembershipUserCol lect ion allUsersWithName =

Membership . FindUsersByName ( GridView1 . Se lec tedValue as string ) ;i f ( allUsersWithName . Count == 1){

Label1 . Text = "Last l o g i n date " +allUsersWithName [ GridView1 . Se lec tedValue as string ] .LastLoginDate . ToString ( ) ;

}}

9.6.3 Modificarea datelor unui utilizator

O data ce este regasit obiectul de tip MembershipUser pentru un utilizatorale carui date trebuie schimbate, se pot accesa diferite proprietati ale sale(EmailText, CommentTextBox, IsApprovedCheck etc) iar via metoda staticaMembership.UpdateUser(obiect) se face salvarea datelor modificate.

9.6.4 Crearea si stergerea unui utilizator

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

Page 134: 41759043-Curs-Aspnet

134 CAPITOLUL 9. ASP.NET MEMBERSHIP

9.6.5 Validarea unui utilizator

Validarea utilizatorului vizavi de sursa de date folosite se face prin in ter-mediul metodei statice Membership.ValidateUser(string username, string

password).

Page 135: 41759043-Curs-Aspnet

Bibliografie

[1] D. Gourley, B. Totty, M. Sayer, S. Reddy, and A. Aggarwal. HTTP: The

Definitive Guide. O’Reilly, 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 siInformatica, Universitatea Transilvania din Brasov, 2009.

[4] C. Wong. HTTP Pocket Reference. O’Reilly, 2000.

135