Az ASP .NET programozási nyelv

MVC

Az MVC egy tervezési, vagy architekturális minta. Minden alkalmazás 3 rétegre osztható:

ASP .NET Web alkalmazás

Controller-ek és routing

Az MVC modellen belül a Controller szerepe az, hogy válaszoljon a felhasználói inputra, gyakran módosításokat hajtva végre a model-en az inputtól függően. Az MVC Controllerjei az alkalmazás folyamatával, illetve az üzleti logikával törődnek, feldolgozzák a bejövő adatot és kimenő adatot szolgáltatnak a megfelelo View számára. Az aktuális oldal URL-je megmondja az útvonalválasztó mechanizmusnak (routing), melyik controller osztályból kell példányt elkészíteni, és a példány melyik action metódusát kell hívni, emellett szolgáltathat argumentumokat az adott metódus számára.

A Controller metódusa dönti el, hogy melyik View-et adja vissza, amely View HTML-é fog renderelődni. A Controller egy-egy Request kezelésében a második vonal szerepét látja el (az elso a routing mechanizmus).

A View szerepe

A View-k tárolási konvenciója az az, hogy minden Controller-hez tartozzon egy könyvtár a projekt könyvtárának /Views könyvtárán belül, melyet a Controller nevével azonosítunk (a Controller suffix nélkül). Például, ha a Controller neve HomeController, akkor az általa felhasználni kívánt View-k a /Views/Home könyvtárba érdemes helyezni.

Ezen alkönyvtáron belül a konvenció szerint minden action metódushoz egy view file-t érdemes rendelni, mely megegyezik a metódus nevével, mivel ez egy alapot adhat arra, hogy az egyes View-k hogyan asszociálhatók egy action metódussal. Természetesen ettől el lehet térni, ez csak egy (erős) ajánlás.

public class MyController : Controller { public ActionResult Index() { return View(); } [HttpGet] public JsonResult Index() { return Json(new { ID=0, Content="Arvizturo kanyarfuro" }, JsonRequestBehavior.AllowGet); } }

Ha a return View(); híváskor nincs paraméterként a View neve megadva, a ViewResult melyet visszaadunk a névkonvenció alapján fogja a /Views/Controllernév könyvtárban keresni a metódus nevéhez illő View-t.

//A fenti példában a JsonResult egy AJAX HTTPGET kérést fogad, mely egy dinamikusan létrehozott objektumot ad vissza JSON formátumúvá konvertálva.

ViewData és ViewBag

A Controller és a View közötti adatátadás egyik alapveto eszköze ViewDataDictionary-n keresztül történhet (amely egy specializált szótár szerkezet), melyhez a ViewData fogalma tartozik.

A ViewData-t mint asszociatív tömböt lehet a legegyszerubben megérteni, azaz ViewData["kulcs"] hivatkozással lehet a kulcshoz tartozó értéket megkapni.

Habár a ViewData egy kiváló eszköz az adatátadásra, az MVC3-ban megjelent a 4-es verziójú C# dinamic típusának használata az egyszerubb szintaxis kedvéért (a programozó ugyanis többször használ munkája során osztály adattagokat/property-ket, mint asszociatív tömböt).

A ViewBag, amely egy dinamikus wrapper objektum a ViewData körül lehetővé teszi a fejlesztő számára eme egyszerűbb szintaxis használatát. A ViewBag tehát tekinthető csak szintaktikai cukornak, mivel az olyan relatíve valószínűtlen eseteket kivéve, mint pl. "kulcs mely szóközöket tartalmaz" nem jelentkezik sem a ViewData, sem a ViewBag használatának semmilyen nagyjelentőségű elonye a másikkal szemben ( a példában az említett kulccsal hivatkozott objektum nem lesz elérheto a ViewBag használatával)

Erősen típusos View

@model IEnumerable<MvcApplication1.Models.Album> <ul> @foreach (Album p in Model) { <li>@p.Title</li> } </ul>

Habár a View-ban felhasználni kívánt adatot akár a ViewBag használatával is tovább lehet passzolni a Controllertől, a típuskonverzió erőforrásigénye (is) indokolttá teszi hogy legyen valamilyen egyszerűbb mód arra, hogy a használni kívánt model típusát a View szintjén deklarálni lehessen.

A problémára a megoldás a ViewDataDictionary .Model property-je. Ha egy action metódus visszatér a return View(model); vagy a return View("viewnév", model); felhasználásával, a ViewData.Model property-je beállítódik a megadott típusra.

A View-ben szintén deklarálható az

