ASP.NET Dynamic Data – ili kako lako dizati skele
Uvod
Pojam “scaffolding” je od pojave Ruby on Rails okruženja za izradu apliakcija postao neverovatno popularan kada se govori o web aplikacijama. Ideja je veoma prosta. Većina web aplikacija na ovaj ili onaj način predstavlja u osnovio samo CRUD aplikacije.
“Scaffolding” je ideja da se na osnovu podataka iz baze generiše UI koji bi pokrio osnovne CRUD operacije. Pored RoR-a, postoji mnogo drugih framework-a koji nude slične mogućnosti, bilo kao zasebne skritpove koji generišu odgovarajuće fajlove sa formularima (Symfony, CakePHP pa i sam RoR) ili putem davanja specijalngo sajta koji preko modela baze generiše dinamički web strane (Django, recimo). ASP.NET MVC je takođe dodao podrškui za scaffolding u RC1 verziji, tako da sada kada dodajete view možete da odaberete i koju akciju taj view bi trebalo da pokrije i da dobijete gotov kod.
Dynamic Data je sličan mehanizam samo za ASP.NET WebForms svet. U suštini, on predstavlja jedan engine koji koristi LINQ to SQL ili Entity Framerok modele i spaja ih sa skupom predefinisanih
Kako do Dynamic Data?
Dynamic Data se prvi put pojavio kao deo ASP.NET 3.5 Extensions CTP-a, ali se u međuvremenu vratio u “core release” i postao deo .NET Framework 3.5 SP1 paketa. Glavni sajt je www.asp.net/dynamicdata sa koga možete da nađete i link za download.
Pravljenje osnovnog sajta
Krenimo od početka. Instalacija SP1 će dodati nekoliko novih tipova projekata u Visual Studio. Da bismo napravili Dynamic Data projekat, potrebno je da odemo na File –> New i da u odeljku “Web” odaberemo “Dynamic Data Web Application” kao što je pokazano na sledećoj slici:

