ASP.NET MVC En Dansk e-bog.
|
|
|
- Philippa Bendtsen
- 10 år siden
- Visninger:
Transkript
1 ASP.NET MVC En Dansk e-bog. Over de sidste mange uger har 4 forskellige personer i det Danske udvikler community forsøgt så godt de kunne, at skrive et eller flere kapitler til en e-bog om et nyt web framework ved navn ASP.NET MVC. Det er blevet til ialt 5 kapitler, og de kan alle læses længere inde i bogen. Ideén om at lave en e-bog er slet ikke ny, og der findes endda et utal af dem på internettet. Størstedelen af disse er dog ikke på Dansk, og det var et klart ønske jeg havde inden vi gik igang med at skrive. Faktisk var det under en geekdinner i København jeg først hørte om ideén. Det var Mads Kristensen (BlogEngine.NET) der mente, at en e-bog med emnet performance og optimering i ASP.NET ville kunne danne grundlag for en fantastisk e-bog. Jeg kan kun give ham ret og samtidig takke ham for idéen om, at skrive en e-bog. Desværre er min personlige viden omkring optimering og performance i ASP.NET rimlig begrænset, og jeg håber derfor, at andre kan tage intiativ til at skrive omkring netop dette emne. Der har ikke været en redaktør inde over denne e-bog, og det er med vilje. Jeg har villet have forskellige resultater fra de forskellige forfattere, og det synes jeg bestemt jeg har opnået. Jeg føler deres sprog gør bogen mere charmerende at læse, og samtidig giver det en følelse af, at det hele ikke er formuleret på samme måde. Jeg synes slutresultatet er blevet fantastisk. Jeg snakkede lidt med Nis om, at skulle inkludere et kapitel til Model i bogen, men det blev vi enige om ikke at gøre af den grund, at lade læseren selv tage valget omkring sin egen Model. Hvis bogen påpegede en bestemt model var vi måske lidt bange for, at alle dem der læste bogen ville lave samme model som i bogen, og det er nødvendigvis ikke hvad vi ønsker. Hvis du slet ikke kender til MVC og hvad det står for, så vil jeg forslå at du starter med se dette webcast af Dennis Knappe, downloader de Visual Studio templates der skal bruges samt den nyeste MVC release fra Jeg vil ikke sige mere, bare håbe på at du vil nyde bogen ligeså meget som vi har nydt at skrive den. God fornøjelse.
2 Controllere i ASP.NET MVC Introduktion Som du så i kapitlet om Routing, bruger vi Routing til at bestemme hvilken Controller og Action, der skal bruges til at vise siderne i vores ASP.NET MVC applikation. Controllerens opgave er at sørge for at modtage og håndtere data, og sørge for at korrekte data bliver vist i det rigtige View. En Controller sørger ikke for at generere den HTML som vises i browseren. Det er en opgave der overlades til det korresponderende View. Controlleren skal heller ikke ses som stedet hvor vi udfører forretningslogik eller lignende. En Controller bruges alene til styring af opbygning af UI. Al anden logik skal ligge i vores Model. Når du opretter et nyt ASP.NET MVC projekt i Visual Studio 2008, bliver der oprettet en Controllers folder og to Controllere. De to Controllere er navngivet HomeController og AccountController. Som det er tilfældet i resten af ASP.NET MVC bruger Controllers også i høj grad princippet om konvention over konfiguration. Således også i navngivning af Controlleren der navngives med funktion + Controller. Home bliver altså til HomeController som vist nedenfor i figur 1. Figur 1 - Controller folder i et ASP.NET MVC projekt Oprettelse af en Controller Når vi bygger vores applikation er det selvfølgelig nødvendigt med flere Controllere vi skal gerne have en Controller per område i vores applikation. I det følgende vil vi oprette en BookController. Vi skal bruge BookControlleren til at holde styr på alle vores bøger.
3 For at oprette en ny Controller i Visual Studio 2008, højreklikker vi på Controllers folderen i Solution Explorer, og bliver præsenteret for nedenstående dialog: Figur 2 - Add Controller dialog I dialogen skriver vi navnet på Controlleren, og vi har mulighed for at Visual Studio 2008 automatisk tilføjer metoder (Actions) for de gængse CRUD (Create, Read, Update, Delete) operationer på vores objekt. Actions Når vi nu har kreeret vores Controller, kan vi tage et kig på de forskellige metoder som er blevet oprettet. Disse metoder kalder vi i MVC sprog for Actions. public ActionResult Index() return View(); Den simplest mulige Action er angivet her ovenfor. Som du kan se er der tale om en funktion der ikke tager nogle parametre, og returnerer et View. Når vi kalder denne metode ved at skrive i vores browser, vil vi altså nå frem til denne controller og action, der så vil sørge for at returnere det tilsvarende view der hedder index i folderen Views/Book. Input til Actions Hvis vi kigger videre på nogen af de andre metoder der er blevet autogeneret af Visual Studio har vi f.eks. vores Details View ideen med Details Viewet er at vise alle detaljer for den enkelte bog: public ActionResult Details(int id) return View(); Vi har to måder at angive parametre til vores Action metoder. Den ene er at bruge en Querystring og angive værdien vi ønsker overført til vores Action. Det vil se således ud:
4 Den anden måde at angive parametre på er at bruge Routing, og i ruten angive hvilken del af adressen der er parameteren. F.eks. Vi kan så enten vælge at trække værdien ud af vores URL/Querystring eller vi kan lade ASP.NET MVC om at foretage en automatisk mapning fra querystring route til de parametre som vores Action har brug for. ASP.NET MVC kigger i vores Querystring og Form Collection når den forsøger at lave denne automatiske mapning. Når vi skriver vores Actions kan der også være brug for forskellige Actions afhængigt af hvordan vi kalder vores Action. Hvis vi f.eks. ønsker at tilføje en bog til vores katalog over bøger vil det være naturligt at bruge føgende URL: Nedenfor ser i den tilhørende kode: public ActionResult Create() return View(); Når vi kalder Create første gang ønsker vi altså at få vist et View, hvor vi kan indtaste information om den bog vi gerne vil tilføje. Dette vil typisk ske ved at vi klikker på et link i vores browser. Dette request vil da blive lavet vha. et HTTP GET request. Når vi efterfølgende ønsker at vi gemme værdierne kalder vi igen. Denne gang som HTTP POSTmed værdierne fra vores Create View. For at kunne skelne mellem disse to Actions har vi atributten AcceptVerbs vi kan udsmykke vores Action med. [AcceptVerbs(HttpVerbs.Post)] public ActionResult Create(FormCollection collection) try Book book = new Book(); UpdateModel(book); book.save(); return RedirectToAction("Index"); catch return View(); ModelBinder En anden måde at binde sine data til det indtastede i formen er ved at bruge typestærke Views og ModelBinder. Typestærke Views, for vi ved at sætte Inherits attributten på Viewet til den type som vi ønsker at bruge i vores Controller.
5 Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<pubs.Models.Book>" %> Det næste vi så skal gøre, er at navngive vores html elementer med name attributten. Navnene skal modsvare vores properties på objektet som vist nedenfor. <p> <label for="title">title:</label> <%= Html.TextBox("Title") %> <%= Html.ValidationMessage("Title", "*") %> </p> <p> <label for="publisher">publisher:</label> <%= Html.TextBox("Publisher") %> <%= Html.ValidationMessage("Publisher", "*") %> </p> <p> <label for="id">id:</label> <%= Html.TextBox("ID") %> <%= Html.ValidationMessage("ID", "*") %> </p> Nu kan vi ændre vores input til Create Action, så vi i stedet for at bruge FormCollection, bruger det typestærke Book objekt som parameter. Dette giver os noget meget clean kode, samtidig med at vi kan unit-teste helt uden at vi skal til at mocke en FormCollection eller lignende. Vi kan bare kalde vores Action med et Book objekt. [AcceptVerbs(HttpVerbs.Post)] public ActionResult Create(Book book) try book.save(); return RedirectToAction("Index"); catch return View(); ActionResult Når vores Action metode har udført den tilknyttede logik returnerer vores Action altid et ActionResult. ActionResult kommer i 6 varianter, hver med deres muligheder:
6 [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(int id, FormCollection collection) try Book book = new Book(id); UpdateModel(book); book.save(); return RedirectToAction("Index"); catch return View(); ViewResult Et ViewResult sørger for at rendere et HTML View som bekrevet i kapitlet om Views. Som du kan se i de ovenstående kodeeksempler kalder vi normalt metoden View() på Controller klassen. View har forskellige overloads en tager det data (Model) vi gerne vil vise, men der er også overloads hvor vi kan angive hvilket View vi ønsker at vise. EmptyResult EmptyResult returnerer ingenting fra vores Action. Siger næsten sig selv. RedirectResult Vi bruger Redirects, når vi ønsker at sende brugeren videre til et andet View. Som i eksemplet ovenfor hvor vi vi sender brugeren videre til oversigten når bogen er gemt. Et RedirectResult returnerer til en anden Action på samme Controller. Vi har tre valg for et Redirect, vi kan redirecte til en URL (Redirect(url), vi kan redirecte til en Action (RedirectToAction(action) og endelig kan vi redirecte til helt anden route i applikationen (se RedirectToRoute(route)). JsonResult Et alternativ til en ScriptService i ASP.NET, kan være at bruge et JSONResult på sin Action. Ved hjælp af hjælpemetoden JSON() kan man returnere data i JavaScript Object Notation. JSON er meget kompakt, og bruges i udstrakt grad til AJAX funktioner. JSON understøttes af alle de kendte Javascript Frameworks. Nedenfor kan du se et eksempel på hvordan man kan bruge JSONResult, og resultatet. Du kan læse mere om AJAX og JSON i afsnittet om JQuery og MVC.
7 public ActionResult GetBookAsJSON() Book book = new Book(); book.title = "ASP.NET MVC by Dummies"; book.publisher = "MS"; book.id = 1; return Json(book); //output: "Title":"ASP.NET MVC by Dummies","Publisher":"MS","ID":1 ContentResult Når vi af en eller anden grund ønsker at returnere ren tekst fra vores Actions, kan vi bruge ContentResult. FileResult Du kan let sende binære filer til klienten med ASP.NET MVC. Via hjælpemetoden File() kan du sende filer og MVC giver dig 3 forskellige måder at gøre det på: stien til en fil, et byte array eller med en stream. Du bestemmer selv HTTP content-type, der skal sendes med. ActionFilters En anden smart ting ved ASP.NET MVC er muligheden for at tilføje adfærd til sin Controller ved hjælp af attributter på vores Action. Vi kalder disse attributter for ActionFilters. Som udgangspunkt har vi tre ActionFilters i ASP.NET MVC: Authorize, HandleError og Cache. Authorize Som navnet siger så drejer det sig om at beskytte en Action for uvedkommende adgang. Authorize har forskellige overloads. Vi kan vælge at angive hvilke brugere eller hvilke roller der skal have adgang, alternativt et miks af disse, men vi kan også bare vælge at brugeren skal være autoriseret, det vil sige at vi i Action metoden har adgang til brugernavn etc. [Authorize] public ActionResult ChangePassword() ViewData["PasswordLength"] = MembershipService.MinPasswordLength; return View(); Ovenfor ser vi et eksempel på enkel brug af Authorize. Her ønsker vi bare at brugeren er logget ind inden han får adgang til Action metoden. Nedenfor begrænser vi adgang til bestemte brugere og roller
8 [Authorize(Roles="Administrator", Users="daniel, nis")] public ActionResult ChangePassword() ViewData["PasswordLength"] = MembershipService.MinPasswordLength; return View(); HandleError Et andet ActionFilter er HandleError. Med HandleError kan vi samle ikke håndterede exceptions op, og redirigere til en std. fejlside. Som udgangspunkt vil HandleError kigge efter et View der hedder Error, først i den View mappe der tilhører Controlleren vi har dekoreret med HandleError. Hvis ASP.NET MVC ikke finder viewet her, går den videre til Shared Views. Det er også muligt at filtrere på typen af Exception, og der er også mulighed for at vælge et specifikt View der skal vises når fejlen er opstået. [HandleError(ExceptionType=typeof(NullReferenceException), View="Error")] public ActionResult Create() throw new NullReferenceException(); return View(); For at få HandleError til at virke, skal du enable CustomErrors i web.config, og vel at mærke den rigtige web.config. Et ASP.NET MVC projekt har som udgangspunkt en web.config i roden af sitet, men der er også en web.config i Views folderen. Man skal opdatere web.config i roden af sitet, for at HandleError kommer til at fungere. Cache Et tredje ActionFilter er OutputCache. Som navnet antyder så kan vi bruge OutputCache til at cache resultatet af en metode, i et givet tidsrum. En yderligere finesse ved OutputCache filteret er muligheden for at bruge forskellige VaryBy som f.eks VaryByParam, eller VaryByHeader, så vi sikrer at den mest optimale caching af vores data. [OutputCache(Duration=10)] public ActionResult Index() List<Book> books = Book.List(); return View(books); Opsummering I dette kapitel har vi set hvordan du kan bruge Controllere i ASP.NET MVC. Vi har set hvordan du kan bruge Visual Studio til at oprette Controllere og Actions, og vi har set hvordan du kan angive parametre som input til dine Action metoder.
9 Så kiggede vi på hvordan man returnerer data fra en Controller Action, og hvordan vi kan formatere/vise det returnerede ved hjælp af de forskellige typer af ActionResults.
10 Views I vores gennemgang af ASP.NET MVC er vi nu nået til Views som udgør V et i MVC. Views er præsentationslaget i MVC. Det er her vi lægger vores html skabeloner som skal udfyldes med data og sendes tilbage til brugeren. Man kan sige at views svarer lidt til det vi kender som.aspx filer i ASP.NET WebForms. Faktisk bruger MVC som udgangspunkt den samme skabelon-motor som WebForms, men kan også anvende andre skabelon-motorer som vi skal se på senere. Views bruges altså, når din controller er færdig med at hente og behandle data, og du er klar til at lave den html, som skal sendes tilbage til brugeren. Ofte vil man have et view for hver action metode, der skal returnere html til brugeren og derfor siger konventionen, at man skal navngive sit view efter den action metode som kalder viewet. Hvis en action metode hedder Show så dikterer konventionen at viewet skal hedde Show.aspx. Views understøtter Web Controls og Master Pages, men programmeringsmodellen er anderledes, og man kan ikke bruge alle de Web Controls man kender fra WebForms. Primært kan man sige, at alt hvad der virker uden postback modellen fra WebForms, virker med standard views og kontroller i MVC. Fra skabelon til View En af grundene til at vælge ASP.NET MVC er at man ønsker fuld kontrol over html en i alle de sider der sendes til brugeren. MVC giver dig den frihed og det ansvar og er meget velegnet til, at du som udgangspunkt har lavet en statisk html skabelon som skal gøres dynamisk ved hjælp af MVC. Da MVC understøtter Master Pages, kan vi oprette en sådan og indsætte den faste del af skabelonen, som skal gå igen på flere sider. Derefter kan vi oprette views der svarer til de action metoder, der findes i vores controller klasse. Master Pages En af de gode ting der er bragt med over fra WebForms er Master Page begrebet. Master Pages er en slags layout skabeloner, der typisk indeholder den html, der omkranser din side. I din Master Page vil du oftest have en eller flere steder, hvor det side-specifikke indhold skal indsættes. Disse indsættelsespunkter oprettes i form af <asp:contentplaceholder> kontroller og tildeles navne via ID-attributten på kontrollen. Senere placeres indhold i disse indsættelsepunkter ved hjælp <asp:content> kontroller i de enkelte views som refererer til en navngiven <asp:contentplaceholder> kontrol i Master Pagen. Da Master Pages deles af flere views og flere controllere, skal disse ligge i et særligt område for tværgående skabeloner. Dette er en undermappe til Views mappen kaldet Shared. Her placeres Master Pages og views, som skal bruges flere steder. For at oprette en Master Page højre-klikker du på Shared mappen, vælger Add og derefter New Item.... I den dialogboks der kommer frem, skal du vælge MVC View Master Page og klikke på OK-knappen. Når Master Pagen er oprettet, indsætter vi html fra vores statiske skabelon og fjerner den del af html'en, der ikke skal gå igen på alle sider. Istedet indsætter vi en <asp:contentplaceholder> kontrol således:
11 <asp:contentplaceholder ID="body" runat="server" /> På de views som benytter denne Master Page indsættes html'en i den <asp:content> kontrol således: <asp:content ContentPlaceHolderID="body" runat="server"> <!-- Indsæt html her --> </asp:content> Når vi har vores Master Page på plads, kan vi gå videre til vores views. Placering af Views Alle views i MVC skal ligge under den mappe, der hedder Views i roden af MVC projektet. Under denne mappe oprettes en undermappe for hver controller, der benytter sig af views. Disse undermapper skal hedde det samme som den controller, de indeholder views for. Eksempelvis skal undermappen til en klasse kaldet PostsController hedde Posts. Vores html skabelon skal bruges til at vise et blogindlæg. Hvordan laver vi den om til et view? Lad os antage at controlleren hedder PostsController. Views til PostsControlleren skal da ligge i en mappe kaldet Posts under mappen Views. I PostsControlleren har vi en action metode som viser et blog-indlæg kaldet Show(). Viewet som skal bruges af denne action metode, skal derfor hedde Show.aspx og ligge i mappen Posts. Det er denne konvention, der gør at en action metode selv kan finde det rigtige view, selvom vi blot skriver return View(); i vores action metode. MVC frameworket leder efter et view der passer til action metoden i nogle bestemte mapper i følgende rækkefølge: ~/Views/[Controller navn]/[view navn].aspx ~/Views/[Controller navn]/[view navn].ascx ~/Views/Shared/[View navn].aspx ~/Views/Shared/[View navn].ascx På samme måde finder MVC frameworket frem til partielle views, som vi skal se nærmere på lidt senere.
12 Sådan opretter du et nyt View Der er flere måder at oprette et view på. Lad os kort gennemgå de 2 primære metoder: 1. Hvis du højre-klikker på en controller mappe under mappen Views og, vælger Add og derefter View... så kalder dette en dialogboks frem hvor du kan angive navnet på det view du ønsker at oprette samt andre oplysninger om dette view. 2. Den anden måde at oprette et view på er ved at stille cursoren i en action metode og højre-klikke for at kalde kontekst-menuen frem. I denne menu kan du vælge Add View og Go To View. Her vælger vi Add View og Visual Studio bruger informationer om den kontekst vi står i - her en action metode kaldet Show() - til at foreslå nogle fornuftige default værdier til Add View dialogboksen. Visual Studio opretter også mappen til controller views med det rigtige navn under Views, hvis den ikke findes allerede. Ved at bruge dette værktøj hjælper Visual Studio os med at overholde konventionerne. Uanset om man tilføjer viewet på den ene eller den anden måde så vises følgende dialogboks: Her skal du give dit View et navnet hvis ikke Visual Studio allerede har fundet det rigtige navn via konteksten. Du kan herefter vælge imellem flere forskellige indstillinger, hvor vi her vil koncentrere os om et par af dem.
13 Først og fremmest kan du vælge om dit view skal være type stærkt. At gøre dit view type stærkt vil sige at du angiver en.net type som værende den primære data type, som dette view vil benytte, når data sendes fra controller til view. Hvis vi her vælger en Post type fra et blog system så vil vi på vores view have adgang til en egenskab kaldet Model af den type vi her vælger (i eksemplet af typen Post). Når vi angiver en.net type, får vi adgang til et sæt af skabeloner fra en dropdown-liste. Disse skabeloner gør det let, at oprette simple sider til at liste, redigere og vise data af den type, vi har angivet. På engelsk kalder man disse skabeloner for scaffolding og de er der primært for, at give os et hurtigt skelet til de sider, vi laver. Det er muligt at lave sine egne skabeloner, som vises i denne dialogboks og dermed gøre det let, at oprette flere sider, som skal følge det samme mønster, men med forskellige data typer. Disse skabeloner skrives i et skabelon-sprog kaldet T4 1. Endvidere kan vi i dialogboksen vælge Master Page til vores view og angive hvilken <asp:contentplaceholder> i Master Pagen, der er den primære modtager at indholdet fra vores view. Dit første View I dit view kan du starte med at indsætte den del af den statiske skabelon, som skal være i dit view. Denne del vil vi her, trin for trin, gøre dynamisk. Lad os tage et kig på en simpel skabelon til visning af et blog indlæg. <asp:content ContentPlaceHolderId="body" runat="server"> <div class="post"> <h1>min nye blog</h1> <p class="byline">af Nis, 26. jan 2009</p> <p>lorum ipsum... /p> </div> </asp:content> Hvis vi nu besøger adressen i browseren (f.eks. /posts/show/1) på vores udviklingsweb, ser vi den statiske udgave af vores blog, som nu er sammensat af en Master Page og vores første view page. Selvom dette stadig er en relativ statisk side, bekræfter det os i at tingene er limet rigtigt sammen, og vi kan begynde at tænke på at udskifte statiske dele at skabelonen med data fra controlleren. Data til dit View Vi kan se, at vi skal bruge data fra vores controller så som overskrift, forfatter, dato for indlægget samt teksten, som udgør selve indlægget. Disse data skal være tilvejebragt når viewet skal gøres sit arbejde og vi vil derfor se på hvordan data kan sendes fra controlleren til viewet. Vi har to primære måder at sende data fra controller til view på: 1) Via en dictionary kaldet ViewData som indeholder key-value par hvor nøglerne er at typen string og værdierne er af typen object. 2) Ved hjælp af et type stækt view hvor vi kan sende et objekt med til viewet så længe typen passer til viewet. 1 Læs mere om T4 på adressen
14 Hvis vi benytter os af metode 2, kan vi stadig benytte ViewData til ekstra data, vi måtte have brug for at sende med så det er ikke enten eller. Lad os først se et eksempel på en simpel action metode til at vise et blog indlæg, hvor vi i controlleren benytter metode 1. public ActionResult Show(int id) Post post = BlogService.GetPost(id); if (post == null) return RedirectToAction("Missing"); ViewData["Title"] = post.title; ViewData["CreatedAt"] = post.createdat.tostring("d. MMM yyyy"); ViewData["Author"] = post.user.name; ViewData["Body"] = post.body; return View(); Denne action metode kaldes med id'en på et blog indlæg. Hvis der findes et blog-indlæg med det pågældende id, hældes data fra Post objektet over i ViewData. I viewet kan vi nu rette den statiske udgave til, så den i stedet benytter de data, vi sendte fra vores controller: <asp:content ContentPlaceHolderId="body" runat="server"> <div class="post"> <h1><%= ViewData[ Title ] %></h1> <p class="byline">af <%= ViewData[ Author ] %>, <%= ViewData[ CreatedAt ] %></p> <%= ViewData[ Body ] %> </div> </asp:content> Da de data vi sendte fra controlleren alle var af typen string, kan vi her let udskrive dem uden, at skulle bekymre os om data typen og evt. omformatering til tekst streng. Hvis vi havde sendt Post objektet med via ViewData, havde vi været nød til at caste til Post typen, inden vi fik adgang til Post objektets properties. For at undgå dette kan vi benytte et type-stærkt view i stedet. Først skal vi rette lidt i vores controller: public ActionResult Show(int id) Post post = BlogService.GetPost(id); if (post == null)
15 return RedirectToAction("Missing"); return View(post); Denne blev væsentligt forenklet ved, at vi blot sender Post objektet med i kaldet til vores View. Hvis ikke vores view blev oprettet som type stækt, kan vi ændre dette ved at rette deklarationen øverst i vores view således: <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<TinyBlog.Models.Post>" %> Læg mærke til, at vi i Inherits attributten kan angive hvilken type ViewPage<T> accepter som view data type. Vores view skal således også rettes til for at benytte den Model property, som nu er sat på vores view: <asp:content ContentPlaceHolderId="body" runat="server"> <div class="post"> <h1><%= Model.Title %></h1> <p class="byline">af <%= Model.User.Name %>, <%= Model.CreatedAt.ToString( MMM yyyy ) %></p> <%= Model.Body %> </div> </asp:content> På denne måde har vi let adgang til vores objekt uden, at skulle caste. Data til din Master Page Når vi nu er i gang med at se på, hvordan data sendes til dit view, så lad os også lige se på hvordan data sendes til Master Pages. En Master Page har umiddelbart adgang til den samme ViewData dictionary, som det view der kalder den har adgang til. Det er derfor let at sende data til Master Pagen den vej igennem. Du kan også vælge at gøre din Master Page type-stærk. Her skal du dog tænke dig om, for det begrænser alle de views, der skal benytte denne Master Page til også at være type-stærke med samme type eller en type der er nedarvet fra denne type. Hvis alle dine views benytter sig af særlige view-model klasser som mellemled imellem din controller og dine views, kan du overveje at lave en klasse, som fungerer som base class for alle dine view-model klasser. Denne base class kan indeholde de data, som skal være tilgængelige på alle dine sider. Det er denne base class, som du binder til din Master Page og denne har således kun adgang til de properties, som er defineret på denne base class. Men det er også netop de oplysninger, som går igen på alle sider.
16 Frygten for TagSoup Denne måde at skrive html view logik, hvor html og kode blandes sammen virker på nogle, som et skridt baglæns i forhold til WebForms. Man kan frygte at blandingen af html og kode, ender op med et forfærdeligt rod - også kendt som TagSoup. View i MVC er dog ikke et skridt i den retning. Heldigvis! Det er et spørgsmål om at skille tingene ad sådan som MVC opfordrer til. Når viewet får overdraget kontrollen, skal alle data være tilvejebragt og behandlet. Det eneste der bør foregå i et view er simpel præsentations-logik. Dvs. skal denne knap vises (ja/nej), gentag for alle disse elementer denne html og så fremdeles. Hvis du opdager, at du ofte er nød til at efterbehandle de data, som controlleren sender til dig, kan du overveje at indføre en såkaldt view-model klasse imellem klassen i din domæne-model og dit view. Dit view bindes i stedet for op på view-model klassen og din controller benytter i stedet denne klasse til at sende data til viewet. F.eks. således: // return View(new PostView(post)); Din PostView klasse står herefter for at behandle data fra post objektet så disse er lette at anvende i dit view. Lad os se på et lille eksempel: public class PostView // public string Byline get return string.format( af 0, d. 1:dd-MM-yyyy, _post.user.name, _post.createdat); // Nu kan vi i vores view blot skrive <%= Model.Byline %> for at udskrive forfatter og dato for indlægget. Du bør overveje, om du kan nøjes med at lægge disse hjælpe metoder direkte i domæne model klassen.
17 Partielle views Ofte ser vi at dele af vores html sider går igen på flere sider, men ikke altid er en del af den overordne side opbygning og derfor ikke hører hjemme i en Master Page. I WebForms ville sådan del-sider ofte blive til selvstændige kontroller f.eks. som User Controls. I MVC verdenen kaldes disse ofte for partials. Som navnet antyder, er det netop dele af sider, som ikke skal bruges alene, men som regel kun skal bruges som en del af et view. Et partial view er med andre ord en logisk sammenhængende klump præsentation som skal bruges i flere sammenhænge. Vi så tidligere, at man når man opretter et view, kan vælge om det skal være et partial view. Partial views virker på næsten samme måde som views. Dog kan partial views ikke knyttes sammen med en Master Page hvilket heller ikke giver mening. Med den skabelon-motor som følger med som standard er partial views implementet som User Controls og har derfor fil-endelsen.ascx. Du kalder en partial inde fra dit view således: <div id= postslist > <% foreach (var post in Model) %> <% Html.RenderPartial( SinglePost, post) %> <% %> </div> Bemærk at metoden RenderPartial ikke returnerer resultatet i en tekststreng og du skal derfor ikke skrive <%=, men blot <%. Som du sikkert har bemærket, sender vi eksplicit data med til vores partial view. På det tidspunkt hvor vi kalder vores partial, bør alt data vi skal bruge være loadet og behandlet. Dette gør det let, at følge datas vej igennem applikationen fra det øjeblik, vi modtager en forespørgsel, til vi afleverer et svar til brugeren. Det er også muligt at returnere partielle views fra action metoder. Hertil skal vi blot benytte hjælpemetoden PartialView() i stedet for View() i vores controller. Man kan f.eks. bruge denne hjælpe metode til at svare på AJAX forespørgsler, som forventer at få en stump html tilbage til indsættelse på den side, der oprettede forespørgslen.
18 Views med formularer I WebForms var <asp:form> kontrollen et vigtigt element, som mange andre kontroller afhang af. Derfor var der næste altid en <asp:form> kontrol på de sider man oprettede. I MVC spiller formularer en mindre central rolle, og derfor indeholder views kun <form>-tags, hvis der skal sende data tilbage til serveren. For at oprette en formular i et view kan du enten bare skrive html <form>-tagget og dermed lave formularer sådan, som man nu engang gør i html. MVC ikke gør noget specielt ved din formular er dette en udmærket måde at gøre det på. Der er også en nemmere måde at oprette formularer på. Det er trods alt et meget almindeligt scenarie i en web-applikation. For at lette genereringen af formularen stiller MVC en række hjælpe metoder til rådighed. Her er et eksempel på en simpel login formular: <%= Html.ValidationSummary() %> <% using (Html.BeginForm()) %> <p> <label for="username">username:</label> <%= Html.TextBox("username") %> <%= Html.ValidationMessage("username") %> </p> <p> <label for="password">password:</label> <%= Html.Password("password") %> <%= Html.ValidationMessage("password") %> </p> <p> <%= Html.CheckBox("rememberMe") %> <label class="inline" for="rememberme">remember me?</label> </p> <p><input type="submit" value="log On" /></p> <% %> Dette er let forsimplet version af den login formular som MVC generer til AccountController klassen, som kommer med et nyt MVC projekt. Hvis vi kigger på den html, som bliver genereret af dette view, så ser den dejlig enkelt ud: <form action="/account/logon" method="post"> <p> <label for="username">username:</label> <input id="username" name="username" type="text" value="" /> </p> <p> <label for="password">password:</label> <input id="password" name="password" type="password" />
19 </p> <p> <input id="rememberme" name="rememberme" type="checkbox" value="true" /> <input name="rememberme" type="hidden" value="false" /> <label class="inline" for="rememberme">remember me?</label> </p> <p><input type="submit" value="log On" /></p> </form> Der er ikke masser ekstra html tags og javascript. Den genererede html ser stort set ud som den, vi selv ville have skrevet. Da formularen ikke indeholder fejl i ovenstående version, er alle validerings tags udeladt. Formularen med fejl ser således ud: <ul class="validation-summary-errors"> <li>you must specify a username.</li> <li>you must specify a password.</li> <li>the username or password provided is incorrect.</li> </ul> <form action="/account/logon" method="post"> <p> <label for="username">username:</label> <input class="input-validation-error" id="username" name="username" type="text" value="" /> <span class="field-validation-error">you must specify a username.</span> </p> <p> <label for="password">password:</label> <input class="input-validation-error" id="password" name="password" type="password" /> <span class="field-validation-error">you must specify a password.</span> </p> <p> <input id="rememberme" name="rememberme" type="checkbox" value="true" /> <input name="rememberme" type="hidden" value="false" /> <label class="inline" for="rememberme">remember me?</label> </p> <p><input type="submit" value="log On" /></p> </form> Formularen med validerings elementer indsat ser stadig meget fornuftig ud.
20 Data til din formular Når du benytter de indbyggede hjælpe funktioner til at bygge din html formular, så har det andre fordele end at spare tastetryk. Når du f.eks. benytter hjælpe-funktionen til at udskrive en tekstboks som her: <%= Html.TextBox( Title ) %> Så udfyldes tekstboksen med data hvis MVC kan finde en property kaldet Title på det model-objekt du har tilknyttet viewet. Så ved at benytte disse hjælpe-funktioner kan du let oprette en formular og udfylde den med data fra et objekt. Når formularen sendes tilbage til serveren, er der i controlleren hjælpe-metoder til at hælde data tilbage i objektet, inden du gemmer det i databasen: // var whitelist = new[] "Title", "Body", IsPublished, "CreatedAt" ; UpdateModel(post, whitelist); // Formularer i MVC giver dig fuld kontrol over html en, men kræver til gengæld, at du selv gør en større del af arbejdet med at opbygge html en. Ved at binde properties på dit model-objekt til formular-felter er det let at vise formularen med de rigtige data. Fejler valideringen, vises de data, der blev accepteret igen.
21 Hvis du ikke skal svare med html Nu er html ikke den eneste slags svar en moderne web-applikation skal kunne svare med. Man skal kunne svare på AJAX forespørgsler, lave XML til RSS og f.eks. sende binære filer så som billeder tilbage til brugeren. Af den grund findes der ude over views og partielle views, som vi hidtil har kigget på, også 7 andre view typer som MVC understøtter out-of-the-box. Redirect Efter views nok det mest almindelige resultat fra en action metode. Som navnet siger, bruges Redirect hjælpemetoderne til at redirecte svar til andre metoder eller url er. Der findes 3 Redirect hjælpemetoder som gør det let at redirecte til url (se Redirect()), redirecte til en anden action metode (se RedirectToAction()) eller redirecte til helt anden route i applikationen (se RedirectToRoute()). JSON JSON står for JavaScript Object Notation og er et kompakt data format, som er velegnet til at sende data fra serveren til browseren, som et svar på en AJAX forespørgsel. For at sende JSON data tilbage til klienten kan du benytte Json() hjælpemetoden, hvor du sender de data med som argument f.eks. return Json(post); MVC sørger for at omforme dine data til JSON format. JavaScript Nogle gange kan du have brug for at sende noget javascript kode tilbage til browseren og få denne javascript kode udført på klienten. Til at understøtte dette scenarie kan du bruge JavaScript() hjælpemetoden. Denne metode tager det script, du ønsker at sende som argument f.eks. return JavaScript( alert( Hello world ); ); Content I visse tilfælde er det ren tekst man ønsker at sende tilbage. Her skal du bruge Content() hjælpemetoden. Den tager som argument det tekst, du ønsker at sende til klienten. Du kan også benytte denne til at sende andre tekst formater, som ellers ikke er direkte understøttet af MVC. En af Content() metodens overloads giver dig mulighed for at sætte den HTTP content-type der passer til dit svar. File Du kan let sende binære filer til klienten med MVC. Via hjælpemetoden File() kan du sende filer og MVC giver dig 3 forskellige måder at gøre det på: via en fil sti, et byte array eller via en stream. Også her bestemmer du selv HTTP content-type, der skal sendes med. EmptyResult når der ikke skal sendes noget svar tilbage til klienten. Der findes ikke nogen hjælpemetode til denne type svar, men det er også let uden prøv med return new EmptyResult(); HttpUnauthorizedResult sender en 401 status kode tilbage til klienten om, at adgang er blevet nægtet.
22 ViewEngines Et vigtigt aspekt af ASP.NET MVC er at flere dele af frameworket kan skiftes ud med andre dele efter behov. Således er man ikke tvunget til at benytte den WebForms-baserede skabelon-motor, som MVC kommer med. MVC har et begreb kaldet ViewEngines. En ViewEngine er en motor der styrer views-delen i MVC. Der findes flere forskellige ViewEngines, og det er relativt let at skifte motor på view-delen af MVC. Et af disse alternativer hedder Spark 2. Spark er en ViewEngine som forsøger at blande html og kode på en anderledes og mere elegant måde. For at benytte Spark skal du downloade og udpakke de binære biblioteker til din computer. Herefter kan du tilføje referencer til Spark.dll og Spark.Web.Mvc.dll i dit ASP.NET MVC projekt. Til sidst skal du fortælle MVC, at den nye ViewEngine skal bruges. Dette gøres lettest i Global.asax i metoden Application_Start(). Her tilføjer du linien: ViewEngines.Engines.Add(new SparkViewFactory()); Fra nu af vil MVC ikke blot søge efter Show.aspx og Show.ascx i dine View mapper. Den vil også søge efter Show.spark. Så hvis du opretter en Show.spark kan du afprøve om denne alternative skabelonmotor, er noget for dig. Her er et eksempel på Spark html: <var names="new [] 'alpha', 'beta', 'gamma'"/> <for each="var name in names"> <test if="name == 'beta'"> <p>beta is my favorite.</p> <else/> <p>$name is okay too I suppose. </test> </for> Se flere eksempler på Sparks hjemmeside. 2 Læs mere om Spark på adressen
23 Jquery og ASP.NET MVC Jquery er et open source JavaScript bibliotek som Microsoft har besluttet at pakketere sammen med bla. ASP.NET MVC. Det vil sige, at når du fra Visual Studio opretter et nyt MVC projekt så ligger Jquery i Scripts mappen af dit projekt. At inkludere et open source projekt i et Microsoft produkt er noget helt nyt, og sender et signal om, at Microsoft gerne vil støtte op og kontribuere til noget de ikke selv har fundet på eller udviklet. I Scripts mappen ligger somsagt Jquery, og biblioteket er allerede blevet minificeret for at efterlade et så lille fodaftryk som muligt (min versionen). Selvom Jquery allerede er minificeret, kan du gøre din applikation endnu mere perfomance optimeret. Ved at refere til en Jquery fil der ligger hos Google Code, kan du dele en Jquery reference med mange andre udviklere, og på den måde reducere fodaftrykket yderligere overfor dine brugere. Du finder Google s Jquery reference her: Men det er vigtigt, at du forstår at Jquery intet har med Microsoft at gøre og du kan ikke finde noget dokumentation på nogle af Microsofts hjemmesider. Javascript i nye klæder? Internettet er en forholdsvis ung ting, ihvertfald i forhold til meget andet. Når noget er så nyt som internettet, så skal brugerne af det, af naturlige årsager, afprøve dets egenskaber og muligheder. Man kan roligt sige at JavaScript er blevet afprøvet (måske også mishandlet) igennem de sidste 15 år med internettet. Om det har været brugt til noget fornuftigt eller ej kan vel diskuteres, men prøv at husk tilbage på 90ernes hjemmesider med snevejr, musik og blinkene menuer. Det svarer til nutidens MySpace hjemmesider som mange sikkert vil syntes er forvirrende. I take med at internettet er blevet mere modent, er vores brug af JavaScript også blevet mere fornuftigt. Idag er nettet blevet til en stor fælles platform hvor den gennemsnitlige computer-bruger tilbringer det meste af sin tid. Derfor har det været nødvendigt at stabilisere platformen på alle mulige måder, og det har de sidste mange år (og den dag idag) betydet at vores applikationer skal være mere enkle og brugervenlige (læs: web 2.0). Jquery har i sin rolle som et meget enkelt JavaScript bibliotek, en rolle i denne modningsproces.
24 JavaScript kan bruges til rigtig mange ting, og det er uhyre magtfuldt sprog. Men ofte er det blevet brugt steder hvor en anden teknologi måske ville have været at fortrække, og det tidligere overforbrug af JavaScript har skadet sprogets ry en smule. Idag er JavaScript blevet in igen, bare i en enklere form. Dette skyldes at flere forskellige: nogle har uafhængigt af hinanden, bygget en abstrakion oven JavaScript, og på den måde lavet et pænt og nemt bibliotek man kan benytte sig af istedet for scripte direkte i JavaScript. Der findes mange andre javascript abstraktioner såsom Moo Tools, Prototype og Fork. Jquery ér JavaScript i nye klæder og open source bibliotektet har virklig gjort det super nemt for alle udviklere, at lave fede og stilede features på. Det er også blevet meget nemmere at f.eks at til HTML ens DOM på. HTML DOM en (Document Object Model) er den HTML model vi får stillet til rådighed vi dynamisk kan programmere op imod. Jquery muliggør dette på en meget elegant måde, nemlig via CSS Selectors. CSS selectors bør være kendt for storts set alle webudviklere, og hvis du ikke kender navnet, så kender du højst sansynligt syntaksen. Jquery: Selectors I dette korte eksempel ser vi hvordan vi meget nemt kan få fat i det tag vi har givet navnet ptext : <p id="ptext"> Hej Jquery! </p> <input type="button" onclick="changecss('ptext', 'redtext');" value="skift farve" /> Jeg har oprettet en fil ved navn functions.js og lagt den i Scripts mappen. /// <reference path="jquery vsdoc.js" /> function changecss(selector, css) $("#" + selector).addclass(css); Jeg har selvfølgelig tilføjet en reference i MasterPage en til både vores functions.js fil og Jquery fil jquery min.js. I normal JavaScript kunne det samme eksempel se nogenlunde således ud: function changecss(selector, css) var element = document.getelementbyid(selector); element.setattribute("class", css);
25 Det er måske ikke den store forskel, men vi behøver ikke taste så meget i Jquery. Lad <table os se på class="datatable"> et andet eksempel med Jquery selectors: <tr> <th>film</th> <th>skuespiller</th> </table> </tr> <tr> </tr> <tr> </tr> <tr> </tr> <td>rocknrolla</td> <td>nonso Anozie</td> <td>rocknrolla</td> <td>charlotte Armer</td> <td>lakeview Terrace</td> <td>samuel L. Jackson</td> Som vi kan se har vi navngivet vores tabel datatable. Nu kan vi, ligsom i det foregående eksempel, nemt få fat i tabellen med Jquery. Lad os sige, at vi gerne vil sætte en baggrundsfarve på hver anden række i tabellen. Det er ligetil med Jquery. Vi ligger en nye funktion ind i vores functions.js fil og tilføjer en CSS klasse i MasterPage n på vores projekt. $(document).ready(function() $(".datatable tr:odd").addclass("alternate-row"); ); Læg mærke til at vi først ønsker at køre denne funktion når vores dokument er færdigt med loade vores DOM. I eksemplet spørger vi på alle de elementer i vores HTML der har datatable som klasse (.datatable). Derefter hiver vi fat i alle underliggende tr tags, vælger de ulige(tr:odd) og sætter en klasse (alternaterow) på dem vi finder. Hvis du spørger mig, så er dette kode både elegant og uhyre simpelt at forstå! Jquery : Ajax Asynkron JavaScript og XML (Ajax) er måske nyt i nogen udvikleres øre, men det er bestemt ikke et nyt koncept, og måske kender du allerede. Ajax er hvad vi for 10 år siden (eller deromkring) kendte som remote scripting. Idag arbejder diverse Ajax biblioteker sammen med XMLHTTPRequest objektet der ligger i alle velkendte browsere. Ajax går i al sin enkelthed ud på at lave ens applikation eller side mere jævn i forhold til brugervenlighed for bruger oplevelse. Forstil dig, at hvis du f.eks trykker på en knap der skal opdatere en
26 nyhedsliste på en side, så kræver det( behind-the-scenes ) muligvis, at jeg snakker med en database og sender noget data frem og tilbage over ledningen. Det samme gør sig gældende med Ajax bortset fra at brugeren ikke ligger mærke til den velkendte opdatering af en side (page-refresh) og på den måde ikke taber fokus fra siden. Jquery understøtter også Ajax kald, og ligsom meget af det andet i Jquery, så er det supernemt at fortage. Lad os tage et simpelt eksempel til at starte med. Når jeg trykker på knappe nedenstående vil jeg gerne hente nogle navne i en anden fil. Dette kan jeg gøre helt smertfrit med Ajax og Jquery. <span>navne:</span> <p id="names"> </p> <input type="button" id="getnames" onclick="getnames();" value="hent navne" /> I functions.js filen har oprettet en function der ser således ud: function getnames() $("#names").load("/home/viewpage1"); Jeg har oprettet et View der ser såldes ud: <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %> Daniel Jesper Nis Nikolaj Og på home controlleren har jeg ligeledes oprettet en metode der kan servere vores view. public ActionResult ViewPage1() return View(); Uden at vi ligger mærke til det, bliver navnene fra ViewPage1 viewet loadet ind i vores p fra det kalende view. Lad os se på et mere advanceret eksempel med Ajax og Jquery. Lad os sige vi skal lave rating funktion af et forum spørgsmål, alt efter hvor godt du synes indlægget er kan du give god eller dårlig rating. Vores Jquery funktioner ser således ud:
27 function rateup(messageid) var status; $.ajax( url: " + messageid, success: function(response) status = response; $("#ratingcount" + messageid).text(status);, error: function(xhr) alert(xhr.status); ) function ratedown(messageid) var status; $.ajax( url: " + messageid, success: function(response) status = response; $("#ratingcount" + messageid).text(status);, error: function(xhr) alert(xhr.status); ) rateup og ratedown tager begge en enkelt parameter som argument; messageid. Dette er forum beskedens id som brugeren har valgt at stemme på. Ved hjælp af ajax i Jquery laver vi en funktion der skal tage sig af det response der kommer tilbage hvis operationen gik godt (success). Ligeledes er der i begge funktioner lavet en funktion der giver brugeren besked hvis en fejl måtte opstå. Hvis operationen har været en success opdatere vi text egenskaben på et p tag via ( ratingcount + messageid). Alt dette sker uden at brugeren lægger mærke til det og det er med til at gøre applikationen mere jævn og brugervenlig.
28 Jquery : Plugins En af de rigtig smarte ting ved Jquery, er plugin modellen ved bibliotketet. Det er meget nemt at tilføje ekstra muligheder Jquery, så hvis du måtte have brug for det, kunne du f.eks benytte dig af plugins andre havde skrevet. Der findes et utal af plugins på nettet og på Jquery.com finder du et plugin repository der er inddelt i kategorier. Jquery dokumentation Du finder hele dokumentationen for Jquery på hjemmesiden og jeg vil forslå at du går igennem API referencerne for at få et indblik hvad der ellers er muligt med Jquery.
29 Routing i ASP.NET MVC Hvilken route skal vi tage? Inden vi kaster os over hvordan vi kan definere vores egne router, og få en forståelse for hvordan og hvornår man gør det, så skal vi hurtigt lige have slået fast hvad en route gør og hvordan den egentligt virker. Routing i ASP.NET er både fleksibel og nem at administrerer. Når et request kommer ind til ens MVC website, holder MVC frameworket requestet op imod de route-regler der er beskrevet i vores applikation, og bestemmer efterfølgende hvilken controller der skal kaldes. Routes er som standard let-læselige (/Produkt/Biler/Audi/RS6) og man kan selv bestemme hvordan man øsnker de skal forme sig. Dette gør sig gældende for både ind og udgående url er. Global.asax og routes I global.asax filen på et standard ASP.NET MVC projekt er der defineret nogle routes som dit website vil opføre sig udfra. Som standard ser Global.asax filen således ud når du har oprettet et net MVC projekt fra Visual Studio eller Visual Web Developer public class MvcApplication : System.Web.HttpApplication public static void RegisterRoutes(RouteCollection routes) routes.ignoreroute( "resource.axd/*pathinfo" ); routes.maproute( "Default", "controller/action/id", new controller = "Home", action = "Index", id = "" ); protected void Application_Start() RegisterRoutes( RouteTable.Routes ); Som du kan se er der pr. default allerede skrevet en route og den kan vi lige studere lidt nærmere. I vores RegisterRoutes metode er der tilføjet en route til vores website.
30 routes.maproute( "Default", "controller/action/id", new controller = "Home", action = "Index", id = "" ); Her angiver vi, at vores route skal hedde "Default" og pr. default skal den mappes til controlleren "Home" og den controller action ved navn "Index". Se bort fra "Id" delen af reglen lige nu, og tænk på vores routes som værende simple url regler som vores site sidenhen vil bruge til at lave nemme og letlæslige urler. Hvis vi åbner Home controlleren i Controller mappen, så kan vi se at der allerede ligger en metode ved navn "Index". Det er denne metode vi lige har mappet til pr. default fra vores global.asax fil, og som man rammer hvis man åbner hjemmesiden (roden) med en browser. Lad os prøve at åbne et browser vindue og indtaste (6087 er et port nummer jeg bruger, det skal du selv udskifte til dit eget, eller evt. trykke F5). Der skulle meget gerne komme en side frem der ser nogenlunde således ud. Vi står lige nu i roden af vores website, og den rod er bestemt udfra den "Default" route vi har angivet i vores Global.asax fil. Grunden til at vores regel virker er, at vi har hardcodet, at vi pr. default gerne vil have fat i "Home" controlleren og "Index" action metoden i "Home" controlleren. Hvis du prøver at åbne vil du få samme resultat, og hvis du så prøver at åbne vil du ligeledes se samme side. Det sidste eksempel er for at demonstrere at vores route regel også kan godtage et id. De regler vi her har kigget på stemmer fuldstændig overens med den ene regel vi har opsat i vores Global.asax fil. Hvis vi lige hurtigt kigger tilbage på vores "Default" route igen, så kan vi se at den også tillader en "Id" parameter i vores url. Hvis vi prøver at ændre i vores route kan vi se, at vi faktisk ikke behøver en "Id"
31 parameter i vores regel for at kunne kalde default siden i vores MVC projekt. Bare husk at routes er regler for de urler vi kan bruge imod vores website. routes.maproute( "Default", "controller/action", new controller = "Home", action = "Index", ); Nedenstående route fejler fordi frameworket ikke kan finde en route der matcher det indgående request ( routes.maproute( "Default", "controller/action/id", Hej new controller = "Home", action = "Index", ); Nedenstående route virker, men "Id" parameteren kommer ikke med over i controlleren, så den er ubruglig: routes.maproute( "Default", "controller/action", new controller = "Home", action = "Index", id = "id" ); Vi beholder lige routen selvom den er ubruglig. Så prøver vi derimod at åbne HomeControlleren fra Controller folderen, og laver Index metoden om, så den rent faktisk tager en parameter, og ja, så er routen ikke længere ubruglig. public ActionResult Index(string id) ViewData[ "Title" ] = "Home Page"; ViewData[ "Message" ] = "Velkommen til ASP.NET MVC"; ViewData[ "Id" ] = id; return View();
32 Alt starter med en route i din Global.asax fil og du skal ikke være bekymret for at lave for mange router i Global.asax. Mange url's ligner hinanden og du kan derfor ofte generalisere, da det er dig selv der bestemmer hvordan du vil have dine requests skal se ud. F.eks routes.maproute( "Default", "controller/action", new controller = "Home", action = "Index", ); Denne route passer på alle de requests der ser således ud: Så vi kan f.eks spørge på: Alle disse url's (og flere til) matcher den samme route regel. Vi har en controller der hedder Home og vi har en controller der hedder Account. Disse controllers har hver deres action metoder (Login, Register og About), og hver af disse passer til ovenstående route regel. Det er et absolut must at have sine mest specielle regler liggende i toppen af sin global.asax fil og de mest generelle i bunden. Dette skyldes, at reglen uanset hvad, vil blive taget i brug hvis den matcher requestet. routes.maproute( "Default", "controller/action", new controller = "Home", action = "Index", ); routes.maproute( "Search", "Search/Keyword", new controller = "Search", action = "SearchByKeyWord" ); Hvis jeg kalder Url'en hvilken route bliver så taget i brug? Det gør den første route i global.asax! Men eftersom den første regel bliver taget i brug kigger applikationen efter
33 en controller der hedder "Search" og en action der hedder "PillerGoj". Actionen "PillerGoj" findes ikke og vi får derfor en bummer! routes.maproute( "Search", "Search/Keyword", new controller = "Search", action = "SearchByKeyWord" ); routes.maproute( "Default", "controller/action", new controller = "Home", action = "Index", ); Når vi rykker vores mere generelle route ned i bunden af siden, så virker vores search route som forventet. Det skal man selvfølgelig lige vænne sig til :0) routes.maproute( "Products", "product/product/subproduct/action", new controller = "Product", ); Ovenstående vil mappe til en "product" controller og i den ligger en action... public ActionResult GetNewest(string product, string subproduct) ViewData[ "Title" ] = String.Format( "Get the newest products in 0/1", product, subproduct ); return View(); I vores route mapper vi vores action som det sidste i vores regel og derfor kan vi lave en Url der ser således ud: product = controller hifi = product (parameter i action metoden) accessories = subproduct (parameter i action metoden) GetNewest = action Ovenstående regel kan du ligge i toppen af global.asax filen da den er ret speciel :0) I vores GetNewest Action bliver der sendt 2 streng argumenter med, men vi kan faktisk selv styre hvilken type disse parametre skal have med. Se f.eks på denne route:
34 routes.maproute( "Default", "controller/action/id", new controller = "Home", action = "Index", id = typeof(int) ); I denne route specificere vi, at vores id er af typen int. Dette betyder at vi i vores Action nu kan skrive: public ActionResult Index(int? id) ViewData[ "Title" ] = "Home Page"; ViewData[ "Message" ] = "Velkommen til ASP.NET MVC"; ViewData[ "Id" ] = id.value; return View(); Læg dog mærke til, at jeg benytter mig af en nullable int. Dette skyldes, at jeg ville få en fejl hvis jeg bare brugt en normal int. Prøv selv at skift typerne ud og se hvad der sker Routes i databasen Der kan være fordele ved at lægge sine routes i en database frem for i sin global.asax fil. Hvis du skal tilføje en route i.asax kræver det en rekompilering når du skal deploye den og det kan være ufedt i et størrer system. En anden grund kan være tilgængelighed; måske er det ikke kun udviklere der skal kunne bestemme router i ens applikation. Jeg har lavet en simpel tabel i min database.
35 public static void RegisterRoutes(RouteCollection routes) using (MvcBasics.WebRoutesDataContext ctx = new WebRoutesDataContext()) var ignoreroutes = ( from r in ctx.routes where r.ignore == true select r ).ToList(); foreach (var item in ignoreroutes) routes.ignoreroute( item.url ); var webroutes = ( from r in ctx.routes where r.ignore == false orderby r.sortindex descending select r ).ToList(); foreach (var item in webroutes) routes.maproute( item.name, item.url, new controller = item.defaultcontroller, action = item.defaultaction ); Direkte i RegisterRoutes har jeg lavet et kald på LINQ SQL model som napper alle de router jeg har defineret i databasen. Hver gang vi støder ind i en af de registrere router i databasen, opretter vi en ny route i vores applikation og sætter samtidig de fornødne egenskaber på routen. Router alle andre steder Generelt vil jeg mene man er rimlig godt tjent med at have sine router i Global.asax filen. Man skal passe på med at lade alle give mulighed for at tilføje eller ændre i disse route-regler, af den simple grund, at det kan knække din applikation. Det kan selvfølgelig også ske med en Global.asax fil, men det er ikke hvem som helst der bør hvad adgang til den. Forstil dig nogle har slettet dine route-regler fra databasen og du skal til at finde ud af hvad der mappede til hvad. Dette må være en pinsel. Andre resourcer Se bla. Phil Haacks URL Routing Debugger som kan bruges til, at teste ens routes med.
36 HTML helpers i ASP.NET MVC En vigtig del af at lave web applikationer består i, at skrive noget HTML der kan præsentere grafik, formularer osv. I traditionelle script sprog som PHP og ASP er man pr. Default nødsaget til at skrive denne HTML selv. Det er der på ingen måde noget i vejen for, men det kan dog hurtigt blive trættende, at skulle skrive så meget markup kode for at opnå så lidt. I WebForms frameworket af ASP.NET findes der en stor mændge kontroller. Nogle mere brugbare end andre og nogle skal man pr. Definition bare holde sig fra. Stort set samtlige kontroller i WebForms er fyldt med store ugennemskuelige klasser, events og en masse andet snask, som en generel udvikler ikke nødvendigvis gider bekymre sig om når han skal udvikle. I WebForms har du mulighed for at trække et vilkårligt antal kontroller ind i din HTML kode. Ved at attributerer kontrollen med en ID parameteren får du programmel adgang til kontrollen, dens state osv. Det er i sig meget smart, men det har i visse situationer vist sig at være svært, at forme disse kontroller som man gerne vil have dem til at se ud og opføre sig. Dermed ikke sagt at man skal holde sig fra WebForms, for det havde i allerhøjeste grad stadig sin beretning, men man skal overveje hvor man vil bruge det. Eftersom MVC frameworket ikke understøtter ViewState, ligsom WebForms gør, så vil jeg på krafigste anbefale ikke at du ikke bruger ViewState kontroller fra WebForms frameworket. Hvis du f.eks forsøger, at bruge Click eventen på Button kontrollen fra WebForms frameworket i dit MVC projekt, vil du få nedenstående fejl. Det er ikke svært at leve uden ViewState, tværtimod! Back to Basics? I modsætning til WebForms stiller MVC frameworket en række HTML hjælpe metoder til rådighed. Du tilgår de forskellige hjælpe metoder ved hjælp af HtmlHelper klassen på dit view instans. Denne hjælpe klasse
37 indholder funktionalitet til at opbygge det mest basale HTML med. Ikke pragraffer eller div tags, men kontroller såsom knapper, tekst bokse, formularer osv. <form method="post" action="<%=url.action("save", "Blog") %>"> <input type="text" name="first_name" /> <%=Html.TextBox("last_name") %> </form> Ovenstående viser hvordan man kan tage HTML hjælpe klassen i brug. Vi bygger 2 tekst bokse, hvor den ene er oprettet direkte i HTML, den anden med HtmlHelper klassen. Resultatet af disse to måder er ens, bortset fra deres navne. <form method="post" action="<%=url.action("save", "Home") %>"> <%=Html.TextArea( "textmessage", null, 5, 40, = = "color:#336699;" )%> </form> Ovenstående definere vi et textarea med nogle forskellige parametre. Bemærk vi i med den valgte overload kan sætte et vilkårligt antal attributer på vores textarea. Dette gøres simpelthen ved at give et objekt med som parameter (new ). Dette objekt indholder henholdsvis navnet på attributen og værdien af denne. I dette tilfælde style og class. Nedenstående er listet nogle af de mest brugte metoder på HtmlHelper klassen. Html.ActionLink o Laver et link til en given Controller Action, ud fra den controller og action du angiver. Den kigger efter dine routes i din global.asax, så du på den måde altid får et link som peger til den action, selvom url en skifter. Html.BeginForm o Starter et HTML-Form tag, som sender sine resultater videre til en controller action. Denne metode bruger også funktionaliteten med dynamiske ruter, så den automatisk finder frem til URL en ud fra controllerens navn og action. Html.DropDownList o Laver en dropdown list ud fra en såkaldt SelectList, som er en specelt form for collection. Denne metode gør det let, f.eks. at vise virksomhedens ansatte i en dropdownlist Html.RenderPartial o Rendere et såkaldt partial view. Denne kan sammenlignes med User Controls fra ASP.NET Webforms. Dette partial view, deler ViewData med hovedviewet, eller kan få en delmængde af ViewData en sendt med. Html.TextBox o Opretter en textbox, som får det name som er angivet. Denne metode er især brugbar, da MVC understøtter sit eget valideringssystem, hvor den automatisk gør denne tekstbox rød, hvis indholdet ikke er valid.
38 Html.ValidationSummary o Viser resultatet af valideringen for brugeren, hvis der bruges det indbyggede valideringssystem Lad os se på hvordan vi kan lave simpel validering med MVC framworket og en HtmlHelper klassen. Vi laver følgende HTML og tager HtmlHelper klassen i brug forskellige steder. <% using (Html.BeginForm<HomeController>( c => c.index( "" ), FormMethod.Post )) %> <span>navn: </span> <br /> <%=Html.TextBox( "name" )%><br /> <br /> <%=Html.ValidationMessage( "name" )%><br /> <br /> <%=Html.SubmitButton( "save", "Gem" )%> <% %> Det eneste vi skal gøre for at få validering på denne simple formular er, at tjekke for om værdien vi sender med over det vores controller, er som vi ønsker. Dette gør vi i vores controller action som ser således ud. [AcceptVerbs( HttpVerbs.Post )] public ActionResult Index(string name) if (String.IsNullOrEmpty( name )) ViewData.ModelState.AddModelError( "name", "Udfyld navn" ); if (ViewData.ModelState.IsValid) //Opret navnet et sted, evt. databasen. return RedirectToAction( "created" ); else return View(); Hvis name parameteren er tom tilføjer vi en fejl besked til vores ModelState objekt på ViewData og returnere samme view som vi kom fra. Viewet finder pr. Automatik ud af, at der er en fejl i ModelState objektet, og vi kan efterfølgende skrive fejl ud til browseren.
39 Udvid HTML funktionaliteten Da vi ikke har en kontrolmodel ligsom i ASP.NET Webforms, og størstedelen af HtmlHelper metoderne samtidig returnere strenge, giver det en nem mulighed for at udvide funktionaliteten med sine egne metoder. Mange ASP.NET Webforms udviklere har aldrig udviklet sin egen kontrol, fordi det simpelthen er for komplekst. I MVC er det som sagt blot en metode som retunere en streng. public static class MyHtmlHelperExtentions public static string GravatarImage(this HtmlHelper html, string ) //Gravatar skal bruge en MD5 hash af en string hash = FormsAuthentication.HashPasswordForStoringInConfigFile( .tolower(), "MD5" ); //Vi bygger URL'en string src = " + hash.tolower() + "?s=48&d=wavatar"; //Vi retunere en IMG-tag med url'en til billedet return string.format( "<img src='0'/>", src ); Vi kan kalde vores egen HtmlHelper extension metode ligsom vi plejer. <%=Html.GravatarImage("[email protected]")%> At kunne udvide standard HtmlHelper klassen med sine egne metoder er rigtig smart og kan give rigtig mange fordele. Men det skal også siges, at extension metoder skal bruges med omhu, derfor vil jeg anbefale dig, at tænke dig om før du implementere mange forskellige extension metoder på HtmlHelper klassen. Der er dog en ting du skal gøre manuelt for dine egne extension metoder virker helt efter hensigten. Du skal huske at inkludere det namespace de nu engang er oprettet under. Du kan tilføje namespacet til det pågældende view du arbejder med eller over hele applikationen. Det sidste er bestemt at fortrække og det gøres ved at tilføje dit namespace til namespace tagget under system.web -> pages. <namespaces> <add namespace="system.web.mvc"/> <add namespace="system.web.mvc.ajax"/> <add namespace="system.web.mvc.html"/> <add namespace="system.web.routing"/> <add namespace="system.linq"/> <add namespace="system.collections.generic"/> <add namespace="demoapp.models"/> </namespaces> Jeg vil ligeledes anbefale dig at holde øje med Codeplex.com for opdateringer omkring ASP.NET MVC, og især den release der kaldes MVC Future. Releasen består af en enkelt DLL fil som indeholder yderligere
40 funktionalitet på bla. HtmlHelper klassen. I skrivende stund kan du finde det her -
41 Forfatterne Daniel Mellgaard Frost, Developer Evangelist hos Microsoft Danmark. Nis Wilson Nissen, BookingStudio udvikler hos Knappe&Kragh. Nikolaj Winnes, Konsulent hos Legayo Consulting ApS. Jesper Blad Jensen, Udvikler hos Hedal Kruse Brohus A/S. Vil du gerne have en præsentation eller mere dybdegående kendskab til MVC Frameworket, kan du tage kontakt til en eller flere af ovenstående personer.
Dokumentering af umbraco artikeleksport:
Dokumentering af umbraco artikeleksport: Lav en artikel side 2-3. Installationsguide side 3-5. Opsættelse af databasen og web.config side 5-8. Umbraco: templates side 8. Umbraco: borger.dk tab side 8.
Procesbeskrivelse - Webprogrammering
Procesbeskrivelse - Webprogrammering Indholdsfortegnelse Forudsætninger... 1 Konceptet... 2 Hjemmesiden... 2 Server-side... 3 Filstrukturen... 3 Databasehåndtering og serverforbindelse... 4 Client-side...
Gem dine dokumenter i BON s Content Management System (CMS)
24. august 2007 Gem dine dokumenter i BON s Content Management System (CMS) INDHOLDSFORTEGNELSE 1. Indledning... 2 2. Se indholdet i dit Content Management System... 3 3. Tilgå dokumenterne i My Content
Umbraco installationsvejledning
på et ScanNet ASP Webhotel Indledning Beskrivelse Denne vejledning vil indeholde installation af CMS systemet Umbraco på et ASP Webhotel. Det dansk grundlagt Content Management System (CMS) Umbraco er
PHP 3 UGERS FORLØB PHP, MYSQL & SQL
PHP 3 UGERS FORLØB PHP, MYSQL & SQL Uge 1 & 2 Det basale: Det primære mål efter uge 1 og 2, er at få forståelse for hvordan AMP miljøet fungerer i praksis, og hvordan man bruger PHP kodesproget til at
Dokumentation. Udbyder : sms1919.dk Service : sms-grupper Static FBML Facebook. : Facebook Integration med sms-grupper.
Dokumentation Udbyder : sms1919.dk Service : sms-grupper Static FBML Facebook Moduler Påkrævet : Facebook Integration med sms-grupper Version : v1.00 Indholdsfortegnelse Versionshistorik... 3 Målet med
Database for udviklere. Jan Lund Madsen PBS10107
Database for udviklere Jan Lund Madsen PBS10107 Indhold LINQ... 3 LINQ to SQL og Arkitektur... 3 O/R designere... 5 LINQ Den store introduktion med.net 3.5 er uden tvivl LINQ(udtales link): Language-INtegrated
Brugervejledning til Design Manager Version 1.02
Brugervejledning til Design Manager Version 1.02 Indholdsfortegnelse 1. Introduktion... 3 1.1 Det kan du med HostedShop Design Manager... 3 1.2 Feature list... 3 2. Design... 4 3. Filer og CSS... 4 3.1
3) Først og fremmest kan du vælge hvilket tema din side skal have.
Wordpress er et open source software du kan bruge til at oprette blogs og hjemmesider i. Du har mulighed for at vælge forskellig temaer og designe din side som du har lyst. Blogs og hjemmesider kan blandt
ASP.NET MVC Framework - en del af ASP.NET 3.5 Extensions
ASP.NET MVC Framework - en del af ASP.NET 3.5 Extensions Captator Tlf: 8620 4242 www.captator.dk Carsten Juel Andersen Softwarearkitekt [email protected] Mobil: 2348 0003 februar 2008 ASP.NET MVC Framework
Advanced Word Template Brugermanual
Advanced Word Template Brugermanual Forord: Advanced Word Template er et værktøj, der anvendes sammen med Microsoft Word til at opbygge ensartet beskrivelser på en mere intelligent måde end Copy and Paste
PHP Quick Teknisk Ordbog
PHP Quick Teknisk Ordbog Af Daniel Pedersen PHP Quick Teknisk Ordbog 1 Indhold De mest brugte tekniske udtryk benyttet inden for web udvikling. Du vil kunne slå de enkelte ord op og læse om hvad de betyder,
Hvorfor skal vi bruge objekt orienteret databaser?
OODBMS Vs. RDBMS 1 Indholdsfortegnelse Hvorfor skal vi bruge objekt orienteret databaser?... 3 OODBMS i erhvervslivet... 4 Bagsiden af medaljen... 5 OODBMS i praksis... 6 Konklusion... 8 2 Hvorfor skal
vorbasse.dk Redaktørmanual Kentaur
Redaktørmanual Kentaur Indholdsfortegnelse Kapitel 1 - TYPO3 Brugerfladen 3 Log ind 3 Backend 4 Frontend 5 Hvor skal jeg klikke? 5 Gem, gem og vis, gem og luk 6 Kapitel 2 - Sider & menuer 7 Sammenhæng
Det Naturvidenskabelige Fakultet. Introduktion til Blackboard (Øvelser) Naturvidenskabeligt Projekt 2006 Prøv at forske
Det Naturvidenskabelige Fakultet Introduktion til Blackboard (Øvelser) Naturvidenskabeligt Projekt 2006 Prøv at forske Indholdsfortegnelse Introduktion til Blackboard Content System...3 Øvelse 01 individuel:
PHP Snippets. De små korte. Skrevet af Daniel Pedersen
PHP Snippets De små korte Skrevet af Daniel Pedersen Indhold PHP Snippets De små korte er en samling af små og praktiske kode eksempler med kort forklaring, som med formål at kunne benyttes til opsalgsværk
Indholdsfortegnelse. Hvorfor skal jeg tage backup af min blog? Side 3. Tag backup med UpDraft Side 4. Tag manuelt backup Side 8 - 2 -
- 1 - Indholdsfortegnelse Hvorfor skal jeg tage backup af min blog? Side 3 Tag backup med UpDraft Side 4 Tag manuelt backup Side 8-2 - Hvorfor skal jeg tage backup af min blog? Lige meget om du har opbygget
har jeg hentet nedenstående anmeldelse af et godt program til
Software Fra design af hjemmesider: har jeg hentet nedenstående anmeldelse af et godt program til Wordpress er intet mindre end et genialt program til hjemmesider. For det første er det gratis, og for
UPLOAD. Af Database og Website til Skolens Server
UPLOAD Af Database og Website til Skolens Server INDHOLDSFORTEGNELSE Fra projekt til server... 3 Overførsel af SQL Database... 3 Eksekvering af T SQL Script... 8 Modificering af Visual Studio Projekt...
I denne manual kan du finde en hurtig introduktion til hvordan du:
VORES NORDSJÆLLAND HURTIGT I GANG MANUAL 01: Bruger HVAD INDEHOLDER DENNE MANUAL? I denne manual kan du finde en hurtig introduktion til hvordan du: 1. Finder Vores Nordsjælland hjemmesiden 2. Opretter
Internet Information Services (IIS)
Internet Information Services (IIS) Casper Simonsen & Yulia Sadovskaya H1we080113 06-11-2013 Indholdsfortegnelse Problemformulering... 2 Hvorfor:... 2 Hvad:... 2 Hvordan:... 2 Problembehandling... 3 Introduktion...
Indhold. 1 Indledning... 3. 1.1 Kompatible browsere... 3. 2 Log ind i Umbraco... 3. 3 Content-delen... 4. 3.1 Indholdstræet... 4
Indhold 1 Indledning... 3 1.1 Kompatible browsere... 3 2 Log ind i Umbraco... 3 3 Content-delen... 4 3.1 Indholdstræet... 4 3.2 Ændring af indhold... 5 3.3 Tilføjelse af en side/sektion... 6 3.4. At arbejde
Ruko SmartAir. Updater installation
Ruko SmartAir Updater installation Introduktion. Updateren er en speciel enhed som giver os mulighed for at tilføje, læse og skrive funktioner i en offline installation. Med læse og skrive funktionen kan
Manual Serif Web & Tableau Public
Manual Serif Web & Tableau Public Indhold 2 Start 3 Festivalprogram 4-19 Kursuskatalog 20-22 Dramaskolehold 23-28 Visitkort konsulenter 29-30 Visitkort scener 31-35 Amatørkulturens tal 36-42 VIGTIGT! For
SIDEN PÅ WORDPRESS.COM
WordPress WordPress er et fantastisk program til blog og til hjemmesider, hvor du gerne vil kunne rette via din browser. WordPress er meget udbredt og det er derfor nemt at finde fora, templates og hjælp
Opdatering af ISOWARE til version 6.1.0
Opdatering af ISOWARE til version 6.1.0 September 2015 Indhold Kontaktoplysninger... 1 VIGTIGT... 2 Opdatering af trejdepartssoftware... 2 Opdatering til version 6.1.0.... 2 1. Backup af databasen... 3
Hjemmeside på SkoleKom
Hjemmeside på SkoleKom 1 Om vejledningen Har din lærer givet tilladelse, kan du nu lave din helt egen personlige hjemmeside på SkoleKom. En hjemmeside på SkoleKom er let at gå til, og har du arbejdet lidt
SWC eksamens-spørgsmål. Oversigt
SWC eksamens-spørgsmål Oversigt #1 Typer og variable #2 Aritmetik og logik #3 Klasser (definition, objekter) #4 Klasser (metoder) #5 Klasser (nedarvning, polymorfi) #6 Conditional statements #7 Repetition
Bemærk! Et PHP script har kun brug for at forbinde én gang til databaseserveren. Det kan så sagtens udføre flere kommandoer vha. denne forbindelse.
Mysqli Webintegrator Når vi arbejder med server-side scripting ( i vort tilfælde PHP), har vi ofte behov for at kunne tilgå data, som vi opbevarer i en database. Det kan f.eks. dreje sig om nyhederne i
Hold kontakten med dit netværk!
Hold kontakten med dit netværk! - Outlook er dit netværksprogram Outlook er mere end blot et mailprogram Du kan bruge Outlook til meget mere end blot at sende og modtage mails med. Eksempelvis, så er Outlook
Kom i gang med SAS STPbaserede
make connections share ideas be inspired Kom i gang med SAS STPbaserede webapplikationer Lars L. Andersson Chefkonsulent Webapplikationer Interaktion med serverbaserede data via skærmbilleder leveret gennem
Brugermanual til Assignment hand in
Brugermanual til Assignment hand in Indhold: Undervisere:...2 Hvor finder jeg Assignment hand in?...2 Opret en opgave...4 Slet en opgave...5 Rediger en opgave...5 Hvor finder jeg de afleverede filer?...5
Brugervejledning til databrowseren
Brugervejledning til databrowseren Indholdsfortegnelse Indledning...2 Hvordan tilgås browseren og api et...2 Databrowseren...2 Søgning...2 Visning...4 Features i listevisningen...4 Detaljeret visning...5
Arrangementer i Listevisning
Kort introduktion til Typo3-plugin ARRANGEMENTER. De indledende øvelser er fuldstændig de samme som i TYPO3 TRIN FOR TRIN 1 side 1-2. Du åbner altså din browser (Internet Explorer er den almindeligste),
Adobe Acrobat Connect brugergrænsefladen
Adobe Acrobat Connect brugergrænsefladen Adobe Connect er et webbaseret videokonferenceværktøj, der giver mulighed for online, synkron kommunikation, deling af filer, skærm og whiteboard, gennemførelse
ViKoSys. Virksomheds Kontakt System
ViKoSys Virksomheds Kontakt System 1 Hvad er det? Virksomheds Kontakt System er udviklet som et hjælpeværkstøj til iværksættere og andre virksomheder som gerne vil have et værktøj hvor de kan finde og
Installationsguide til Oracle Database XE 10.2 og APEX 3.1.1
Installationsguide til Oracle Database XE 10.2 og APEX 3.1.1 Oracle Database Express Edition (XE) er Oracles lille gratis database tilsvarende Microsofts SQL Server Express Edition. Oracle Database XE
Byggebasen Javascript
EG Data Inform Byggebasen Javascript Implementering af ansvarsperioder og produktdata på eget site Jens Karsø 2013 Indhold Byggebasen javascript-plugin til DB12-site... 2 DB12-site kommunikationsmodel...
Tredjepart webservices
Tredjepart webservices 4. juni 2015 USS Dok. Klik her for at angive tekst. 1/12 Indholdsfortegnelse Introduktion... 3 Miljøer... 3 Adgang... 3 API kald... 4 GET: /authorizations... 4 Input 4 Output 4 Output
Indhold. Vejledning til ShareFile. Sådan uploader du en fil til My Files & Folders. Sådan uploader du en fil til Shared Folders
Indhold Sådan uploader du en fil til My Files & Folders Sådan uploader du en fil til Shared Folders Sådan giver du andre adgang til Shared Folders/My Files & Folders Sådan deler du en fil fra My Files
BRUGER KURSUS RAMBØLL HJEMMESIDE
Til Forsyningsvirksomheder i Danmark Dokumenttype Brugervejledning Rambøll Hjemmeside Full Responsive Dato Oktober 2017 BRUGER KURSUS RAMBØLL HJEMMESIDE BRUGER KURSUS RAMBØLL HJEMMESIDE Revision 01 Dato
DMX styring med USB-interface
DMX styring med USB-interface Introduktion...2 DMX bibliotek...3 Programmering af kanaler...7 Sådan skabes et show/en lyssekvens...11 Introduktion DMX LightPlayer er en avanceret men meget brugervenlig
Dannelse af PDF dokumenter
Dannelse af PDF dokumenter Indhold Dannelse af PDF-dokumenter i Phd Planner... 2 Valg af vedhæftninger i PDF dokumentet... 2 Valg af skabelon for PDF dokumentet... 3 Når PDF filen er dannet... 5 Gem PDF
Wipigo Galleri. Brugsforvirring. Venstre side af startbillede efter der er logget ind (Højre side viser det/de gallerier der er oprettet).
Wipigo Galleri. Brugsforvirring Venstre side af startbillede efter der er logget ind (Højre side viser det/de gallerier der er oprettet). Kategorier/Gallerier/Albums, flere benævnelser for den samme ting.
Integration med Microsoft SharePoint
Integration med Microsoft SharePoint Kom godt i gang med opsætning af integrationen Integration med SharePoint Kom godt fra start I TimeLog Project er der mulighed for at integrere til Microsoft SharePoint,
Affaldsdatasystem Vejledning supplement i system-til-system integration for.net brugere
Affaldsdatasystem Vejledning supplement i system-til-system integration for.net brugere Dokument version: 2.0 ADS version: 1.0 Henvendelse vedrørende affald: Miljøstyrelsen Roskilde, Affaldssekretariatet
Vejledning til Blackboards portfolio værktøj
Vejledning til Blackboards portfolio værktøj Brug denne vejledning, når du skal udarbejde din undervisningsportfolio i Blackboards portfolio værktøj. Ved at følge alle trinene nedenfor får du udarbejdet
De skjulte input typer:
Hvis man skal lave en html formular er der nogle felter til rådighed som kan benyttes, alt efter hvad output fra formularen skal være. Det felt som alle andre felter skal omkranses af er form tagget, som
Administration af subsites BRUGERVEJLEDNING FOR ADMINISTRATOREN
Administration af subsites BRUGERVEJLEDNING FOR ADMINISTRATOREN Indholdsfortegnelse Introduktion... 2 Definitioner... 2 Generelt... 3 Oprettelse af en skabelon... 4 Sidetypeskabeloner... 5 Globale displaymoduler...
Daglig brug af JitBesked 2.0
Daglig brug af JitBesked 2.0 Indholdsfortegnelse Oprettelse af personer (modtagere)...3 Afsendelse af besked...4 Valg af flere modtagere...5 Valg af flere personer der ligger i rækkefølge...5 Valg af flere
Installation af Oracle 10g Release 2 database
Installation af Oracle 10g Release 2 database Oracle 10g database indeholder databasesoftware, enterprise manager, SQL*Plus m.m., HTML DB (i dag kendt som Application Express) og tilhørende HTTP Server
Kenn Römer-Bruhn. WordPress. - gør dig synlig på nettet
Kenn Römer-Bruhn WordPress - gør dig synlig på nettet version 1.3 2. september 2013 Lidt om hvem Kenn er Arbejdsområder i dag: Forfatter, skribent, redaktør, forlægger, fotojournalist, blogger, grafisk
Portfolio Andreas Stjerneklar Kristensen. Multimedia Designer Eksamen 1. Semester
Portfolio Andreas Stjerneklar Kristensen Multimedia Designer Eksamen 1. Semester Indledning Design Skitser ASK logoet Teknologivalg No database Javascript Eksempel Udviklingsmuligheder Mere relation mellem
Guide til, hvordan du tilføjer en GIPPLER- fane til din Facebook side
Guide til, hvordan du tilføjer en GIPPLER- fane til din Facebook side Bemærk! Vi bruger i denne guide både Facebook og en applikation på Facebook for, at lave din GIPPLER- fane. Vi kan af naturlige årsager
Installation af Elektronisk APV på flere PC er
Installation af Elektronisk APV på flere PC er Vejledning til installation af Elektronisk APV, når programmet skal installeres på flere PC er, der kobler sig op på en fælles server. 1 Installation af Elektronisk
Vejledning til Teknisk opsætning
Vejledning til Teknisk opsætning v. 1.0 Adm4you, 2010. Indhold Kort om denne vejledning... 3 Generelt om easyourtime... 3 Installation af databasen... 3 Sikkerhed og rettigheder... 4 SQL Login... 4 Rettigheder
Sådan logger du ind... 2 Hvilke mapper kan du tilgå... 3 Visning af eksempel af en fil... 5 Sådan deler du en fil... 7 Se hvad du deler med andre...
Sådan logger du ind... 2 Hvilke mapper kan du tilgå... 3 Visning af eksempel af en fil... 5 Sådan deler du en fil... 7 Se hvad du deler med andre... 9 Offline synkronisering... 11 Klienter til mobile enheder...
RefWorks en vejledning fra UCL Biblioteket. Indholdsfortegnelse
Indholdsfortegnelse Hvad er RefWorks?... 2 Opret dig som bruger... 2 Inden du går i gang... 3 Klargøring af computer til download af Write-N-Cite v. 4.2... 3 Installation af Write-N-Cite... 4 Installation
RIGSPOLITIET. Vejledning i konvertering. fra. Word -dokument. til. PDF-fil. på politi.dk. Rigspolitiets websektion
RIGSPOLITIET Vejledning i konvertering fra Word -dokument til PDF-fil på politi.dk Rigspolitiets websektion Indledning Da vi skal leve op til kravene om tilgængelighed på Internettet, skal alle tekster
Installation af Wordpress
Kræver et webhotel der kører PHP og database (MySQL) Installation af Wordpress Wordpress-grund-programmet downloades fra WordPress.org det er gratis Fra webhotellet skal man have 4 informationer som skal
Lundtofte skole 2007/08. Åbn FrontPageExpress og Explorer begge programmer skal være åbne når du laver hjemmesiden.
Det vigtigste Hjemmeside i FrontPageExpress Åbn FrontPageExpress og Explorer begge programmer skal være åbne når du laver hjemmesiden. Lav en mappe til din hjemmeside. Find først din mappe på skolens netværk,
Quick Guide for Mobil Reception (Omhandler mobil reception også kaldet isymphony)
Quick Guide for Mobil Reception (Omhandler mobil reception også kaldet isymphony) Generelt Mobil Reception er et værktøj som bruges til at overvåge medarbejdere, kø er og meget andet samt styre dit omstillingsanlæg
Redaktørvejledning for www.bredstrup-pjedsted.dk Skriv en artikel
Arbejdsgang - Skriv artiklens tekst - Gør billeder klar - Log-in på hjemmesiden - Opret ny artikel - Vælg kategori - Skriv overskrift - Indsæt tekst - Tilføj billeder - Gennemgå artiklens indstillinger
MANUAL. Siteloom CMS
MANUAL Siteloom CMS www.hjerteforeningen.dk/cms Brugernavn: Password: 3. september, 2012 BASIS FUNKTIONER 1. Kalender... 4 1.a. Opret... 5 1.b. Rediger eller slet... 8 2. Sider... 10 2.a Opret side...
Anvendelse af Model- View koncept i SAS Stored Processer
Anvendelse af Model- View koncept i SAS Stored Processer Peter Sandal Boll Chefkonsulent Professional Services, Skanderborg SAS Institute A/S Agenda Model-View-Controller konceptet (MVC) Eksempel med put-rapport
Dynamicweb Quickguide
Brugervejledning Dynamicweb Quickguide Version: 1.1 2012.03.15 Dansk JURIDISK MEDDELELSE Copyright 2012 Dynamicweb Software A/S. Alle rettigheder forbeholdes. Dette dokument eller dele heraf må på ingen
Quick guide til e-learn.sdu.dk (Blackboard) for studerende
Quick guide til e-learn.sdu.dk (Blackboard) for studerende Der opnås adgang til e-learn.sdu.dk (Blackboard) via single sign-on, sso.sdu.dk/, eller adressen: e-learn.sdu.dk/. Når du har logget på, står
PBX Online Brugervejledning www.pbxonline.dk
PBX Online Brugervejledning www.pbxonline.dk Indledning PBX Online er dit personlige omstillingsanlæg som ikke kræver noget fysisk udstyr installeret i dit firma. Du styrer det hele via din web browser.
PHP kode til hjemmeside menu.
PHP kode til hjemmeside menu. Home Hovedmenu 1 Hovedmenu 2 Hovedmenu 3 Hovedmenu 4 Undermenu 1 Breadcrumb Her vises indholdet af den valgte side Undermenu 2 Undermenu 3 Undermenu 4 Evt. en mulighed for
IT Support Guide. Installation af netværksprinter (direkte IP print)
IT Support Guide Denne guide er hentet på www.spelling.dk Program: Microsoft Windows Vista Program sprog version: ENG (US) Guide emne: Installation af netværksprinter (direkte IP print) Publikationsnr.:
Adobe Digital Editions
Adobe Digital Editions Kom godt i gang Klik på knapperne nedenfor for at komme videre Forberedelse Download Adobe Digital Editions: Til Windows TRYK HER Til Mac OS TRYK HER Bemærk: Adobe Digital Editions
My booking. Generelt. Forsiden. Version 9.0
My booking Version 9.0 System til at lave online bookinger, med mulighed for opdeling i grupper, forskellige booking typer, ændre layout indstillinger, status styring, sprogvalg samt en del mere, detaljer
Sådan kan du sende data fra din egen hjemmeside til JitBesked via en HTML-JDF.
Sådan kan du sende data fra din egen hjemmeside til JitBesked via en HTML-JDF. Vejledningen her beskriver hvordan man opbygger en form i HTML og sender indholdet af felterne til JitBesked. Det kræver du
Fase Forklaring Navigation. Mappen skal indeholde alle elementer til dit site.
1 Opstart af et site Opret hovedmappen Opret grafikmappen Opret dit site Mappen skal indeholde alle elementer til dit site. Opret en mappe indeni den første og kald den grafik. Heri lægges alle dine grafikfiler.
FC-intranet: FC-intranet er et fælles mail- og konferencesystem, hvor lærere og elever kan kommunikere.
IT-intro 9. august 2011 14:56 IT-introduktion på Risskov Gymnasium FC-intranet: FC-intranet er et fælles mail- og konferencesystem, hvor lærere og elever kan kommunikere. Før end man kan logge sig ind
Sådan kommer du godt igang -guide
Sådan kommer du godt igang -guide Log på: Åbn SDUs e-læringsplatform ved at åbne din internetbrowser og indtaste adressen: http://elearn.sdu.dk Klik på Login Indtast brugernavn (username) og adgangskode
Samspillet mellem databaser og kort styres af GeoCAD programmet GeoDB.
GeoCad modul GeoDB I GeoCAD er det muligt at koble relationsdatabase til GeoEDIT. Her igennem er det muligt at lagre forskellige oplysninger i databasen og koble disse oplysninger til objekter i kortet.
GRAFISK WORKFLOW. 1 Grafisk workflow
GRAFISK WORKFLOW 1 Opgavebeskrivelse I forbindelse med et nyt online koncept Web in a box skulle jeg lave en Photoshop-skabelon, der kan eksportere materiale til en hjemmeside automatisk. Selve konceptet
Sådan installeres og teste WordPress på en lokal server
Sådan installeres og teste WordPress på en lokal server Det gratis WordPress blog værktøj er vokset gennem årene til et fuldgyldigt CMS-system content management system). WordPress har forenklet processen
Manual til Wordpress. 1. Log ind på din Wordpress-side. Indhold:
Manual til Wordpress Sådan opdaterer du din hjemmeside i Wordpress: Dette er en manual til de mest grundlæggende ting, så du selv kan redigere indholdet eller tilføje nyt på din hjemmeside. Guiden er skrevet
Manual Version 2. til oprettelse af hjemmesider for landsbyer i Rebild kommune
Manual Version 2 til oprettelse af hjemmesider for landsbyer i Rebild kommune Oversigt: Login Hjemmeside...... side 3 Login Administrationsmodul... side 5 Kategorier.. side 6 Opret/rediger første side...
