ASP.NET 2.0 Web stranice i Web kontrole Svi dosadašnji primjeri bili su ili konzolne aplikacije ili aplikacije temeljene na Windows formama. U ovom je dijelu dan pregled mogućnosti koje .NET platforma nudi u kreiranju prezentacijskog sloja kojeg koristi pretraživač. Zbog toga će u početku biti dan kratki pregled ključnih koncepata orijentiranih na Web (HTTP, HTML, skripte na klijentskoj strani, skripte na serverskoj strani) i ulogu Web servera u svemu tome (uključujući ASP.NET razvojni server WebDev.WebServer.exe). Izlaganje u ovom dijelu rezervirano je za predstavljanje osnovnih dijelova ASP.NET-a i na način korištenja Web kontrola. ASP.NET 2.0 nudi brojne nove Web kontrole, novi model «master stranice» i različite tehnike prilagođavanja. Uloga HTTP-a Web aplikacije su sasvim različite od tradicionalnih desktop aplikacija. Prva očigledna razlika je u broju korištenja računala. Standardna Web aplikacija koristi barem dva umrežena računala (tijekom razvoja sve se može testirati na jednom računalu). S tom činjenicom na umu, umrežena računala moraju razmjenjivati podatke poštivajući pravila protokola. U ovom je slučaju riječ o HTTP protokolu. Kada se na klijentskom računalu pokrene Web pretraživač (Netscape Navigator, Mozzila Firefox, ili Microsoft Internet Explorer), uputi se HTTP zahtjev za dohvaćanjem određenih resursa (primjerice datoteke *.aspx ili *.htm) sa udaljenog serverskog računala. HTTP je tekstualni protokol izgrađen temeljem standardne zahtjev/odgovor paradigme. Primjerice, kada upišemo u pretraživač adresu http://www.fesb.hr, softver pretraživača koristi Web tehnologiju koja se zove Domain Name Service (DNS) koji pretvara registrirano ime u 32 bitni broj (IP adresa). U tom trenutku, pretraživač otvara vezu preko soketa (tipično preko porta 80) i šalje HTTP zahtjev za postavljenom stranicom na adresi http://www.fesb.hr website-u. Jednom kada host zaprimi HTTP zahtjev, specificirani resurs možda ima ugrađenu logiku kojom dohvaća bilo kakvu vrijednosti koje mu dostavlja klijent (primjerice vrijednosti unutar tekst boxa), sa ciljem da formatira odgovarajući HTTP odgovor. Web programerima stoje na raspolaganju brojne tehnologije (CGI, ASP, ASP.NET, Java servleti, itd.) da dinamički generiraju sadržaj koji će vratiti u HTTP odgovoru. U tom trenutku, pretraživač na klijentskoj strani prikazuje HTML koji je poslao Web server. Na slici je predstavljen temeljni HTTP zahtjev/odgovor ciklus. Slika 1. Osnovni dio HTTP protokola: zahtjev/odgovor ciklus Drugi razlog koji Web programiranje čini izrazito različitim od stvaranja tradicionalnih desktop aplikacija leži u činjenici da je HTTP protokol u kojem nema provjere stanja u kojem se nalaze bilo klijent ili server (stateless protokol). Sve dok Web server emitira odgovor klijentu, sve što je bilo prije toga je zaboravljeno. To znači da na programeru leži odgovornost «pamćenja» eventualno bitnih stvari (primjerice, odabrani proizvodi u web trgovini) o klijentu koji je trenutno vezan za određeni Web site. ASP.NET tehnologija nudi brojne načine pamćenja stanja, od koji mnogi zauzimaju standardno mjesto na bilo kojim web platformama (varijable sesije, kukiji, aplikacijske varijable), ali i neke nove tehnike (pregled stanja, upravljanje stanjem i cache). Razumijevanje Web aplikacije i Web servera Web aplikacija može se shvatiti kao skup datoteka (*.htm, *.asp, *.aspx, datoteke sa slikama, itd.) i odgovarajućih komponenti (.NET datoteka koda) koje su pohranjene na određenom direktoriju određenog Web servera. Web aplikacija ima specifični životni ciklus i omogućava brojne događaje (inicijalno pokretanje-startup i konačno gašenjeshutdown) na koje se možemo zakačiti (pozvati). Web server je softver čiji je zadatak ugostiti vašu veb aplikaciju i tipično nudi brojne servise kao što su sigurnosni servisi, podrška za FTP, servis za razmjenu pošte, itd. IIS je Microsoftov proizvod (program) koji radi kao web server i podrazumijeva podršku za ASP.NET web aplikacije i za klasični ASP. Kada izrađujemo ASP.NET web aplikacije, često dolazi do interakcije sa IIS-om. IIS treba dodatno instalirati. Ako je instaliran, do interakcije može doći korištenjem foldera za Administrativne alate. Za primjere koji slijede dovoljno je koristiti Default-ni Web Site čvor. Korištenje IIS virtualnih direktorija Jedna jedina IIS instalacija dovoljna je za prikaz brojnih web aplikacija, od kojih je svaka pohranjena u zasebnom virtualnom direktoriju. Svakom virtualnom direktoriju pridruženo je odgovarajuće fizičko mjesto na lokalnom hard disku.. Stoga, kreiramo li novi virtualni direktorij kojeg možemo nazvati ProbniWeb, do ovog će site-a vanjski korisnici dolaziti upisivanjem adrese http://www.ProbniWeb.hr, pod pretpostavkom da imate odgovarajući registrirani site, a ispod svega toga, virtualni direktorij bit će mapiran na odgovarajuće fizičko mjestio na disku, primjerice: C:\Inetpub\wwwroot\AspNetProbniWeb, u kojem su svi dijelovi web aplikacije. Kada se kreira Web aplikacija korištenjem Visual Studia 2005, na raspolaganju stoji opcija kreiranja virtualnog direktorija za trenutni website. Također postoji mogućnost da sami, ručno, kreiramo website. Primjerice, želite li kreirati jednostavnu web aplikaciju koja se zove Test. Prvi je korak kreirati direktorij koji sadrži skup datoteka koje grade taj novi site (npr. D:\Web\TestWebSite). Slijedeće, trebamo kreirati novi virtualni direktorij koji će služiti kao host Test site-u. Desnim klikom kliknemo na DefaultWebSite čvor IIS-a i odaberemo ->New>Vitual Directory iz ContexMenua. Ova opcija pokreće ugrađenog čarobnjaka. Preskočite formu sa dobrodošlicom i upišite ime vašeg website-a (TestWebSite). U slijedećem koraku vas se pita da specificirate fizički direktorij u kojem su datoteke i slike koje grade vaš site. Treba upisati D:\Web\TestWebSite. U zadnjem koraku čarobnjak traži dodatne informacije tipa dostupnosti datoteka (read, write, mogućnost pregledavanja datoteka preko pretraživača, mogućnost pokretanja izvršnih datoteka-npr. cgi aplikacija i sl.). Za ovaj primjer, dovoljno je ne mijenjati defaultne vrijednosti (bude li trebalo, to se može uvijek napraviti aktiviranjem desnog klika). Kada završite, možete se uvjeriti da je novi virtualni direktorij registriran sa IIS. ASP.NET 2.0 razvojni server ASP.NET 2.0 isporučuje se sa web serverom imena WebDev.WebServer.exe. Ovaj program omogućava hostanje ASP.NET web aplikacija van granica IIS-a. Korištenjem ovog alata, može se izgraditi i testirati stranica iz bilo kojeg direktorija na računalu (što je zgodno za izgradnju ASP.NET 2.0 web programa na Windowsima XP Home Edition koji ne podržava IIS). Kada aplikaciju gradimo sa Visual Studiom 2005, postoji opcija WebDev.WebServer.exe za hostanje stranica. Ovaj se alat može koristiti i ručno i iz .NET komandnog prompta sa naredbom: WebDev.WebServer.exe -? Nakon čega se pojavljuje linija u koju je potrebno upisati odgovarajuće opcije sa komandne linije, što znači specificirati nekorišteni port (opcija /port) i root direktorij web aplikacije (korištenjem /path opcije). Primjerice: WebDev.WebServer.exe /port:12345 /path: «D:\Web\TestWebSite» Jednom kada je naredba upisana, može se pokrenuti pretraživač i zahtijevati stranicu. Dakle, pretpostavimo li da je u direktoriju AutiWebSite datoteka koja se zove MyPage.aspx, može se upisati slijedeći URL: http://localhost:12345/MyPage.aspx Brojni primjeri koji slijede koristit će upravo WebDev.WebServer.exe preko VisualStudia 2005. Ovaj web server nije namijenjen hostanju web aplikacija produkcijskog nivoa. Namijenjen je samo razvoju i testiranju. Uloga HTTP-a Jednom kada je konfiguriran direktorij koji hosta web aplikaciju, treba generirati sadržaj aplikacije. Podsjetimo se da je web aplikacija samo izraz kojim obilježavamo skup datoteka koje konstituiraju funkcionalnost site-a. Sigurno će brojne od tih datoteka sadržavati sintaktičke tokene definirane sa HTML-om koji nam služi da bi opisali kako želimo predstaviti tekst, slike, linkove i različite druge grafičke komponente stranice na klijentskoj strani. Ovaj aspekt web razvoja mnogi programeri ne vole jer, iako mnogi alati generiraju HTML kod, dobro je imati nekakvo znanje o HTML-u ako se radi sa ASP.NET-om. Dakle, osnovni HTML dokument izgledao bi: <html> <head> <title> Ovo je nekakav WebSite</title> </head> <body> </body> </html> <title> tag se korist za postavljanje stringa u naslovnu traku pretraživača koji poziva određenu stranicu. Razvoj HTML formi Stvarna događanja neke *.htm datoteke pojavljuju se unutar dosega tzv. <form> elementa. HTML form je jednostavno imenovana grupa povezanih elemenata korisničkog sučelja koja se koristi da bi prikupili ulazne podatke od korisnika, koji se zatim prenose do web aplikacije pomoću HTTP-a. Ne treba brkati HTML formu sa čitavim područjem kojeg prikazuje pretraživač. U stvarnosti, neka HTML forma je više logičko grupiranje dijelova koje umećemo unutar <form> i </form> tagova na slijedeći način: <html> <head> <title> Ovo je Auto WebSite</title> </head> <body> <form id= «defaultPage» name «defaultPage»> <!—Ovdje je sadržaj Web-a> </form> </body> </html> Ovoj je formi pridružen odgovarajući ID i ime «defaultPage». Tipično, otvaranje <form> tag-a podupiremo sa akcijskim atributima koji specificiraju URL kojem proslijeđujemo podatke sa forme, kao i metode kojima prenosimo te podatke (POST ili GET). Pogledajmo koji se sve elementi mogu uključiti u HTML formu. Visual Studio 2005 omogućava HTML tab na Toolbox-u koji dozvoljava odabir odgovarajućeg grafičkog dijela korisničkog sučelja (vidi Sliku). Slika 2. Kreiranje izgleda stranice pomoću HTML tab-a u Toolbox-u. Izrada HTML korisničkog sučelja Prije nego dodamo u dokument određene dijelove sučelja, vrijedno je napomenuti da Visual Studio 2005 dozvoljava editiranje *.htm datoteke korištenjem HTML projektanta i prozora sa Svojstvima (property). Odabirom opcije DOCUMENT iz dialoga Properties (vidi sliku) možemo konfigurirati odgovarajuće dijelove HTML stranice, primjerice boju pozadine. Kreirajmo izgled stranice slijedećim kodom: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Testni Web Site</title> </head> <body bgcolor="NavajoWhite"> <h1 align="center">Testna Login stranica</h1> <form id="defaultPage" name ="defaultPage" runat="server"> <p align="center"> User name: <input id="txtUserName" type="text" name="txtUserName" ></p> <p align="center"> Password: <input id="txtPassword" type="password" name="txtPassword" ></p> <p align="center"> <input id="btnSubmit" type="submit" name="btnSubmit" value="Submit" > <input id="btnReset" type="reset" name="btnReset" value="Reset" > </p> </form> </body> </html> Primijetite da smo sastavnim dijelovima HTML dokumenta pridjelili odgovarajuće ime i ID (texUserName, txtPassword, btnSubmit, btnReset). Osim toga svaka ulazna jedinica ima i svoj tip (type) koji ove cjeline čini sastavnim dijelovima grafičkog sučelja u kojem se automatski sva polja postavljaju na odgovarajuće postavne vrijednosti. Primjerice tip «password» omogućava automatsko pretvaranje slova u zaštićene znakove, tip «reset» omogućava brisanje unesenih vrijednosti, a «submit» omogućava slanje podataka primatelju. Na donjoj je slici prikaz stranice dobivene gornjim kodom. Slika 3. Izgled stranice generirane HTML kodom Uloga skriptiranja na klijentskoj strani Određena *.htm datoteka može sadržavati blokove skriptnog koda koji će biti prikazani u strimu sa odgovorom i kojeg će obrađivati pretraživač preko kojeg se pozove određena *.htm datoteka. Dva su razloga zbog kojih se koristi skriptiranje na klijentskoj strani - da bi se procijenilo ono što korisnik unese, a što će se kasnije obrađivati na serverskoj strani - da bi došlo do interakcije sa DOM-om (Document Object Model) ciljnog pretraživača Obzirom na prvi razlog, treba shvatiti da je nužno zlo web aplikacija potreba da se često izvode kružni prolasci prema serveru (postback) kako bi se ažurirao HTML prikazan u pretraživaču. Kako su ti pozivi nezaobilazni, uvijek treba voditi računa da broj prolazaka preko mreže bude što manji. Jedan od načina na koji se to postiže upravo je skriptiranje na klijentskoj strani kojim procjenjujemo korisnikov unos prije nego ga proslijedimo preko forme na serversku stranu. Ukoliko se pronađe greška (primjerice neko od važnih polja nije popunjeno), možemo obavijestiti korisnika, bez izazivanja nepotrebnih troškova zbog slanja nepotpunog dokumenta preko mreže. Osim procjenjivanja korisnikovog unosa, klijentsko skriptiranje može se koristiti za interakciju sa DOM-om samog pretraživača (objektni model dokumenta ugrađen u pretraživač). Većina komercijalnih pretraživača predstavljaju se kao skup objekata preko kojih se može upravljati načinom na koji se pretraživač ponaša. Jedan od najvećih izvora problema leži u činjenici da većina pretraživača predstavljaju slične, ali ne i identične objektne modele. Stoga, ukoliko prikažemo blok skriptnog koda na klijentskoj strani koji ima interakciju sa DOM-om, taj neće raditi jednako na svim pretraživačima. ASP.NET ima svojstvo HttpRequest.Browser, preko kojeg možemo tijekom izvođenja odrediti kapacitet određenog pretraživača. Postoji jako puno skriptnih jezika kojima se može autorizirati skriptni kod na klijentskoj strani. Dva su jako popularna: VBScript i JavaScript. VBScript je dio Visual Basic-a 6.0. IE je jedini pretraživač koji ima ugrađenu podršku za VB skript na klijentskoj strani. Zbog toga, ukoliko želite da HTML radi ispravno na bilo kojem komercijalnom pretraživaču, ne bi smjeli koristiti VBScript za skriptiranje logike na klijentskoj strani. Drugi popularni skriptni jezik je JavaScript. JavaScript ni oblikom ni dijelom nije sastavni dio Java jezika. Iako imaju donekle sličnu sintaksu, JavaScript nije potpuno OO jezik i zbog toga je i manje moćan od Jave. Dobra stvar je što današnji pretraživači podržavaju JavaScript, što ga čini prirodnim kandidatom za skriptiranje na klijentskoj strani. Primjer klijentske skripte Da bi ilustrirali ulogu skripte na klijentskoj strani, promotrimo kako se hvataju događaji koji dolaze sa dijelova grafičkog sučelja na klijentskoj strani. Pretpostavimo da imamo HTML botun (btnHelp) na defaultnoj stranici koji dozvoljava korisniku da pročita help. Da bi uhvatili Click događaj ovog botuna, u HTML view ubacite botun (preko Toolbox-a ili ručno), zatim ga odaberite preko «Client Objects and Events» i ubacite događaj «on click». U konacnici originalni HTML nadopunjen je sa linijom: <input id="btnHelp" btnHelp_onclick()" /> type="button" value="Help" onclick="return Možete dodati još atribut language=”javascript”. Visual Studio 2005 sam će kreirati praznu JavaScript funkciju koja će se pozvati kada korisnik pritisne botun. U praznu funkciju mozemo dodati naredbu: alert (“Ovo je Help botun!”). Cijela funkcija trebala bi izgledati: <script language="javascript" type="text/javascript"> // <!CDATA[ function btnHelp_onclick() { alert ("Ovo je Help botun!"); } // ]]> </script> Skriptni blok ubačen je u HTML kod pomoću zagrada <!...> koje označavaju komentar. Razlog za to je jednostavan: ukoliko tu stranicu pošaljemo pretraživaču koji nema podršku za JavaScript, taj dio neće utjecati na prikaz ostalog dijela stranice, jednostavno će se ignorirati. Naravno, u tom će slučaju stranica biti manje funkcionalna ali će se barem ostali dio prikazati onako kako smo naznačili. Provjera valjanosti podataka forme Proširimo default.htm sa ciljem ugrađivanjem logike za provjeru valjanosti na klijentskoj strani. Cilj nam je pozvati JavaScript funkciju koja provjerava jesu li svi dijelovi forme popunjeni u trenutku kada korisnik pritisne Submit botun. Ako nisu, generiramo popup koji korisnika obaviještava šta treba napraviti. Zbog toga i na Submit botun trebamo dodati funkciju koja će se izvesti kada ga pritisnemo: function btnSubmit_onclick() { if ((defaultPage.txtUserName.value=="")||(defaultPage.txtPassword.value==" ")) { alert ("Morate upisati korisnicko ime i password!"); return false; } return true; } Nakon ovoga, možete učitati stranicu preko pretraživača upisivanjem URL-a: http://localhost/TestWebSite/default.htm i vidjeti kako funkcionira skriptna logika. Slanje podataka sa forme (GET i POST) Sada kada imamo jednostavnu HTML stranicu, moramo istražiti kako podatke sa forme proslijediti natrag do servera. Pri gradnji HTML forme, obično ubacujemo akcijski atribut pri otvaranju forme sa <form> tagom da bi specificirali primatelju nadolazeće podatke sa forme. Podatke mogu primati mail serveri, druge HTML datoteke, datoteke Active Server Pages (klasični ASP ili ASP.NET) i sl. Za ovaj primjer koristit ćemo klasičnu ASP datoteku ClassicAspPage.asp. Potrebno je ažurirati default.htm specificiranjem atributa u <form> tagu: <form id="defaultPage" name ="defaultPage" runat="server" action="http://localhost/TestWebSite/ClassicAspPage.asp" method="get"> Ovaj nam atribut osigurava da kada pritisnemo Submit botun, podaci sa forme šalju se ClassicAspPage.asp datoteci koja se nalazi na specifičnom URL-u. Specificiranjem moda GET kao načina slanja, podaci sa forme nadodavaju se na query string kao skup parova sa imenom/vrijednosšću odvojenih znakom «&». http://localhost/TestWebSite/ClassicAspPage.asp?txtUserName=Marko&txtPa ssword=mlnz423&btnSubmit=Submit Drugi je način da specificiramo metodu POST: U ovom slučaju podaci sa forme se ne dodaju u query string, nego se upišu u posebnu liniju u HTTP zaglavlju. Korištenjem POST-a, podaci forme nisu direktno vidljivi vanjskom svijetu. Još je važnije da POST nema ograničenja u korištenju dužine karaktera (mnogi pretraživači imaju limite za GET upite). Za promatrani primjer, koristit ćemo HTTP GET za slanje podataka sa forme odgovarajućoj *.asp stranici. Gradnja klasične ASP stranice Klasična ASP stranica je zbrka HTML-a i skriptnog koda na serverskoj strani. Cilj ASP-a je dinamički generirati HTML kod korištenjem skriptnog koda na serverskoj strani i malog skupa klasičnih COM objekata. Primjerice, možete imati VbScript (ili JavaScript) na serverskoj strani koji čita neku tablicu sa podacima korištenjem klasičnog ADO-a i vraća redove kao generičku HTML stranicu. Za ovaj primjer, ASP stranica koristi ugrađeni COM objekt za ASP zahtjev da bi se pročitali dolazni podaci sa forme (dodani na query string) i vratili ih nazad pošiljaocu. Na serverskoj strani koristi se logika predstavljena VBScript jezikom. Da bi to napravili, novu ASP datoteku pod imenom ClassicAspPage.asp treba pohraniti u isti dierktorij kojeg smo vezali za virtualni direktorij. Stranicu formira slijedeći kod: <%@ language="VBScript" %> <html> <head> <title>Serverska stranica</title> </head> <body> <h1 align="center">Ovo mi je poslano</h1> <p align="center"><b>Korisnicko ime:</b> <%=Request.QueryString("txtUserName") %><br /> <b>Password:</b> <%=Request.QueryString("txtPassword") %><br /> </p> </body> </html> U klasičnom ASP-u definiran je i manji broj dodatnih COM objekata koji se mogu koristiti (Sesion, Server, Application) pri stvaranju Web aplikacije. Za testiranje napravljenog, jednostavno preko pretraživača treba učitati defaultnu stranicu, pritisnuti Submit i trebala bi nam se vratiti nova HTML stranica predstavljena na Slici 4. Slika 4. Dinamički generirana HTML stranica Odgovor na POST zahtjeve Trenutno, kreirana default.htm datoteka specificira HTTP GET kao metodu pomoću koje se šalju podaci sa forme do odredišne *.asp datoteke. KOrištenjem ovog pristupa,vrijednosti upisane u različitim odjeljcima grafičkog sučelja dodaju se na kraj query stringa. Važno je uočiti da metoda Request.QueryString() jedino može izvući podatke koji joj se pošalju pomoću GET metode. Želi li se radije poslati podatke korištenjem HTTP POST zahtjeva, mora se koristiti Request.Form kolekcija za čitanje vrijednosti na serveru, primjerice: <body> <h1 align="center">Ovo mi je poslano</h1> <p align="center"><b>Korisnicko ime:</b> <%=Request.Form("txtUserName") %><br /> <b>Password:</b> <%=Request.Form("txtPassword") %><br /> </p> </body> </html> Time je ilustracija osnovne web aplikacije završena. U nastavku, kako bi se steklo uvid u prednosti koje nudi ASP.NET, dan je pregled problema vezanih za korištenje klasičnog ASP-a. Problemi sa klasičnim ASP-om Iako su brojni web siteovi kreirani sa klasičnim ASP-om, ova je tehnologija na zalazu. Možda je i najveći nedostatak klasičnog ASP-a upravo to što ju je prije činilo moćnom platformom: skriptni jezik na serverskoj strani. Skriptni jezici kao što je VBScript i JavaScript su interpreterski tipovi, entiteti bez tipova koji se ne uklapaju u robustne OO programske tehnike. Drugi problem sa klasičnim ASP-om je činjenica da neka *.asp stranica ne generira modularan kod. Zbog toga što je ASP miješavina HTML-a i skripata na istoj stranici, većina ASP web aplikacija predstavlja konfuznu mješavinu dvije vrlo različite programske tehnike. Dokle god je istina da klasični ASP kod dopušta razdvajanje koda kojeg se može naknadno iskoristiti u razdvojenim include datotekama, objektni model koji to podržava, ne podržava i stvarnu podijeljenost zadataka. U idealnom svijetu web logika trebala bi dozvoljavati da prezentacijska logika bude odvojena od poslovne logike (tj. od funkcionalnog koda). Konačna stavka o kojoj treba povesti računa leži u činjenici da klasični ASP zahtijeva puno ponavljajućeg, redundantnog skriptnog koda koji se ponavlja između procesa. Gotovo sve web aplikacije, provjeravaju korisnički unos, ponovno popunjavaju dijelove grafičkog sučelja prije slanja HTTP odgovora, generiraju HTML tablice i slično. Temeljne prednosti ASP.NET-a 1.x Prva verzuja ASP.NET-a ponudila je iznimna rješenja po svim pitanjima po kojima je klasični ASP očitovao slabosti. Sama .NET platforma omogućila je slijedeće tehnike: • ASP.NET omogućava model nazvan iza-koda, koji dozvoljava odvajanje prezentacijske i poslovne logike • ASP.NET 1.x stranice su kompajlirani .NET asembliji, a ne interpretirani skriptni jezici, što osigurava brže izvođenje • Web kontrole dozvoljavaju programerima izgradnju web aplikacija sa grafičkim sučeljem, na način sličan načinu gradnje Windows Form aplikacija • ASP.NET web kontrole automatski održavaju svoje stanje za vrijeme postback-a korištenjem skrivenih formi pod imenom _VIEWSTATE. • ASP.NET web aplikacije su potpuno objektno orijentirane i koriste zajednički sustav tipova (common type system) • ASP.NET aplikacije mogu se lako konfigurirati korištenjem postavki IIS ili korištenjem konfiguracijske datoteke web aplikacije. ASP.NET 1.x bio je korak u pravom smijeru, a ASP.NET 2.0 je još ukrašeniji Glavna poboljšanja u ASP.NET 2.0 ASP.NET 2.0 nudi brojne nove imenske prostore, tipove, utility-je, i tehnologije za cjelokupan web razvoj pod .NET-om. Promotrimo samo od nekih prednosti: • Websiteovi se više ne moraju hostati pod IIS-om za vrijeme testiranja i razvoja • • • • • Isporučuje se sa velikim brojem web kontrola (sigurnosne kontrole, upravljanje novim podacima, nove UI kontrole) koji nadopunjuju postojeći skup kontrola Podržava korištenje master stranica pomoću kojih zajedničko korisničko sučelje možemo vezati za skup povezanih stranica Podržava teme, koje nude deklarativan način za promjenu izgleda i ugođaja čitave web aplikacije. Podržava web dijelove koji se mogu koristiti kako bi korisnici prilagodili izgled i ugođaj web stranice Podržava konfiguriranje utemeljeno na webu i upravljačke utilitije koji održavaju Web.config datoteke. Imenski prostori u ASP.NET–u 2.0 Postoje 34 web orijentirane imenska prostora koji se mogu grupirati u četiri temeljne kategorije: • • • • Temeljna funkcionalnost (tj. tipovi koji dozvoljavaju interakciju sa HTTP zahtjevima i odgovorima, infrastrukturu Web formi, tema i podrške za profiliranje, web dijelovi i slično) Web forme i HTML kontrole Razvoj za mobilni web XML web servisi U tablici su predstavljeni neki od temeljnih imenskih prostora: IMENSKI PROSTOR System.Web System.Web.Caching System.Web.Hosting System.Web.Management System.Web.Profile System.Web.Security System.Web.SessionState System.Web.UI Značenje Definira tipove koji omogućavaju komunikaciju između pretraživača i web servera (zahtjevodgovor mogućnosti, manipulaciju sa kukijima i prijenos datoteka) Definira tipove koji omogućavaju podršku za keširanje za web aplikacije Definira tipove koji dozvoljavaju gradnju prilagođenih poslužitelja za ASP.NET izvršno vrijeme Definira tipove za upravljanje i nadzor zdravlja neke ASP.NET web aplikacije Definira tipove koji se koriste za implementiranje ASP.NET korisničkih profila Definira tipove koji omogućavaju programiranje sigurnosti za vlastiti site Definira tipove koji dozvoljavaju održavanje informacija o stanjima na per-users osnovi (varijable stanja sesije) Definiraju brojne tipove koji dozvoljavaju System.Web.UI.WebControls System.Web.UI.HtmlControls izgradnju GUI-a za vlastitu web aplikaciju ASP.NET-ov model web kodne stranice ASP.NET web stranice mogu se konstruirati korištenjem jednog od dva pristupa. Može se kreirati jedna *.aspx datoteka koja sadrži mješavinu koda serverske strane i HTML-a (kao i klasični ASP). Korištenjem modela stranice sa jednom datotekom, kod na serverskoj strani stavlja se unutar <script> dosega, ali sami kod nije pravi skriptni kod (kao VBScript ili JavaScript). Umjesto toga, naredbe unutar <script> bloka pišu se u nekom od odabranih jezika (C#, VisualBasic.NET, itd.). Grade li se stranice koje imaju vrlo malo koda (a veći je dio HTML), model stranice sa jednom datotekom je zgodnije koristiti jer takav model osigurava i čitav niz drugih prednosti kao što su: • Stranice sadržane u modelu sa jednom datotekom lakše se isporučuju ili šalju drugom razvojnom timu • Nema ovisnosti između datoteka, pa je takve datoteke lakše preimenovati • Lakše je upravljanje sa datotekama u sustavu upravljanja sa izvornim kodom, pošto su sve akcije definirane u jednoj datoteci. Defaultni pristup koji je preuzet sa Visual Studiom 2005 je korištenje tehnike sa kodomiza (code behind), koji dozvoljava odvajanje HTML koda sa prezentacijskom logikom i programskog koda. Takav se model ponaša jako dobro kada stranice sadržavaju znatan dio koda ili kada više ljudi radi na razvoju istog web site-a. Dobre strane tog kodnog modela su slijedeće: • Takve stranice preglednije razdvajaju kod od prezentacije, pa dizajneri mogu raditi na izgledu, a programeri na kodu • Dizajneri nisu izloženi kodu ili drugima koji rade samo sa izgledom stranice • Kod može biti distribuiran duž više *.aspx datoteka. Bez obzira koji se pristup koristi, karakteristike prikaza ostaju iste. Pod ASP.NET 2.0 pristup temeljen na jednoj datoteci ne smatra se manje vrijednim; ovisno o karakteristikama site-a, važno je izvući dobrobiti iz oba pristupa. Rad sa modelom stranice u jednoj datoteci Najprije obratimo pozornost na model u jednoj datoteci. Cilj je napraviti datoteku Default.aspx koja nam nudi pregled video filmova koji se mogu naručiti. Iako se datoteka može napraviti i u Notepad-u, možemo i iskoristiti mogućnosti koje nudi Visual Studio 2005. Dakle, treba odabrati: File->New-> File opciju sa menu-a: Slika 5. Kreiranje nove *.aspx datoteke Stranica koja se kreira u IDE-u može se editirati na dva različita načina: ili preko tzv. «design» pogleda ili u izvornom (tekstualnom) modu. U tom slučaju vide se HTML tagovi i dio koji je izdvojen za pisanje skripti (<script>). U design modu na stranicu ubacite jedan botun, label (standard toolbox) i GridView (DataToolbox). Preko Property dialoga zgodnije je pridjeliti odgovarajuće ID-ove (lbl Info, btnFillData, videoGridView). Forma izgleda: <form id="form1" runat="server"> <div> <asp:Label ID="lblInfo" runat="server" Text="Pritisnite botun za popunjavanje mreze"></asp:Label><br /> <br /> <asp:Button ID="btnFillGrid" runat="server" OnClick="btnFillData_Click" Text="Popuni mrezu" /><br /> <br /> <asp:GridView ID="videoGridView" runat="server"> </asp:GridView> </div> </form> Razriješimo zatim Click događaj (isto tako najlakše je preko Property prozora), pri čemu odgovarajuću metodu treba dodati u dijelu rezerviranom za serverske skripte: <script runat="server"> protected void btnFillData_click(object sender, EventArgs e) { } </script> Još treba implementirati kod na serverskoj strani i to tako da aktiviramo ADO.NET čitača podataka kako bi popunio GridView. Treba dodati naredbu kojom specificiramo importiranje SystemDataSqlClient imenskog prostora. Ta je logika sadržana u slijedećem kodu: protected void btnFillData_Click(object sender, EventArgs e) { SqlConnection sqlConn=new SqlConnection("Data Source=.;Initial Catalog=Video;UID=sa;PWD="); sqlConn.Open(); SqlCommand cmd=new SqlCommand("Select * From Inventory", sqlConn); videoGridView.DataSource=cmd.ExecuteReader(); videoGridView.DataBind(); sqlConn.Close(); } Prije nego detaljnije objasnimo format *.aspx datoteke, pokušajmo je pokrenuti. Otvorimo komandni prompt i upišemo: Webdev.webserver.exe /port:***** /path:”d:\web\....”. Kada se stranica prikaže, u početku vidimo samo botun i poruku, a kada botun pritisnemo, podaci iz baze podataka upišu se u odgovarajuće HTML tagove, kao što se vidi na slici: Sada, obratimo više pozornosti na detalje iz *.aspx datoteke. Naredba <%@ Page %> Prva stvar koju je lako primijetiti je činjenica da se ASP datoteka uvijek otvara sa skupom naredbi. ASP naredbe uvijek se označavaju sa <%@ XXX %> i može se nadopuniti sa različitim atributima kojima definiramo karakteristike jezika. Svaka *.aspx datoteka mora imati barem <%& Page %> naredbu koju koristimo za definiranje jezika kojeg koristimo na stranici (pomoću language atributa). Ta se ista naredba koristi za definiranje imena koda koji prati tu stranicu (kod iza stranice) i koji osigurava podršku pri pojavljivanju stranice i slično. U Tablici je dan pregled nekih atributa koji dolaze uz Page naredbu: Atribut CompilerOptions Značenje Dozvoljava definiranje bilo kojeg flega sa komandne linije (predstavljenog jednim stringom) kojeg prosljeđujemo kompajleru kada se stranica obrađuje. CodePage Specificira ime odgovarajućeg koda koji prati stranicu. EnableTheming Osigurava da kontrole na *.aspx stranici podržavaju ASP.NET teme EnableViewState Označava da li se pogled na stanje održava za vrijeme zahtjeva za stranicom Inherits Definira klase u kodu iza stranice iz koje *.aspx datoteka nešto nasljeđuje, što može biti bilo koja klasa uzvedena iz System.Web.UI.Page MasterPageFile Postavlja se master stranica koja se koristi zajedno sa trenutnom *.aspx stranicom Trace Označava je li omogućeno trace-nje Naredba <% Import %> Koristi se za eksplicitno navođenje svih imenskih prostora koje treba ta stranica. U ovom dijelu specificiramo je li koristimo tipove iz System.Data.SqlClient imenskog prostora. Za svaki imenski prostor koristimo posebnu <%Import%> naredbu. (Ta naredba nije potrebna ukoliko koristimo model sa kodom iza stranice. U tom slučaju za specificiranje vanjskih imenskih prostora koristimo C# ključne riječi). Nameće se pitanje zašto u *.aspx datoteci ne navodimo standardne imenske prostore - iz jednostavnog razloga jer *aspx stranice imaju automatski pristup do ključnih imenskih prostora: • System • System.Collections • System.Collections.Generic • System.Configuration • System.IO • System.Text • System.Text.RegularExpressions • Svi System.Web orijentirani imenski prostori Postoje još neke naredbe koje se mogu navesti iznad Page i Import naredbe. O njima više kasnije. «Script» blok Pod modelom datoteke na jednoj stranici, *.aspx datoteka sadrži skriptnu logiku koja se izvodi na Web serveru. Zbog toga svi skriptni blokovi koji se izvode na serveru moraju imati runat=«server» atribut. Ukoliko to ne postoji, tada se podrazumijeva da se pri izvođenju aktivira klijentska skripta: <script runat="server"> protected void btnFillData_Click(object sender, EventArgs e) { } </script> Potpis ove metode strašno podsjeća na delegate događaja iz windows formi. Podsjetimo li se načela iz Windows formi, tada je jasno da hendler (serviser) događaja mora biti kreiran po uzoru na .NET delegata. I ovdje kreirani delegat koji na serverskoj strani vodi računa o tome je li pritisnut botun, može pozivati samo one metode koje kao prvi parametar imaju varijablu tipa System.Object, a kao drugi parametar koriste varijablu tipa System.EventHandler. ASP.NET dijelovi sučelja Konačno, pozornost moramo obratiti na deklaraciju Button, Label i GridView kontrole Web formi. Poput klasičnog ASP-a i čistog HTML-a, ASP.NET dijelovi sučelja postavljaju se unutar “form” elementa. U ovom slučaju, otvaranje form tag-a popraćeno je runat=”server” atributom. To je značajno jer ovaj tag informira ASP.NET runtime da prije nego što se HTML pošalje u strimu odgovor, postojeći ASP dijelovi sučelja imaju se šansu prikazati: <form id=”form1” runat=server> </form> Sve ASP.NET Web kontrole deklariraju se unutar <asp> i </asp> tagova i isto tako imaju atribut runat=”server”. Unutar forme specificiramo ime Web Form kontrole i proizvoljan broj name/value parova koji nam osiguravaju pravilan prikaz odgovarajućih HTML dijelova. Kod: <%@ Page Language="C#" %> <%@ Import Namespace = "System.Data.SqlClient" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> protected void btnFillData_Click(object sender, EventArgs e) { SqlConnection sqlConn = new SqlConnection("Data Source=.;Initial Catalog=Video;UID=sa;PWD="); sqlConn.Open(); SqlCommand cmd = new SqlCommand("Select * From Inventory", sqlConn); carsGridView.DataSource = cmd.ExecuteReader(); carsGridView.DataBind(); sqlConn.Close(); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Cars Inventory</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="lblInfo" runat="server" Text="Click on the Button to Fill the Grid"> </asp:Label><br /><br /> <asp:GridView ID="videoGridView" runat="server"> </asp:GridView><br /> <asp:Button ID="btnFillData" runat="server" Text="Fill Grid" OnClick="btnFillData_Click" /> </div> </form> </body> </html> Model stranice sa skrivenim kodom (kod iza stranice) Kako bi ilustrirali ovaj drugi model modificirajmo prvi primjer korištenjem Microsoft Visual Studio 2005 Web Site template-a. Aktiviramo File->New->Web Site opciju sa izbornika: Obratite pozornost da je moguće odabrati lokaciju novog Web site-a. Odaberemo li za lokaciju - File System, tada će sve datoteke site-a biti smještene u lokalni direktorij i stranice će biti ponuđene korištenjem webdev.webserver.exe-a. Odaberemo li FTP ili HTTP, tada će site biti hostan unutar virtualnog direktorija o kojem vodi računa IIS. Za ovaj primjer, jednostavnosti radi, odaberimo File System. Opet, preko dizajnera dodajmo botun, labelu i gridview, te preko Property dijaloga dotjerajmo stranicu na željeni oblik. Pritisnemo li ”Source” botun na dnu prozora editora vidjet ćemo na početku datoteke slijedeću liniju: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> Od svih atributa najvažniji je CodeFile koji definira ime datoteke koja leži u pozadini *.aspx datoteke. Prema defaultnoj vrijednosti, ta datoteka ima isto ime kao i *.aspx datoteka, samo što se na kraju dodaje nastavak -.cs. Do nje se može doći i otvaranjem čvora *.aspx u Solution Explorer-u (na slici). Pogledamo li sadržaj same *.aspx.cs datoteke, tada nakon brojnih using naredbi koje označavaju web orijentirane imenske prostore, kod označava određene klase razvijene iz System. Web.UI.Page. Primijetite da je ime tih klasa isto kao i ime inherits atributa unutar <% Page %> naredbe. using using using using using using using using using System; System.Data; System.Configuration; System.Web; System.Web.Security; System.Web.UI; System.Web.UI.WebControls; System.Web.UI.WebControls.WebParts; System.Web.UI.HtmlControls; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } } Povedimo računa o događaju kojeg izaziva klik na miša, u klasu dodajmo funkciju: protected void btnFillGrid_Click(object sender, EventArgs e) { } Da bi se očitovao efekt funkcije, unutar tijela funkcije treba prepisati kod koji je prije bio sastavni dio iste funkcije, ali u istoj, *.aspx datoteci: SqlConnection sqlConn = new SqlConnection("Data Source=.;Initial Catalog=Video;UID=sa;PWD="); sqlConn.Open(); SqlCommand cmd = new SqlCommand("Select * From Inventory", sqlConn); GridView1.DataSource = cmd.ExecuteReader(); GridView1.DataBind(); sqlConn.Close(); Pri otvaranju WebSite-a i odabirom FileSystem-a za lokaciju, automatski se starta webdev.webserver.exe kada aplikaciju pokrenemo (ako se prethodno starta IIS, to se naravno neće dogoditi). U oba slučaja defaultni pretraživač prikazat će sadržaj stranice i akciju koja slijedi nakon pritiska na botun. Debugiranje i praćenje prikaza ASP.NET stranica Jednako kao i pri gradnji bilo kojeg drugog projekta pod Visual Studiom i sa ASP.NETovim projektima mogu se koristiti iste tehnike za debugiranje. Mogu se označiti karakteristične točke (brakepoints) na stranici sa kodom, kao i u skriptnim blokovima *.aspx datoteke, pokrenuti debug-iranje (sa F5) i pomicati se korak po korak kroz aplikaciju. Ipak, ASP.NET aplikacija mora u tom slučaju imati pravilno definirane ovlasti definirane u Web.config datoteci. Ukoliko projekt nema tu datoteku, Visual Studio će je dodati, a u njoj je od značaja jedan jedini element: <compilation>. <?xml version="1.0"?> <!-Note: As an alternative to hand editing this file you can use the web admin tool to configure settings for your application. Use the Website->Asp.Net Configuration option in Visual Studio. A full list of settings and comments can be found in machine.config.comments usually located in \Windows\Microsoft.Net\Framework\v2.x\Config --> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <appSettings/> <connectionStrings/> <system.web> <!-Set compilation debug="true" to insert debugging symbols into the compiled page. Because this affects performance, set this value to true only during development. --> <compilation debug="true"/> <!-The <authentication> section enables configuration of the security authentication mode used by ASP.NET to identify an incoming user. --> <authentication mode="Windows"/> <!-The <customErrors> section enables configuration of what to do if/when an unhandled error occurs during the execution of a request. Specifically, it enables developers to configure html error pages to be displayed in place of a error stack trace. <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"> <error statusCode="403" redirect="NoAccess.htm"/> <error statusCode="404" redirect="FileNotFound.htm"/> </customErrors> --> </system.web> </configuration> Isto tako, može se osigurati praćenje prikaza stranice dodavanjem atributa Trace=”true” unutar <% @Page %> naredbe: <%@ Page Language="C#" AutoEventWireup="false" CodeFile="Default.aspx.cs" Inherits="_Default" %> Jednom kada to napravimo, HTML koji se prikazuje na stranici sada je nadopunjen sa brojnim detaljima koji se odnose na prethodna HTTP zahtjev/odgovor događanja. Da bi ispisali poruke praćenja, koristimo Trace svojstvo tipa System.Web.UI.Page-a. Svaki put kada želimo zabilježiti neku poruku (iz skriptnog bloka ili C# koda), jednostavno pozovemo Write() metodu. protected void btnFillGrid_Click(object sender, EventArgs e) { // Emit a custom trace. Trace.Write("My Category", "Filling the grid!"); SqlConnection sqlConn = new SqlConnection("Data Source=.;Initial Catalog=Cars;UID=sa;PWD="); sqlConn.Open(); SqlCommand cmd = new SqlCommand("Select * From Inventory", sqlConn); carsGridView.DataSource = cmd.ExecuteReader(); carsGridView.DataBind(); sqlConn.Close(); } Pokrenemo li projekt još jednom i pošaljemo zahtjev prema serveru, pronaći ćemo, osim uobičajenih kategorija i uobičajenih poruka i vlastitu, ubačenu sa Trace.Write naredbom. Slika. Ispis vlastite poruke tijekom Trace-a Struktura direktorija ASP.NET website-a Za razliku od ASP.NET 1.x, u novoj verziji ne nailazimo u direktoriju na neke uobičajene datoteke kao što su Web.config, Global.asax, AssemblyInfo.cs i sl. Umjesto toga imamo jedan direktorij App_Data, a nedostaje čak i uobičajeni direktorij References. Standardni direktoriji kao što su Web.config i Global.asax, podržani su i pod ASP.NETom 2.0 samo što ih treba eksplicitno uključiti u projekt korištenjem opcije sa menu-a: WebSite->AddNewItem. Isto tako možemo dodati i reference na bilo koji vanjski .NET asembly korištenjem opcije sa menu-a: WebSite->AddReferences (krajnji rezultat je malo drugačiji od onog koji je do sada izazivala ova opcija sa menu-a). Još je jedna bitna razlika pod Visual Studiom 2005 što se mogu dodati bilo koji broj posebno nazvanih poddirektorija, od kojih svaki ima posebno značenje za ASP.NET izvršno vrijeme. U tablici su redom predstavljeni svi ti posebni poddirektoriji: Poddirektorij App_Browsers Stvarno značenje Direktorij sa datotekama koje definira pretraživač koje se koriste za identifikaciju pojedinih pretraživača i da bi se odredile njihove mogućnosti. App_Code Direktorij za izvorni kod za komponente ili klase koje želimo kompilirati kao dijelove vlastite aplikacije. ASP.NET kompilira kod u ovaj direktorij kada se zatraže stranice. Kod u direktoriju App_Code automatsli je dostupan vlastitoj aplikaciji. App_Data Direktorij za pohranjivanje Access*.mdb datoteka, SQLExpress.mdb, XML datoteka i drugih datoteka sa podacima. App_GlobalResources Direktorij za *.resx datoteke koje se programski dohvaćaju iz aplikacijskog koda. App_LocalResources Direktorij za *.resx datoteke koje su vezane za specifičnu App_Themes App_WebReferences Bin stranicu. Direktorij koji sadrži kolekciju datoteka koje definiraju način na koji se pojavljuju ASP.NET web stranice i kontrole. Direktorij za proxy klase, scheme, ili druge datoteke koje su povezane sa web servisom u aplikaciji. Direktorij za kompilirane privatne asemblije (*.dll datoteke). Asembliji u bin datoteci automatski su referencirani sa vlastitom aplikacijom. Ukoliko postoji potreba za dodavanjem bilo kojeg od ovih poddirektorija u aplikaciji, može se to eksplicitno napraviti korištenjem opcije sa izbornika: WebSite->AddFolder. Ipak, u brojnim slučajevima IDE to radi automatski onda kada tijekom kreiranja aplikacije umećemo odgovarajuće datoteke na vlastiti site (primjerice dodavanjem nove C# datoteke automatski će se dodati direktorij App_Code ako do tada nije postojao). Uloga Bin datoteke Kao što je već opisano, ASP.NET web stranice na kraju se kompiliraju u .NET asemblije. Obzirom na to, ne bi trebalo biti iznenađenje da kreirani website-ovi mogu referencirati bilo koje privatne ili dostupne asemblije. Pod ASP.NET-om 2.0, način na koji site traži asemblije bilježi se na sasvim drugačiji način od onog u ASP.NET-u 1.x. Razlog za ovakav odmak leži u načinu na koji Visual Studio 2005 tretira web site-ove – na tzv. projectless način. Iako template za WebSite generira *.sln datoteku koja loada *.aspx u IDE, više ne postoji i odgovarajući *.csproj datoteka. ASP.NET 1.x WebApplication projekti bilježe sve vanjske asemblije unutar *.csproj. Ta činjenica nameće pitanje gdje se kriju vanjski asembliji zabilježeni unutar ASP.NET 2.0? Kada referenciramo privatni asembli, Visual Studio 2005 automatski će kreirati Bin direktorij u strukturi direktorija kako bi pohranio lokalnu kopiju binary dadoteke. Kada temeljni kod zatraži tip unutar ove biblioteke koda, automatski se učita na zahtjev. Pomoću jednostavnog testa, ako aktiviramo WebSite->AddReference opciju sa Menu-a i odaberemo bilo koju od prethodnih *.dll-ova, uvjerit ćemo se da se Bin direktorij očituje unutar Solution Explorera (vidi sliku). Slika. Pojavljivanje Bin direktorija u projektu Ako se referencira shared asembli, Visual Studio 2005 automatski će umetnuti Web.config datoteku u postojeći web solution (ako već nije unutra) i zabilježiti vanjsku referencu unutar <assemblies> elementa. Primjerice, aktiviramo li ponovo WebSite>AddReference opciju sa izbornika i ovaj put odaberemo neki shared assembli (primjerice System.Drawing.dll), možemo se uvjeriti da će Web.config biti ažuriran kao: <?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <appSettings/> <connectionStrings/> <system.web> <compilation debug="false"> <assemblies> <add assembly="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/> </assemblies> </compilation> <authentication mode="Windows"/> </system.web> </configuration> Kao što se može primijetiti, svaki asembli je opisan korištenjem istih informacija koje nam trebaju za dinamičko učitavanje preko Assenmbly.Load() metode. Uloga App_Code direktorija App_Code direktorij koristi se za pohranjivanje izvornog koda koji nije direktno vezan za specifičnu web stranicu (kao što je datoteka sa «kodom iza») ali se mora kompilirati kako bi se koristila sa websiteom. Kod unutar App_Code direktorija biti će kompiliran «onfly» prema potrebi. Nakon toga, assembli će biti dohvatljiv bilo kojem drugom kodu sa website-a. U tom smislu, App_Code direktorij je nalik Bin direktoriju, osim što se u njemu može pohraniti izvorni kod, a ne samo onaj kompilirani. Glavna prednost ovakvog pristupa je mogućnost definiranja prilagođenih tipova za web aplikaciju, bez da te programe zasebno kompiliramo. App_Code direktorij može sadržavati izvorne kodove pisane različitim programskim jezicima. Tijekom izvođenja te dijelove prihvaća odgovarajući kompajler kako bi generirao odgovarajući asembly. Ukoliko radije razdvajate kod mogu se definirati i odgovarajući poddirektoriji koji čuvaju odgovarajuće izvorne kodove (*.cs, *.vb, itd.). Primjerice, pretpostavimo da smo dodali direktorij App_Code u korijenski direktorij web site-a i da ovaj sadrži dva poddirektorija (MojVbKod i Moj CSharpKod) koji sadrže programe napisane specificnim jezikom. Tada možemo i naznačiti sve što treba u web.config datoteci korištenjem <codeSubDirectories> elementa: <?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <appSettings/> <connectionStrings/> <system.web> <compilation debug="false"> <assemblies> <add assembly="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/> </assemblies> <codeSubDirectories> <add directoryName="MyCSharpCode" /> <add directoryName="MyVbNetCode" /> </codeSubDirectories> </compilation> <authentication mode="Windows"/> </system.web> </configuration> App_Code direktorij sadržavat će također i datoteke koje nisu pisane u programskom jeziku, ali su korisne zbog raznih drugih stvari (primjerice *.xsd, *.wsdl, itd). ASP.NET 2.0 ciklus kompiliranja stranice Neovisno o korištenom modelu kodne stranice (model sa jednom stranicom ili model sa kodom iza stranice), datoteke *.aspx i sve relevantne datoteke sa kodom iz stranice kompiliraju se u odgovarajući .NET asembli. Taj asembli se zatim hosta sa ASP.NET radnim procesom (aspnet_wp.exe) u granicama vlastite aplikacijske domene. Način na koji se websiteov assembly kompilira pod ASP.NET-om 2.0 je sasvim različit. Kompilacijski ciklus za stranice sa jednom datotekom Koristi li se model stranice sa jednom datotekom, HTML oznaka, <script> blok, i definicije web kontrola dinamički se kompiliraju u klasu koja se izvodi iz tipa System.Web.UI.Page. Ime ove klase temelji se na imenu *.aspx datoteke i sadrži an_aspx nastavak (primjerice stranica naziva Mojastranica postat će klasa MojaStranica_aspx). Prema ovom modelu , web kontrole deklarirane u *.aspx datoteci koriste se za izgradnju dodatne parcijalne klase koja definira svaku UI varijablu člana i konfiguracijsku logiku koja se vjerojatno nalazi u metodi InitializeComponent() ASP.NET 1.x-a. Ova parcijalna klasa kombinira se tijekom kompiliranja sa datotekom koda, pa to rezultira temeljnom klasom generiranog _aspx tipa (u kompilacijskom modelu sa jednom stranicom, generirana _aspx datoteka izvodi se direktno iz System.Web.UI.Page). U bilo kojem slučaju, jednom kada je asembli kreiran na inicijalni HTTP zahtjev, koristit će ga se i za sve zahtjeve koji slijede i zbog toga se ne mora rekompilirati. Upravo zbog toga, prvi HTTP zahtjev traje najdulje, a naredni zahtjevi za stranicom su iznimno efikasni. Pod ASP.NET 2.0 moguće je prekompilirati sve stranice (ili podskup stranica) korištenjem alata sa komandne linije nazvanim aspnet_compiler.exe. Detalji su navedeni u .NET Framework SDK dokumentaciji. Lanac nasljeđivanja za tip stranice Konačno generirana klasa koja predstavlja *.aspx datoteku konačno se izvodi iz System.Web.UI.Page. Kao i bilo koja temeljna klasa, ovaj tip omogućava polimorfni interfejs za sve izvedene tipove. Ipak, tip Page nije jedini član u hijerarhiji nasljeđivanja. Ako lociramo tip Page (u System.Web.dll asembliju) korištenjem Object Browsera Visual Studia 2005, pronaći ćemo da klasa Page «je» TemplateControl, koji «je» Control, a ovaj «je» Object (vidi sliku). Za pretpostaviti je da svaka od ovih temeljnih klasa donosi određenu funkcionalnost svakoj *.aspx datoteci. U većini projekata koriste se članovi koji su definirani unutar Page i Control roditeljskih klasa. Grade li se uobičajene Web Form kontrole ili se djeluje na način prikazivanja koristit će se uglavnom System.Web.UI.TemplateControl. U nastavku slijedi uloga Page tipa. System.Web.UI.Page tip Prva roditeljska klasa koju vrijedi upoznati je sama Page klasa. U tablici su navedena brojna svojstva koja omogućavaju interakciju sa različitim web primitivama kao što su aplikacijske i varijable sesije, HTTP zahtjev/odgovor, podržavanje tema itd. Tablica opisuje neka od bitnijih svojstava. Svojstvo Aplikacija Cache ClientTarget IsPostBack MasterPageFile Request Response Server Session Theme Trace Značenje Dozvoljava interakciju sa varijablama aplikacije za tekući website Dozvoljava interakciju sa cache objektom za tekući website Dozvoljava specificiranje kako bi se stranica trebala prikazati u pretraživaču koji je traži. Dobiva se vrijednost koja indicira je li stranica učitana kao odgovor na klijentov postback ili se učitava zato što je prvi put zatražena Kreira se master stranica z atraženu stranicu Omogućava se pristup trenutnom HTTP zahtjevu Dozvoljava se interakcija sa izlazećim HTTP odgovorom Omogućava pristup HttpServerUtility objektu, koji sadrži različite pomagačke funkcije na serverskoj strani Dozvoljava interakciju sa podacima sesije za trenutnog pozivača Dohvaća ili postavlja naslov teme koja se koristi za tekuću stranicu Omogućava pristup TraceContext objektu, koji dozvoljava ostavljanje uobičajenih poruka tijekom debugiranja Interakcija sa dolazećim HTTP zahtjevima Osnovni tijek web sesije počinje klijentovim logiranjem na site, popunjavanjem korisničkih informacija, pritiskom na Submit botun kako bi se poslala nazad HTML forma sa podacima određenoj web stranici za obradu. U većini slučajeva, tag koji otvara form izraz specificira neki akcijski atribut i atribut metode koja indicira datoteku na serverskoj strani kojoj se šalju podaci iz različitih HTML odjeljaka, kao i metodu za slanje tih podataka (GET ili POST): <form name="defaultPage" id="defaultPage" action="http://localhost/Cars/ClassicAspPage.asp" method = "GET"> ... </form> Za razliku od klasičnog ASP-a, ASP.NET ne podržava objekt Request. S druge strane, sve ASP.NET stranice nasljeđuju System.Web.UI.Page.Request svojstvo, koje omogućava pristup instanci klase tipa HttpRequest. U donjoj tablici navedeni su neki ključni članovi koji oponašaju članove iz ostavštine klasičnog ASP Request objekta. Member Meaning in Life ApplicationPath server Browser Cookies FilePath Form Headers HttpMethod IsSecureConnection QueryString RawUrl RequestType ServerVariables UserHostAddress UserHostName Gets the ASP.NET application’s virtual application root path on the Provides information about the capabilities of the client browser Gets a collection of cookies sent by the client browser Indicates the virtual path of the current request Gets a collection of Form variables Gets a collection of HTTP headers Indicates the HTTP data transfer method used by the client (GET, POST) Indicates whether the HTTP connection is secure (i.e., HTTPS) Gets the collection of HTTP query string variables Gets the current request’s raw URL Indicates the HTTP data transfer method used by the client (GET, POST) Gets a collection of web server variables Gets the IP host address of the remote client Gets the DNS name of the remote client Kao dodatak ovim svojstvima, tip HttpRequest ima brojne korisne metode, uključujući slijedeće: • • • MapPath(): Mapira se virtualna staza navedana u URL-u zahtjeva u fizičku stazu na serveru SaveAs(): Pohranjuju se detalji tekućeg HTTP zahtjeva u datoteku na web serveru (koji se dokazao korisnim za debugiranje) ValidateInput(): Ako je značajka za validaciju omogućena preko Validate atributa page naredbe, ova se metoda može pozvati kako bi čekirala sve korisničke unose (uključujući i kukije) sa ciljem spriječavanja potencijalno opasnih ulaznih podataka Dobivanje statistike pretraživača Prvi interesantan aspekt HttpRequest tipa je svojstvo Browser, koje omogućava pristup do HttpBrowserCapabilities objekta. Zauzvrat, ta klasa očituje brojne članove koji dozvoljavaju da se programski ispituje statistika pretraživača koji šalje dolazeće Http zahtjeve. Kreirajmo novi Website nazvan FunWithPageMembers. Prvi zadatak je izgraditi takvo korisničko sučelje koje dozvoljava korisniku klik na botun web kontrole kako bi video različitu statistiku o pretraživaču koji pristupa siteu. Ta će se statistika generirati dinamički I pridružiti nekoj labeli (primjerice lblOutput). Funkcija očitovanja na događaj ima oblik (Button Click event handler): protected void btnGetBrowserStats_Click(object sender, System.EventArgs e) { string theInfo = ""; theInfo += String.Format("<li>Is the client AOL? {0}", Request.Browser.AOL); theInfo += String.Format("<li>Does the client support ActiveX? {0}", Request.Browser.ActiveXControls); theInfo += String.Format("<li>Is the client a Beta? {0}", Request.Browser.Beta); theInfo += String.Format("<li>Dose the client support Java Applets? {0}", Request.Browser.JavaApplets); theInfo += String.Format("<li>Does the client support Cookies? {0}", Request.Browser.Cookies); theInfo += String.Format("<li>Does the client support VBScript? {0}", Request.Browser.VBScript); lblOutput.Text = theInfo; } Ovdje testiramo brojne mogućnosti pretraživača. Primjerice, korisno se uvjeriti da li pretraživač podržava ActiveX kontrole, Java aplete i klijentske VB skripte. Ako pristupni pretraživač ne podržava određenu web tehnologiju, *.aspx stranica može imati mogućnost za programsko prilagođavanje karakteristikama pretraživača. Pristup podacima sa dolazne forme Drugi aspekt HttpResponse tipa su svojstva Form i QueryString. Ova dva svojstva dozvoljavaju ispitivanje podataka sa dolazne forme korištenjem ime/vrijednost parova, i ove funkcioniraju identično kao i klasični ASP. To znači ako je forma poslana sa GET, onda se podaci čitaju sa QueryString svojstvom, a ako su podaci poslani sa POST-om onda se dobivaju sa Form svojstvom. Iako svojstva HttpRequest.QueryString i HttpRequest.Form stoje na raspolagannju za dohvaćanje podataka sa forme, ova staromodna tehnika se ne mora koristiti. Na raspolaganju je ASP.NET-ove web kontrole na serverskoj strani, pa UI HTML elemente možemo tretirati kao stvarne objekte. Dakle, uputno je do vrijednosti unutar tekst box-a umjesta sa: protected void btnGetFormData_Click(object sender, EventArgs e) { // Get value for a widget with ID txtFirstName. string firstName = Request.Form["txtFirstName"]; } doći na slijedeći način: protected void btnGetFormData_Click(object sender, EventArgs e) { // Get value for a widget with ID txtFirstName. string firstName = txtFirstName.Text; } Ne samo das a ovakvimpristupom slijedimo dobre OO principe, nego ni ne moramo brinuti na koji su način podaci poslani (GET ili POST) prije nego što su se pojavile vrijednosti. Štoviše, kada direktno koristimo dijelove forme, koristimo sigurnije tipove, jer će sintaksna pogreška biti otkrivena još tijekom kompiliranja. Iako se potreba za direktnim korištenjem Querystring i Form svojstva na ovaj način bitno smanjuje, još uvijek postoji mogućnost da ih, ukoliko nam zatrebaju, opet koristimo. Svojstvo IsPostBack I ovo je svojstvo vrlo važan član HttpRequest klase. Podsjetimo se da je postbek (postback) odnosi na postupak vraćanja neke web stranice za koju session sa serverom još traje. Obzirom na navedeno, IsPostBack svojstvo vraća istinu ako je trenutni Http zahtjev poslan od strane trenutno logiranog korisnika i bit će lažan ukoliko je riječ o prvoj interakciji korisnika sa stranicom. Tipično, potreba da se odredi da li je tekući HTTP zahtjev stvarno postback korisna je kada određeni dio koda želimo korisniku prenijeti samo prvi put kada se uspostavlja veza sa stranicom. Tipičan primjer je kada želimo napuniti neki ADO.NET DataSet kada korisnik prvi put pristupa *.aspx datoteci i kešira objekt za kasniju upotrebu. Kada se pozivatelj vrati na stranicu, možemo izbjeći nepotreban pristup bazi (osim ako neke stranice eksplicitno ne traže da se DataSet uvijek ažurira nakon svakog zahtjeva, ali to je sasvim drugi problem): protected void Page_Load(object sender, EventArgs e) { // Only fill DataSet the very first time // the user comes to this page. if(!IsPostBack) { // Populate DataSet and cache it! } // Use cached DataSet. } Interakcija sa poslanim HTTP odgovorom Sada kada je jasnije kako Page tip dozvoljava interakciju sa dolaznim HTTP zahtjevom, slijedeći korak je naučiti kako ostvariti interakciju sa odlazećim HTTP odgovorom. U ASP.NET-u Response svojstvo klase Page omogućava pristup instanci HttpResponse tipa. Ovaj tip definira brojna svojstva koja dozvoljavaju da se formatira HTTP odgovoe koji je poslan nazad klijentovom pretraživaču. U donjoj tablici navedena su klučna svojstva: Svojstvo Cache ContentEncoding ContentType Cookies IsClientConnected Output Značenje Vraća semantiku keširanja web stranice (primjerice vrijeme isteka, tajnost, promjenjive klauzule) Dohvaća ili postavlja HTTP skup karaktera u izlazni stream Dohvaća ili postavlja HTTP MIME tip u izlazni stream Dohvaća HttpCookie kolekciju koja se šalje sa tekućim zahtjevom Dohvaća vrijednost koja indicira je li klijent još uvijek spojen za server OutputStream StatusCode StatusDescription SuppressContent Osigurava uobičajeni izlaz poslanom HTTP tijelu sadržaja Osigurava binarni izlaz poslanom HTTP tijelu sadržaja Dohvaća ili postavlja HTTP statusni kod izlaza koji se vraća klijentu Dohvaća ili postavlja vrijednost koja indicira da HTTP sadržaj neće biti poslan nazad klijentu Isto tako, u donjoj je tablici navedena lista metoda koju podržava HttpResponse tip koje su opisane u tablici: Metode Cache ContentEncoding ContentType Cookies IsClientConnected Output OutputStream StatusCode StatusDescription SuppressContent Značenje Returns the caching semantics of the web page (e.g., expiration time, privacy, vary clauses) Gets or sets the HTTP character set of the output stream Gets or sets the HTTP MIME type of the output stream Gets the HttpCookie collection sent by the current request Gets a value indicating whether the client is still connected to the server Enables custom output to the outgoing HTTP content body Enables binary output to the outgoing HTTP content body Gets or sets the HTTP status code of output returned to the client Gets or sets the HTTP status string of output returned to the client Gets or sets a value indicating that HTTP content will not be sent to the client Predstavljanje HTML sadržaja Možda je jedan od najpoznatijih aspekata HttpResponse tipa mogućnost pisanja sadržaja direktno u HTTP izlazni stream. HttpResponse.Write() metoda dozvoljava pristup bilo kojem HTML tagu i/ili literalu. Metoda HttpResponse.WriteFile() ovu funkcionalnost diže na jedan veći nivo, na način da možemo specificirati ime fizičke datoteke na web serveru čiji sadržaj treba biti prikazan u izlaznom streamu (korisno kada želimo brzo dobiti sadržaj tekućeg *.aspx datoteke). Za ilustraciju, pretpostavimo da smo dodali još jedan botun u postojeću *.aspx datoteku kojim implementiramo event handler Click događaja na strani servera: protected void btnHttpResponse_Click(object sender, EventArgs e) { Response.Write("<b>My name is:</b><br>"); Response.Write(this.ToString()); CHAPTER 23 ■ ASP.NET 2.0 WEB PAGES AND WEB CONTROLS 861 Response.Write("<br><br><b>Here was your last request:</b><br>"); Response.WriteFile("MyHTMLPage.htm"); } Uloga ove pomoćne funkcije (za koju možemo pretpostaviti da je poziva neki event handler na strani servera) je jednostavna. Jedino o čemu treba voditi računa je činjenica da metoda HttpResponse.WriteFile() može predstaviti sadržaj *.htm datoteke u korijenskom direktoriju na serverskoj strain. Takav način, iako nam stoji na raspolaganju, nije uobičajen za ASP.NET. Glavni razlog je poboljšanje web kontrola na serverskoj strain. Stoga, želimo li prikazati blok tekstualnih podataka preko pretraživača, zadatak se svodi na pridruživanje stringa svojstvu Text određenog labela. Redirekcija korisnika HttpResponse nudi i mogućnost redirekcije korisnika na novi URL: protected void btnSomeTraining_Click(object sender, EventArgs e) { Response.Redirect("http://www.IntertechTraining.com"); } Ako je ovo očitovanje na događaj (event handler) pozvano preko postbeka sa klijentske strane, korisnik će biti automatski prebačen na drugi URL. Napomena: Naredba HttpResponse.Redirect() metoda uključuje kratkotrajni povratak u klijentski pretraživač. Želimo li jednostavno prebaciti kontrolu na neku *.aspx datoteku iz istog virtualnog direktorija, metoda HttpServerUtility.Transfer() će biti efikasnija. Slijedeće o čemu treba voditi računa je trajanje I karakteristični trenuci Page izvedenog objekta. Životni ciklus ASP.NET Web stranice Svaka ASP.NET web stranica ima nepromijenjeni životni ciklus. Kada ASP.NET izvršno vrijeme primi dolazni zahtjev za određenom *.aspx datotekom, odgovarajući System.Web.UI.Page izvedeni tip alocira se u memoriju korištenjem podrazumijevanog konstruktora za taj tip. Nakon toga okruženje automatski pokreće niz događaja. Prema temeljnim postavnim vrijednostima (default) generirani kod iza stranice Visual Studia 2005 definira odgovarajuće očitovanje na događaj (event handler) za događaj Load koji se vezuje uz stranicu: public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } } Osim Load događaja, određena stranica je u mogućnosti presresti bilo koji od kljčnih događaja navedenih u donjoj tablici koji su navedeni onim redoslijedom kojim se o događajima void računa. Svaki od tih događaja Page tipa pokreće se zajedno sa System.EventHandler delegatom. Tablica: Događaj PreInit Značenje Framework koristi ovaj događaj za alociranje bilo koje web kontrole, primijenjivanje tema I postavljanje korisničkog profila. Ovaj se događaj može presresti kako bi promijenili postojeće procese. Init Framework koristi ovaj događaj zbog postavljanja svojstava web kontrola na njihove prijašnje vrijednosti preko postbeka ili podataka za prikaz stanja (view state). Load Kada se pokrene ovaj događaj, stranica i njene kontrole se u potpunosti inicijaliziraju, a njihove prethodne vrijednosti se obnove. U ovom je trenutku, sigurna je interakcija sa svakim dijelom web stranice. “Događaj koji Događaj ovakvog imena ne postoji. Ovaj se “događaj” odnosi na sve trigerira postbek” što uvjetuje postbek na web server (kao primjerice pritisak na botun) Unload Stranica i njene kontrole dovrše proces prikazivanja, a page objekt se gasi. U ovom trenutku interakcija s aposlanim Http odgovorom rezultira sa greškom tijekom run time-a. Ono što se smije hvatanjem ovog događaja je izvesti čišćenje na nivou stranice (zatvaranje datoteka ili konekcija sa bazama podataka, izvesti bilo koju akciju logiranja, otpustiti objekte, i sl.) Uloga AutoEventWireUp atributa Kada se želimo očitovati na događaj, moramo ažurirati <script> blok ili kod iza datoteke sa odgovarajućim kodom očitovanja (event handler). Za razliku od onog što smo trebali pod ASP.NET 1.x, ovdje se ne treba logika događaja implementirati ručno. Sve što je potrebno je definirati metodu korištenjem uzorka: protected Page_nameOfTheEvent(object sender, EventArgs e) { } Primjerice, Unload događaj može se servisirati sa ovim događajem pisanjem slijedećeg koda: public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Page_Unload(object sender, EventArgs e) { } } Razlog zbog kojeg se ova metoda čudom pozove nakon što se stranica oslobodi (usprkos činjenici da nije primijenjena očekivana C# sintaksa) leži u AutoEventWireUp aktivnom (true) atributu u standardnoj <%Page%> naredbi *.aspx datoteke. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> Kao što samo ime sugerira, ovaj atribut (kada je aktivan) generirat će potrbnu koordinaciju sa događajima unutar autogenerirane parcijalne klase koja je opisana u prethodnim dijelu. Stavimo li ovaj atribut kao neistinit, okruženje neće pozvati niti Load niti Unload servisere događaja (event handler). U ovo se možemo uvjeriti postavljanjem prekidnih točaka u Page_Load() I Page_Unload() serviserima događaja. Ukoliko ipak želite koristiti standardnu C# sintaksu kako bi uskočili u tijek Load I Unload događaja, koristimo slijedeći kod: public partial class _Default : System.Web.UI.Page { public _Default() { // Explicitly hook into the Load and Unload events. this.Load +=new EventHandler(Page_Load); this.Unload += new EventHandler(Page_Unload); } protected void Page_Load(object sender, EventArgs e) { Response.Write("Load event fired!"); } protected void Page_Unload(object sender, EventArgs e) { // No longer possible to emit data to the HTTP // response at this point, so we will write to a local file. System.IO.File.WriteAllText(@"C:\MyLog.txt", "Page unloading!"); } protected void btnPostback_Click(object sender, EventArgs e) { // Nothing happens here; this is just to ensure a // postback to the page. } } U ovom slučaju, ovi će događaji biti servisirani u stranici bez obzira na vrijednost koja se dodjeljuje WireUp atributu. I na kraju, treba zapamtiti da jednom kada je Unload događaj pokrenut više ne postoji interakcija sa odlazećim HTTP odgovorom (primjerice pokuša li se pozvati član HttpResponse objekta dobit će se izuzetak tijekom izvođenja). Obzirom na to serviser Unload događaja jednostavno prikazuje liniju teksta do datoteke koja se nalazi na logičkom C disku. Događaj greške (the error event) Tijekom životnog ciklusa stranice može se pojaviti još i Error doogađaj, koji isto djeluje u dogovoru sa System.EventHandler delegatom. Ovaj događaj bit će pokrenut ako neka metoda na objektu izvedenom iz Page tipa generira iznimku koju se ne servisira eksplicitno. Pretpostavimo da je servisirano očitovanje na Click događaj sa za odgovarajući botun na stranici I unutar servisa (koji je nazvan btnGetFile_Click) pokušavamo ispisati sadržaj lokalne datoteke u Http odgovor. Isto tako pretpostavimo da nismo provjeravali je li datoteka uopće prisutna preko standardnih načina za obradu izuzetaka. Ukoliko naiđemo na Page grešku, postoji jedan jedini način na koji možemo izići na kraj s problemom prije nego što krajnji korisnik naiđe na neugodnu grešku. Promotrimo slijedeći kod: public partial class _Default : System.Web.UI.Page { public _Default() { ... // Rig up the Error event. this.Error += new EventHandler(_Default_Error); } void _Default_Error(object sender, EventArgs e) { // Gut the current response, issue an error, // and tell the runtime the error has been processed. Response.Clear(); Response.Write("I am sorry...I can't find a required file."); Server.ClearError(); } protected void btnGetFile_Click(object sender, EventArgs e) { // Try to open a nonexistent file. // This will fire the Error event for this page. System.IO.File.ReadAllText(@"C:\IDontExist.txt"); } ... } Primijetite da serviser (event handler) greške počinje čišćenjem bilo kakvog sadržaja unutar HTTP odgovora i emitira opću poruku o grešci. Ukoliko želimo dobiti pristup konkretnom System.Exception objektu, to se može napraviti pomoću HttpServerUtility.GetLastError() metode. Ovo je poterbno napraviti jer se time izvršno vrijeme informira da se odgovarajući problem rješava na ruke i da daljnje procesiranje zbog toga nije potrebno. Zaboravi li se ovo napraviti, krajnjem će korisniku biti predstavljena stranica pogreške. Na slici je prikazat rezultat ove logike: U nastavku detaljnije su opisane ASP.NET Web kontrole. Priroda Web kontrola Možda je glavna dobrobit ASP.NET-a mogućnost sastavljanja korisničkog sučelja stranice korištenjem tipova koji su definirani u System.Web.UI.WebControls imenskom prostoru. Ove kontrole (koje dolaze pod imenom serverske kontrole, web kontrole ili kontrole web formi) izuzetno su korisne jer automatski generiraju potreban HTML za odgovarajući pretraživač i eksponiraju skup događaja koji se mogu obraditi na serveru. Štoviše, kako svaka ASP.NET kontrola ima odgovarajuću klasu u System.Web.UI.WebControls imenskom prostoru, može se sa njom manipulirati u OO stilu it *.aspx datoteke (unutar <script> bloka) isto kao i unutar koda koji je definiran u odgovarajućoj klasi u modelu sa datotekom “iza stranice”. Kada konfiguriramo svojstva preko Visual Studia, sve zabilježeno sprema se u otvorenoj deklaraciji dane komponente *.aspx datoteke kao niz ime/vrijednost parova. Stoga, dodamo li novi TextBox u designer modu *.aspx datoteke i promijenimo neka svojstva (Border Width, BackColor), modificirat će se i odgovarajući tag: <asp:TextBox id=myTextBox runat="server" BorderStyle="Ridge" BorderWidth="5px" BackColor="PaleGreen" BorderColor="DarkOliveGreen" Text = "Yo dude" > </asp:TextBox> Obzirom na to da HTML deklaracija web kontrole eventualno postane pripadna varijabla iz System.Web.UI.WebConrols imenskog prostora (preko dinamičkog kompilacijskog ciklusa), moći ćemo interaktivno koristiti članove ovog tipa unutar programske logike na serverskoj strani: public partial class _Default : System.Web.UI.Page { ... protected void btnChangeTextBoxColor_Click(object sender, EventArgs e) { // Modify the HTTP response data for this widget. this.myTextBox.BackColor = System.Drawing.Color.Red; } } Sve ASP.NET web kontrole izvode se iz zajedničke temeljne klase System.Web.UI.WebControls.WebControl. Sam WebControl izvodi se iz klase System.Web.UI.Control (koja se izvodi iz System.Object). Control I WebControl definiraju brojna svojstva koja su zajednička svim kontrolama na poslužiteljskoj strani. Prije nego ispitamo naslijeđenu funkcionalnost, pokredajmo što to znači servisirati događaj na serverskoj strani. Kvalificiranje servisiranja događaja na poslužiteljskoj strani Obzirom na tekuće stanje WordWideWeb-a nemoguće je izbjeći prirodnu interakciju poslužitelja i pretražitelja. Kad god ova dva entiteta komuniciraju, uvijek se sve temelji na nekakvim HTTP zahtjev-odgovor ciklusima u kojima se ne vodi računa o stanjima. . ASP.NET poslužiteljske kontrole uvelike nas štite od detalja HTTP protokola, no treba imati na umu da tretiranje Weba kao entiteta pokretanog događajima nije ništa drugo nego veličanstveni show sa dimom i zrcalima koji nam omogućava CLR i nije identičan sa modelom pokretanja događajima korisničkih sučelja za Windows. Zbog toga, iako imenski prostori System.Windows.Forms i System.Web.UI.WebControls definiraju tipove koji imaju ista imena (Buttons, TextBox, GridView, label i dr.), ovi ne očituju i identičan skup grešaka. Primjerice, ne postoji način na koji se može servisirati Mouse-Event na serverskoj strani, tj. Događaj izazvan pomocanjem korisničkog miša. To je očigledno prednost jer bi bezpotrebno opterećivali server sa nebitnim podacima o koordinatama miša. Zbog toga, ASP.NET web kontrole eksponiraju ograničeni skup događaja, a svaki od njih nužno završava postbackom prema web serveru. Bilo koje potrebno procesiranje događaja na klijentskoj strani, zahtijevat će da pisanje klijentske logike. AutoPostBack svojstvo Važno je istaknuti da jako velik broj ASP.NET web kontrola podržava svojstvo koje se zove AutoPostBack (najuočljivije je kod CheckBox-a, RadioButton-a, i TextBox kontrola i svih komponenti koje su izvedene iz ListControl tipa). Prema postavnim vrijednostima, ovo je svojstvo postavljeno na neistinu (false) čime se onemogućava automatsko slanje događaja sa serverske strane (čak i ako je event označen u datoteci programskog koda). U brojnim slučajevima, to je ponašanje kakvo i priželjkujemo. Ipak, želimo li omogućiti bilo kojoj od ovih komponenti postbackove prema serviserima događaja na serverskoj strani, ovu vrijednost moramo uključiti na “istinu”. Ova tehnika može nam biti od koristi želimo li imati sa stanjem jedne komponente automatski napuniti vrijednost neke druge komponente na istoj stranici. Zbog ilustracije, kreirajmo website koji sadrži jedan TextBox i jedan ListBox. Servisirajmo TextChanged događaj TextBoxa i u sklopu servisera događaja na serverskoj strani, popunimo ListBox sa vrijednostima iz TextBox-a. protected void txtAutoPostback_TextChanged(object sender, EventArgs e) { lstTextBoxData.Items.Add(txtAutoPostback.Text); } Pokrenemo li aplikaciju, ništa se ne događa dok upisujemo u TextBox, ukoliko je AutoPostBack svojstvo postavljeno na false. Postavimo li drugačije: <asp:TextBox ID="txtAutoPostback" runat="server" AutoPostBack="True" OnTextChanged="txtAutoPostback_TextChanged"> </asp:TextBox> u trenutku kada prebacimo fokus sa TextBoxa na nešto drugo, tekst će se prebaciti u u ListBox. U ostalim slučajevima, ovo je svojstvo bolje ne mijenjati….
© Copyright 2024 Paperzz