Posle pravljenja projekta, prva stvar koju možemo da primetimo u Solution Exploreru jeste da se generiše značajna količina fajlova koji se nalaze u folderu DynamicData. PageTemplates fodler u okviru rešenja sadrži sve template-a strana koje možemo da koristimo, kao što su “list” ili “details”. Svaka strana se sastoji oz niza korisničkih kontrola (*.ascx fajlova) koji u stvari predstavljaju srž mogućnosti koje Dynamic Data pruža. Ako otvorimo taj folder u rešenju, videćemo sledeću sliku:
Svaka korisnička kontrola odgovara jednom tipu podataka koji koristimo u bazi. DateTime.ascx, recimo, služi za prikaz vrednosti iz baze tipa, pogodili ste, DateTime. Neke kontrole imaju svoje “parnjake” koji se zovu isto, ali imaju sufiks “_Edit”; te korisničke kontrole se koriste tokom menjanja ili dodavanja vrednosti u bazu podataka. Naravno, svaka ova kontrola omogućava izmene na dva načina. Prvi je da se izmeni samo funkcionisanje kontrole. Drugi je da se izmeni izgled putem CSS fajla koji postoji u korenu rešenja.
No, više o izmenama kojima možemo da prilagodimo Dynamic Data specijalnim prilikama ili rešenjima u sledećim postovima. Za sada da pokažemo osnovnu namenu, a to zahteva uključivanje i baze podataka u rešenje.
Uključivanje baze podataka
Prvo što je potrebno, osim baze podataka, jeste i LINQ to SQL model koji je baziran na njoj. Da bih se udaljio malo od stare (dobre?) tradicije Microsoft primera koji koriste Northwind bazu, odabrao sam “Chinook” koju sam našao sasvim slučajno prilikom pregledavanja CodePlex sajta. Više informacija možete da nađete na Chinook projekat linku.
Dodavanje LINQ to SQL modela se vrši na standardni način. Desni klik na rešenje, odabiranje opcije “Add New Item…” i zatim odabiranje LINQ to SQL klase. Posle kreiranja potrebnih fajlova, pred nama se nalazi poznata površina dizajnera na kojeg ćemo prevući nekoliko tabela uz baze podataka. Bitno je obratiti pažnju na ime koje smo dali našoj DataContext klasi. U ovom slučaju, ime koje sam odabrao za DBML fajl je Chinook, stoga je ime klase ChinookDataContext.
Preostaje nam samo da odkomentarišemo par linija koda i uključimo podršku za scaffolding. U global.asax fajlu se nalaz nekoliko stvari koje su nam potrebne. U prvom bloku koda, uz detaljne komentare kako da uključimo scaffolding, imamo i liniju koda koju je potrebno da odkomentarišemo.
1: model.RegisterContext(typeof(ChinookDataContext), new ContextConfiguration() { ScaffoldAllTables = true });
Ključno je proslediti pravi tip DataContext klase ili ObjectContext klase u RegisterContext metod (i, naravno, using direktive ukoliko se isti nalazi u drugom rešenju). Potom možemo da podesimo ScaffoldAllTable property ContextConfiguration klase. Ovo će uključiti sve tabele (odnosno klase) u našem modelu u scaffolding proces, što znači da će se kreirati UI za sve klase koje imamo. U samim komentarima postoje smernice za drugu situaciju, ukoliko želimo da neke klase isključimo iz ovog procesa. Ukratko, potrebno je na te klase staviti "Scaffold(false)” atribut. Pošto su u pitanju L2S ili EF klase, koje se generišu sa partial modifikatorom
Druga stvar koja je bitna za pogledati jesu routes, odnosno putanje koje se definišu takođe u global.asax fajlu. Ukoliko niste upoznati, Routes su došli sa ASP.NET MVC Framework-om, ali su u međuvremenu postali deo generalno System.Web namespace-a. Oni omogućavaju da se definišu rute kojima se stiže do resursa, bilo da su ti resursi aspx strane, kao u slučaju Dynamic Data (ili Web Forms 4.0 koji nam dolazi sa sledećom verzijom VS-a/.NET-a) ili pak kontrolera i njihovih metoda. Ne bi bilo zgoreg, iako verovatno za osnovne upotrebe nećete menjati default putanje, da pogledate
Konačan rezultat
Kada sledeći put budemo pritisli F5, imaćemo gotovu aplikacijiu za pregled i unos podataka u bazu koju smo koristili u LINQ to SQL. Svaka tabela jre pdstavljana po jednim GridView-om, koji omogućava sortiranje, brisanje i promenu vrednosti tog polja. Isto tako, omogućeno je dodavanje novih vrednosti. Naravno, relacije u bazi podataka su očuvane, tako da, primera radi, ako unosimo novi slog u tabelu koja ima definisan strani ključ, dobićemo select listu za odabir vrednosti iz povezane baze.
Naravno, bilo bi besmisleno da imamo aplikaciju koja omogućava unos podataka tako da možemo da unesemo neželjene vrednosti. Dynamic Data kontrole sadrže i validatore za polja. Ako otvorimo, primera radi. TextField_Edit.ascx kontrolu i pogledamo kod, videćemo da postoje validatori:
1: <%@ Control Language="C#" CodeBehind="Text_Edit.ascx.cs" Inherits="DynamicDataTest.Text_EditField" %>
2:
3: <asp:TextBox ID="TextBox1" runat="server" Text='<%# FieldValueEditString %>' CssClass="droplist"></asp:TextBox>
4:
5: <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator1" CssClass="droplist" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
6: <asp:RegularExpressionValidator runat="server" ID="RegularExpressionValidator1" CssClass="droplist" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
7: <asp:DynamicValidator runat="server" ID="DynamicValidator1" CssClass="droplist" ControlToValidate="TextBox1" Display="Dynamic" />
Validatori koriste model da bi shvatili koja polja su obavezna a koja ne i na osnovu toga postavljaju validaciju ili je ne postavljaju. Konačni rezultat je da kada jednom kreirate CRUD UI, ne morate da brinete o tome da radite validaciju, ona je automatski uključena.
Šta dalje?
Gore opisanim koracima smo došli do kompletno funckionalnog sajta za pregled i unos podataka u našu bazu. Naravno, priča se nikako ne završava tu. Sve korisničke kontrole koje sam pomenuo ne samo da mogu da se menjaju, već mogu i da se koriste u postojećim Web Forms aplikacijama kao zamena i/ili dopuna postojećim kontrolama koje rade sa podacima. Više o tome u sledećim člancima u serijalu.
Out.
B.D.