@model tipus
direktíva felhasználásával.

A View-ben lehetőség van a using direktíva használatára a kódfileokban megszokott módon (+ az @ szimbólum):

@using Nevter.Osztaly

Ezáltal könnyebben használhatóak az egyes névtér-elemek.

Amennyiben egy adott using direktívát sok helyen kellene használni, hasznos alternatívaként felmerülhet a web.config használata, ahol a system.web.webPages.razor csomóponton belul a pages pageBaseType="System.Web.Mvc.WebViewPage" csomópont namespaces alcsomópontjában van lehetőség a névteret hozzáadni az egész alkalmazáshoz:

<system.web.webPages.razor> … <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> ... <add namespace="Nevter.alter" /> </namespaces> </pages> </system.web.webPages.razor>

Partial View és Master page

Master Page

A Master Page (vagy másnéven Layout) arra szolgál hogy a webalkalmazás oldalai számára konzisztens megjelenést biztosítson. Ilyen lehet például az oldalmenü, amely minden oldalra változatlan, vagy a minden aloldalra alkalmazható header/footer. Emellett az egyes aloldalak standard viselkedésének (pl. javascript file-ok) megadására is lehetőség van.

Alapértelmezésben a _ViewStart.cstml (razor engine esetén) tartalmazza eme viselkedés és kinézet leírását.

Partial View

Új View hozzáadása esetén lehetoség van arra, hogy az adott View részleges legyen. Ekkor a View renderelésekor nem fog a layout file hozzáadódni a View-hoz.

Ez abban az esetben (is) lehet hasznos, ha az adott weboldal-darabot máshol is fel akarják használni.

View engine

A View Engine felelős a View rendereléséért HTML formátumba. A Razor az elso nagyjelentőségű újítás a HTML oldal renderelésével kapcsolatban mióta az ASP.NET első verziója megjelent. A Razor megjelenése előtt a view engine, ami az aspx/ascx/.master file-ok felhasználásával html oldalakat generált a Web Forms view engine volt, mivel ez kötötte össze a Web Forms illetve az MVC technológiát, ez szolgált átmeneti megoldásnak, majd vert gyökeret. A Web Forms engine-t még ma is használják köszönhetően leginkább a Web Forms szintaxisához szokott fejlesztőknek illetve a régi projektekből megmaradt legacy kód miatt.

A Web Forms engine legnagyobb baja az, hogy arra lett tervezve, hogy a weboldal részeit felépítő control-ok szerkesztését támogassa a grafikus szerkesztőben, amely az MVC-ben legalábbis elavultnak tekinthető. A Razor ezzel szemben specifikusan egy view engine-nek lett tervezve, kód-fókuszú html editálást/alkotást mint helyezve előtérbe.

A Razor nagy előnye elődjéhez képest, hogy könnyebb és gyorsabb gépelni, és a pl. C#-hoz szokott fejlesztoknek könnyebben érthető lesz az elkészült View. Emellett a Razor nem használ XML-szerű szintaxist, sokkal inkább hasonlít egy kódfile-re.

  • Kompakt, kifejező: A Razor szintaxisa igen minimalista, figyelembe véve a leütendő billentyűk számát és azt hogy mennyire egyszerű kifejezni a kód mögötti szándékot.
  • Nem egy új nyelv
    Scott Hanselman, a Razor egyik megalkotója így foglalta össze a fejlesztői tapasztalatait:
    “I kept […] going cross-eyed when I was trying to figure out what the syntax rules were for Razor until someone said stop thinking about it, just type an “at” sign and start writing code and I realize that there really is no Razor.”
    A fejlesztők felhasználhatják eddigi tudásukat, és az általános tapasztalatok azt mutatják, hogy a Razorba beletanulás igen rövid időt vesz igénybe.
  • Bármilyen szövegszerkesztőben működik: A Razor nem egy új nyelv, amit meg kell tanulni, egyszerű a szintaxisa (röviden összefoglalva: A fejleszto normál html kódot ír, ha viszont markup helyett .NET-es kódra van szüksége, csak üt egy @ jelet és írhatja is a kívánt kódot). Pont az egyszerűsége miatt nem feltétlenül kell hozzá a Visual Studio-t használni, hogy View-t lehessen írni. Akár notepad-ben is lehet szerkeszteni.

A Razor megalkotásakor az is cél volt, hogy a markup és kód közötti átmenet olyan finom legyen, amennyire csak lehetséges.

Az átmenet jele az "@" lett, mely a kódblokk kezdetét hivatott jelölni.

