Eötvös Loránd Tudományegyetem Informatikai Kar Webes alkalmazások fejlesztése 6. előadás Weblapok fejlesztése és architektúrája (ASP.NET) 2014.03.31. Giachetta Roberto groberto@inf.elte.hu http://people.inf.elte.hu/groberto
A HTTP protokoll A webes adatközlés alapvető protokollja a HTTP (Hypertext Transfer Protocol), amely a webböngészők elsőszámú kommunikációs csatornája a kérés/válasz paradigmára épül, vagyis a kliens elküld egy kérést, amelyre a szerver (alkalmazás) válaszol a választ értelmezi és megjeleníti kliens (böngésző) kliens (böngésző) válaszból kinyert tartalom (HTML, CSS, JavaScript, ) HTTP kérés HTTP válasz szerver web alkalmazás ELTE IK, Webes alkalmazások fejlesztése 6:2
A HTTP protokoll a szerver beazonosíthatja a klienst, és így felépíthet egy munkamenetet (session) az azonosításhoz kliens oldalon kerülnek mentésre értékek, ennek három módszere: elérési útvonal: magában az útvonalban azonosítják a felhasználót rejtett mező (hidden field): a HTML oldalban elhelyezett érték süti (cookie): a weblaphoz tartozó kis méretű adat (kulcs-érték párok), független az oldaltól a protokoll biztonságossá tehető TSL titkosítással (HTTPS) ELTE IK, Webes alkalmazások fejlesztése 6:3
A HTTP protokoll a kérésnek több típusa lehet, pl.: GET: adott (elérési útvonalhoz tartozó) erőforrás lekérése POST: adatokkal ellátott tartalom küldése (pl. űrlap tartalom) a válasz első sora a státuszsor, amely visszajelez a kérés végrehajtásáról (pl. 200 sikeres, 404 nem található, 503 szolgáltatás nem elérhető) a protokoll állapotmentes, azaz a szerverre érkező kérések egymástól függetlenek két kérés között nincs állapotmegőrzés szerver oldalon (grafikus felületű alkalmazásokkal ellentétben) ELTE IK, Webes alkalmazások fejlesztése 6:4
Fejlesztési módszerek A webes felületű alkalmazás több módszerrel valósítható meg: statikus fejlesztés: a weblap megjelenését és tartalmát definiáljuk, pl. HTML, CSS kliens oldali fejlesztés: a végrehajtást a böngésző, illetve abban futó alkalmazások végzik, pl.: JavaScript, Ajax, Flash, Silverlight szerver oldali fejlesztés: a tevékenységeket a szerver futtatja le, és az eredményt továbbítja a kliensnek, pl.: PHP, Java, ASP.NET, Ruby on Rails, SSJS kliens és szerver oldali fejlesztés, pl. ASP.NET és Javascript, Dart, Pyjamas ELTE IK, Webes alkalmazások fejlesztése 6:5
Fejlesztési módszerek Szerver oldali fejlesztés esetén: a böngésző elküld egy kérést a szervernek, amely feldolgozza azt, és visszaküldi a választ minden frissítési tevékenység a szerveren fut le, és a teljes lap újratöltését eredményezi a böngésző ezt navigáció és űrlapok segítségével kezeli kliens (böngésző) szerver kérés lap újratöltése válasz ELTE IK, Webes alkalmazások fejlesztése 6:6
Fejlesztési módszerek Kliens oldali fejlesztés esetén: a böngésző egy kliens oldali feldolgozó alkalmazással (motor) kommunikál, ez továbbítja a kéréseket a szervernek a motor frissítheti a lap bármely részét, ezért nem kell azt teljesen újratölteni kliens (böngésző) lap frissítése kliens (Javascript motor) szerver kérés válasz ELTE IK, Webes alkalmazások fejlesztése 6:7
Fejlesztés ASP.NET alapon A Microsoft ASP.NET az ASP (Active Server Pages) továbbfejlesztése.net programozás támogatással egy (szerver oldali) programozási felület dinamikus weblapok készítésére HTTP protokollon keresztül hozzáférést biztosít a teljes.net keretrendszerhez, és bármely CLR alapú bővítményéhez, így bármely.net nyelvvel programozható (alapértelmezett a C# és a VB.NET) támogatja a hatékony adatkezelést, a többrétegű alkalmazásfejlesztést jól skálázható, bővíthető ELTE IK, Webes alkalmazások fejlesztése 6:8
Fejlesztés ASP.NET alapon Az ASP.NET alapvetően három programozási modellt kínál: Web Forms: az alkalmazás dinamikus részeit vezérlők és eseménykezelés segítségével valósítja meg az első webes modell, elsősorban azoknak, akik korábban grafikus felületű alkalmazásokat készítettek alapja a Windows Forms, a felülethez (ASP) ugyanúgy tartozik háttérkód (C#, VB.NET) a weblapok dinamikus tartalmát űrlapokba szervezi, amelyekben HTML, valamint ASPX vezérlők kapnak helyet lehetőséget ad kétrétegű (MV) architektúrára, adatkötésre ELTE IK, Webes alkalmazások fejlesztése 6:9
Fejlesztés ASP.NET alapon pl.: <%@ Page Language="C#" %> <script runat="server"> protected void Page_Load( ) { // eseménykezelő betöltéskor label.text = "Hello World! Now it s " + Datetime.Now; // felirat } </script> <html><body> <form runat="server"> <!-- űrlap --> <asp:label runat="server" ID="label" /> <!-- ASP címke, felirata dinamikus --> </form> </body></html> ELTE IK, Webes alkalmazások fejlesztése 6:10
Fejlesztés ASP.NET alapon a szerver minden kéréssel létrehozza az oldalt (objektumot), futtatja az eseménykezelőket, majd a kiszolgálja az eredményt (HTML formátumban) kérés válasz kliens weblap objektum példányosítása eseménykezelők futtatása eredmény HTML összeállítása ELTE IK, Webes alkalmazások fejlesztése 6:11
Fejlesztés ASP.NET alapon Web Pages: egyszerű, jórészt statikus alkalmazások megvalósítása, amelyek támogatnak dinamikus funkciókat és adatkezelést a dinamikus funkciók beépülnek a felületbe, azaz az alkalmazás egy rétegű, nincs architektúra egyszerű webes alkalmazásokra hasznos a webfelület leíró nyelve (Razor) egyszerűsíti a korábbi szintaxist, nincs szükség vezérlőkre, eseménykezelésre az adatkezelés adatbázisszeren keresztül (MSSQL) biztosítja könnyen integrálja a jelentősebb szolgáltatásokat (Twitter, recaptcha, Bing Maps, ) ELTE IK, Webes alkalmazások fejlesztése 6:12
Fejlesztés ASP.NET alapon pl.: @{ // háttérkód Datetime ctime = DateTime.Now; } <html lang="en"> <body> <p>hello world! Now It s @ctime</p> @* változó elérése *@ </body> </html> MVC: összetett weblapok fejlesztésére szánt modell, amely egy jobban szeparált architektúrát kínál, illetve több megjelenítési lehetőséget is kínál ELTE IK, Webes alkalmazások fejlesztése 6:13
Az MVC architektúra A modell/nézet architektúra hátránya, hogy a felület megjelenítése nincs szétválasztva a tevékenységek végrehatásától (eseménykezelés) a felülettervező és a fejlesztő egyazon kódon dolgozik A modell/nézet/nézetmodell (MVVM) architektúra leválasztja a tevékenységeket (parancsok), illetve az adatok felülethez történő hozzárendelését (adatkötés) a nézetmodell nem ismeri a nézetet, csak transzformálja az adatokat, illetve események segítségével jelez a nézetnek, amely lekéri a változásokat a nézetmodelltől a nézetmodell tulajdonképpen egy átjáró (proxy) ELTE IK, Webes alkalmazások fejlesztése 6:14
Az MVC architektúra A modell/nézet/vezérlő (Model-View-Controller, MVC) architektúra egy háromrétegű felépítés, amelyben a tevékenységek végrehajtása egy külön rétegbe kerül a nézet a felület (jórészt deklaratív) definíciója, nem tartalmaz háttérkódot, csupán az adatokat kéri a modelltől a modell a logikai funkciók végrehajtása (üzleti logika), amely magában foglalja az adatkezelést (amely akár külön rétegbe helyezhető) a vezérlő a kezdeményezett tevékenységek végrehajtója, amely befolyásolja a modell állapotát, illetve frissíti a nézetet a tevékenység eredménye alapján ismeri és kezeli a nézetet ELTE IK, Webes alkalmazások fejlesztése 6:15
Az MVC architektúra megjelenít kliens MVC architektúra nézet modell frissít adatelérés felhasznál vezérlő végrehajt adatforrás ELTE IK, Webes alkalmazások fejlesztése 6:16
Az MVC architektúra Az MVC architektúra végrehajtási ciklusa: 1. a felhasználó interakciót létesít a felülettel 2. a vezérlő fogadja a felhasználói tevékenységet, majd a modellben végrehajtja a megfelelő akciót (action method) 3. a modellben végrehajtott akció állapotváltást okoz 4. a vezérlő begyűjti az akció eredményét (action result), majd frissíti a nézetet (push-based) a nézet is lekérdezheti a vezérlők eredményeit (pullbased) esetleg a modell is adhat jelzést a nézetnek, hogy állapota megváltozott 5. a nézet prezentálja az eredményt ELTE IK, Webes alkalmazások fejlesztése 6:17
Az MVC architektúra kérés válasz kliens vezérlő példányosítása eredmény HTML összeállítása vezérlő akció végrehajtása modell állapotfrissítése nézet frissítése ELTE IK, Webes alkalmazások fejlesztése 6:18
MVC web alkalmazások elemei Az ASP.NET MVC alkalmazások az MVC architektúrát valósítják meg dedikált komponensek segítségével a nézetek (View) több leíró nyelvet is használhatnak (ASPX, Razor, ) a nézetben a modell elemeire hivatkozhatunk (adatkötéssel), illetve használhatunk HTML kódot a modell lehet adatmodell (entitásmodell), vagy bármilyen üzleti logika, illetve a speciálisan a nézetet kiszolgáló nézet modell (view modell) a vezérlők (Controller) a tevékenységeket tartalmazzák, amiket akciók (metódusok) segítségével adunk meg az akció eredménye (ActionResult) általában egy nézet ELTE IK, Webes alkalmazások fejlesztése 6:19
MVC web alkalmazások elemei Pl. (vezérlő több akcióval): public class MyController : Controller { // vezérlő public ActionResult Index() { // akció return View("Welcome to the website!"); // az eredmény egy nézet lesz, benne a // szöveg, ez lesz a nézet modell } public ActionResult List(){ // adatok elkérése a modellből return View(list); } public ActionResult Details(String id){ } ELTE IK, Webes alkalmazások fejlesztése 6:20
MVC web alkalmazások elemei Pl. (Razor nézet): @model String @* a modell típusa szöveg lesz *@ @{ } @* kód blokk *@ <!DOCTYPE html> <html> <head> </head> @* statikus tartalom *@ <body> <div> @Model @* elhelyezzük a nézet modellt az oldalban *@ </div> </body> </html> ELTE IK, Webes alkalmazások fejlesztése 6:21
Weblapok hierarchiája Az MVC alkalmazás könyvtárfelépítése tükrözi a moduláris felépítést a View, Controllers és Models könyvtárak a megfelelő tartalmat hordozzák az App_Data könyvtár tárolja az esetleges adattartalmat (pl. adatbázis fájlok) az App_Start könyvtár az indítási tevékenységeket (pl. RouteConfig) a gyökérben található a konfiguráció (web.config), valamint az alkalmazásszintű vezérlés (Global.asax) MVC alkalmazáshoz szükséges a NuGet csomagkezelő ELTE IK, Webes alkalmazások fejlesztése 6:22
Elérési útvonalak kezelése Az MVC architektúrában a felhasználó a vezérlővel létesít kapcsolatot, és annak akcióit futtatja (paraméterekkel) az elérés és paraméterezés útvonalak segítségével adott, amelyek egy útvonalkezelő (routing engine) felügyel az elérés testre szabható (RouteConfig), alapértelmezetten a <domain>/<vezérlő>/<akció>/<paraméterek> formában biztosított vezérlő megadása nélkül az alapértelmezett HomeController vezérlőt tölti be akció megadása nélkül az Index akciót futtatja a paraméterek feloldása sorrendben, vagy név alapján történhet ELTE IK, Webes alkalmazások fejlesztése 6:23
Elérési útvonalak kezelése pl. Útvonal http://mypage/ http://mypage/hello /Hello/List /Hello/Details/1 /Hello/Details?id=1 Tevékenység a HomeController vezérlő Index metódusa fut a HelloController vezérlő Index művelete fut a HelloController vezérlő List művelete fut a HelloController vezérlő Details művelete fut id=1 paraméterrel ELTE IK, Webes alkalmazások fejlesztése 6:24
Vezérlők A vezérlők a Controller osztály leszármazottai, amely tevékenységüket publikus műveletek segítségével valósítják meg a tevékenység eredményt ad vissza (ActionResult), de visszaadhat bármilyen típust, amely a nézet által feldolgozható (pl. String) a nézet modellen túl a nézet felé is megadhat információkat a ViewBag tulajdonságon keresztül ez egy dinamikus tulajdonság, így bármilyen értéket tud fogadni, pl. ViewBag.Message = "Hello" a tartalmat a nézet elérheti és felhasználhatja, pl.: <div>@viewbag.message</div> ELTE IK, Webes alkalmazások fejlesztése 6:25
Vezérlők az eredménye típusa többféle lehet általában nézet (ViewResult), amely lehet parciális (PartialViewResult) lehet fájl (FileResult), szkript (JavaScriptResult), tetszőleges tartalom (ContentResult), de üres is (EmptyResult) jelezhetünk hibát (HttpNotFoundResult, HttpUnathorizedResult, HttpStatusCodeResult) átirányíthatunk (RedirectResult) az eredménytípusokhoz tartozik egy művelet a Controller osztályban, amely azt előállítja, pl.: return View( ); // eredmény ViewResult lesz ELTE IK, Webes alkalmazások fejlesztése 6:26
Vezérlők pl.: public class MyController : Controller { public ActionResult LoadImage(String id){ Byte[] image = // adat betöltése if (image == null) // rossz az azonosító return RedirectToAction("NotFound"); // átirányítunk egy másik akcióhoz return File(image, "image/png"); // visszaadjuk fájlként a tartalmat } public HttpNotFoundResult NotFound() { return HttpNotFound("Content not found."); } // hibajelzés ELTE IK, Webes alkalmazások fejlesztése 6:27
Nézetek A nézet több leíró nyelvet is támogat, ezek közül a Razor rendelkezik a legegyszerűbb szintaxissal a nézet lehet erősen típusos, ekkor megadjuk a nézet modell típusát, pl. @model MyProject.Model.ItemModel a dinamikus elemeket a @ előtaggal jelöljük a @{ } blokkban tetszőleges háttérkódot helyezhetünk a @* *@ blokk jelöli a kommentet használhatunk elágazásokat (@if) és ciklusokat (@for, @foreach) megadhatunk névtérhasználatot a @using elemmel (ellenkezdő esetben a teljes elérési útvonalat használjuk) ELTE IK, Webes alkalmazások fejlesztése 6:28
Nézetek a nézet modellre a Model elemmel hivatkozhatunk, míg a nézetre megadott adatokra a ViewBag elemmel speciális HTML tartalmat a Html elemmel érhetünk el, pl.: hivatkozások akciókra (ActionLink), amelyben megadjuk az akciót, (a vezérlőt) és az argumentumokat (egy argumentum objektumban), pl.: Html.ActionLink("LoadImage", new { id = 1 }); űrlapok (BeginForm, EndForm) megjelenítő és beolvasó elemek (LabelFor, TextBoxFor, PasswordFor), ellenőrzések (ValidationMessageFor) nem kódolt tartalom elhelyezése (Raw) ELTE IK, Webes alkalmazások fejlesztése 6:29
Nézetek lekérdezhetjük a kérés típusát (IsPost) speciálisabb elérési útvonalakat az Url elemmel kezelhetjük, pl.: Url.Content("~/style.css") beágyazhatunk szkripteket a Scripts elemmel, stílusokat a Styles elemmel, pl.: Scripts.Render("~/bundles/jqueryval") a nézetnek megadhatunk elrendezéseket (Layout), illetve különböző profilokhoz igazíthatjuk őket (pl. asztali/mobil környezet) A nézet egy olyan objektum, amely megvalósítja az IView interfészt, a nézet leíró nyelve (motorja) pedig az IViewEngine interfészt, így lehet saját motorokat és nézeteket megvalósítani ELTE IK, Webes alkalmazások fejlesztése 6:30
Nézetek pl.: public class MyController : Controller { public ActionResult List(){ ViewBag.Title = "List of names"; // beállítjuk az oldal címét String[] itemnames = ; return View("ListPage", itemnames); // visszaadunk egy tömböt a List // nézetnek } public ActionResult Details(String name){ return View("DetailsPage", ); } ELTE IK, Webes alkalmazások fejlesztése 6:31
Nézetek pl. (ListPage.cshtml): @model IEnumerable<String> @* erősen típusos oldal *@ @{ Layout = null; // nincs elrendezés } <!DOCTYPE html> <html> <head> <title>@viewbag.title</title> </head> @* a címet a vezérlő adja meg *@ <body> ELTE IK, Webes alkalmazások fejlesztése 6:32
Nézetek @if (Model!= null){ // elágazás <div> @foreach (String name in Model){ <span><b>@name</b> @Html.ActionLink("See details", "Details", name); @* link a Details akcióra *@ </span> } </div> } else { <div>no items found!</div> } </body></html> ELTE IK, Webes alkalmazások fejlesztése 6:33
Weblapok kihelyezése A weblapokat a fejlesztést követően ki kell helyezni (deploy) egy webszerverre a konfigurációnak (web.config) megadható egy nyomkövetési (debug) és egy kiadási (release) változata a weblap alapból nyomkövetésre van konfigurálva, ezt érdemes kikapcsolni a compilation elemben biztonsági okokból a kivételek jelzését csak lokálisan engedélyezzük a customerrors beállításával a nézetek csak a futtatás során fordulnak le, ezért külön oda kell figyelni a hibaellenőrzésre (ez felüldefiniálható a projektfájlban) ELTE IK, Webes alkalmazások fejlesztése 6:34
Példa Feladat: Készítsünk el az utazási ügynökség weblapját, amelyben az apartmanok adatait tudjuk megtekinteni. a főoldalon (Index) az épületek alapvető adatai listázódnak, amit szűrhetünk, a részletek oldalon (Details) egy épület apartmanjai listázódnak az oldalt egy vezérlő (HomeController) irányítja, amely három akciót definiál: minden listázása (Index), egy város épületeinek listázása (List), egy épület részleteinek lekérése (Details) a városok listázásához felhasználjuk a ViewBag tulajdonságot az adatokat adatbázisban (TravelAgency) tároljuk ELTE IK, Webes alkalmazások fejlesztése 6:35
Példa Tervezés (adatbázis): ELTE IK, Webes alkalmazások fejlesztése 6:36
Példa Tervezés (adatbázis): class TravelAgency Controller Controllers::HomeController - _entities :TravelAgencyEntities + HomeController() + Index() :ActionResult + List(Int32) :ActionResult + Details(Int32) :ActionResult View Views::Index View Views::Details -_entities DbContext Models::TravelAgencyEntities ELTE IK, Webes alkalmazások fejlesztése 6:37
Példa Megvalósítás (HomeController.cs): public ActionResult List(Int32 cityid) { // ha hibás az azonosító if (!_entities.city.any(c => c.id == cityid)) return HttpNotFound(); // átirányítjuk a nem talált oldalra } // megkeressük a megfelelő város szonosítókat return View("Index", _entities.building.include("city").where(b => b.cityid == cityid)); ELTE IK, Webes alkalmazások fejlesztése 6:38
Példa Megvalósítás (Index.cshtml): <ul> @* felsoroljuk a városokat *@ @foreach (City city in ViewBag.Cities) { <li> @* létrehozunk egy linket minden városra *@ @Html.ActionLink(city.Name, "List", new { cityid = city.id }) </li> } </ul> ELTE IK, Webes alkalmazások fejlesztése 6:39