@{ var items = new string[] {"one", "two", "three"}; } <html> <head> <title>Sample View</title> </head> <body> <h1>Listing @items.Length items.</h1> <ul> @foreach(var item in items) { <li>The item name is @item.</li> } </ul> </body> </html>

A fenti példakód létrehoz egy string tömböt, majd később egy rendezetlen lista elemeit a tömb elemein végigiterálva alkotja meg. A renderelés eredményeként egy rendezetlen lista elemeiként fognak a html oldalban a deklarált tömb elemei megjelenni.

Lehetőség van a .cstml file-okon belül kommenteket elhelyezni, használhatóak a standard HTML komment ( <!-- komment -->), illetve amennyiben szerver oldali kommentet akarunk (mely nem renderelődik bele a Response-ban visszaküldött HTML-be) a kommentet a @* komment *@ formában lehet leírni, hasonlatosan a többsoros /* ... */ kommentekhez.

Természetesen az alapértelmezett Razor és Web Forms engine-eken kívül lehet mást is használni, vagy akár sajátot írni, az IViewEngine ill. az IView interface-ek felhasználásával.

A Model szerepe

A View-ben leképezett/felhasznált adatokat az úgynevezett Model osztályok példányaiban tároljuk. A modell osztály megalkotásakor a fejlesztők rengeteg opció közül választhatnak, a legnépszerűbbek az ORM megoldások, mint pl. az Entity Framework. A Model bármilyen adatforrásból dolgozhat, nem csak relációs adatbázisokból.

A webalkalmazásoknál a leggyakoribb, hogy az alkalmazás felhasznált adatai valamilyen relációs adatbázisban találhatók (Az ASP.NET esetén a legjobb támogatással az MSSQL rendelkezik).
Az ORM egy virtuális objektum-adatbázis, amit kódból tud a fejlesztő könnyen és egyszerűen elérni (pl. az IRepository pattern implementálásával). Az adatok strukturált lekérdezésre szolgál a LINQ.

Validálás

A felhasználó által elküldött adatok elküldésére több opció is rendelkezésre áll. Lehetséges a szerver oldalon egyedi validálási logika implementálása a ModelState objektum, illetve például attributumok felhasználásával.

A View-ben történő validálási üzenetek megjelenítéséhez használható pl. a HTMLHelper .ValidationMessageFor(), vagy a .ValidationSummary() metódusa, mely a View-ben legenerálja a szükséges html elemeket.

Data Annotations

A System.ComponentModel.DataAnnotations névtérben elhelyezkedő attributumok segítségével végezhetünk szerver oldali validálást, emellett a framework támogatja a kliens oldali validálást ezen attributumok használata esetén.

Az attributumok használata:

[Attributum(parameterek)] modosito tipus PropertyNev{ ... }

A fenti névtérben 4 attributum található:

  • [Required]
  • [StringLength]
  • [RegularExpression]
  • [Range]

A System.Web.Mvc névtérben további attributumok találhatóak, pl.:

  • [Remote]
  • [Compare]

Az attributumok nem csak validálásra használhatóak, hanem segítségükkel egyedi logika is implementálható, például a Controller egy Action metódusának végrehajtása elott ellenorizni valamilyen feltételt.

Természetesen a rendszer lehetőséget biztosít egyedi attributum írására is, ehhez egy osztálynak a ActionFilterAttribute osztályból kell származnia és override-olnia kell az OnActionExecuting illetve a OnActionExecuted metódusokat.
Validálási célú attributum esetén érdemesebb a ValidationAttribute-ból származtatni, itt az IsValid metódust kell felülírni.
A System.Web.Mvc névtérben található attributumok a következőek:
  • AcceptViewAttribute
  • ActionFilterAttribute
  • ActionMethodSelectorAttribute
  • ActionNameAttribute
  • ActionNameSelectorAttribute
  • AuthorizeAttribute
  • BindAttribute
  • CustomModelBinderAttribute
  • FilterAttribute
  • HandleErrorAttribute
  • HiddenInputAttribute
  • HttpDeleteAttribute
  • HttpGetAttribute
  • HttpPostAttribute
  • HttpPutAttribute
  • ModelBinderAttribute
  • NonActionAttribute
  • OutputCacheAttribute
  • RequireHttpsAttribute
  • ValidateAntiForgeryTokenAttribute
  • ValidateInputAttribute
Lehetséges olyan model-t is létrehozni, amely önmagát validálja, ehhez a model (vagy ViewModel) osztálynak implementálnia kell az IValidatableObject interface-t