• Ingen resultater fundet

A.8 Vælg afdelinger, n˚ ar afdelingsdimensionen er valgt i analyseme-

6.2 Server-side

6.2. SERVER-SIDE KAPITEL 6. IMPLEMENTERING

6.2.1.1 Autentificering

DenmvcController, der serverer Dashboard applikationen, hedder

KendoController. Hvis jeg kan begrænse adgangen til denne Controller og dens metoder, og kræve at kun autentificerede bruger/forespørgsler har lov til at bru-ge denne Controller, har jeg opn˚aet autentificering. Dette er præcis, hvad jeg kan opn˚a med[Authorize]attributten iasp.net mvc. Denne attribut kan jeg an-vende p˚a Controller niveau ved at dekorere Controlleren med attributten.mvc runtime vil nu opfange alle indkommende forespørgsler til enhverActionmetode i denne Controller og sørge for, at adgangen er autentificeret; hvis ikke, bliver forespørgslen omdirigeret til login siden. Det er klassen AccountController, der st˚ar for autentificering. Her er defineret enLogonpostActionmetode, som tager et modelobjekt som parameter. Modelobjektet bærer information fra form-felterne, som brugeren har indtastet. Her tjekkes de indtastede oplysninger hos BM.ServerLogic, om der findes en Business Monitor aftale med de indtastede oplysninger. I bekræftende fald, udstedes enauthentication ticketfor bruge-ren ved at kalde metodenSetAuthCookie(userName)p˚aFormsAuthentication klassen.authentication ticketbliver vedligeholdt i enCookie, s˚a en autenti-ficeret bruger ikke skal give sine credentials ved hver forespørgsel. Denne process hedder brugerautentificering. Et anden aspekt i brugerkontrol er brugerautori-sationen, som angiver, hvorvidt en autentificeret bruger har rettigheder til at benytte en bestemt ressource i systemet. Denne har jeg ikke implementeret, men ville let kunne tilføjes.

Figur 6.2:Forms Authentication Control Flow.

6.2. SERVER-SIDE KAPITEL 6. IMPLEMENTERING

Denne sekvens af brugerautentificering er afbildet i figur 6.2. Som det kan ses, starter sekvensen med at brugerens browser forespørger sidenHome.cshtml fra webserveren. DaHomeControlleren ikke er har en begrænset adgang for bruger, returnererasp.netHome.cshtml Viewet. Brugeren forespørger nu Dashboard-siden. Da denne kontroller kræver brugerautentificering, ser asp.net efter en authentication cookie. N˚ar den ikke finder enauthentication cookie, omdirigeres browseren til Logon.cshtm siden. Information om brugernes oprindelig fore-spørgsel gemmes iQuery string med nøglenReturnURL. Browseren forespørger Logon.cshtml siden, som webserveren s˚a returnerer. Brugeren indtaster sine credintials og poster loginformen tilbage til serveren. AccountController vil nu overdrage brugervalideringen tilBM.ServerLogic, som vil returnerer en gu-id, hvis brugeren er valideret.AccountControlleropretter encookie, som inde-holderforms authentication ticket, som bliver sat for sessionen. Serveren omdirigerer browseren til den url, som var gemt i query strings returnURL parameter. Herefter vil browseren forespørge Dashboard siden igen, og denne forespøgsel vil inkludere forms authentication cookie. Serveren vil nu re-turnere Dashboard.cshtml-siden, der ogs˚a linker til andre ressourcer (css og JavaScriptfiler).

6.2.2 Web API

Servicelaget er implementeret med asp.net web api, som gør det lettere at udvikle rest services i.net. Al kommunikation med klientlaget sker gennem dette lag. Der er datalag p˚a serveren - b˚ade den eksisterende BM.DataAccess og laget repræsenteret medEntity Framework, som jeg har implementeret i for-bindele med persistens. web api eksponerer disse data, pakket ind som .net objekter, til klienten i form af jsonoverhttp, s˚a klienten kan arbejde videre med det. F.eks. har jeg sat etapi endpointop, der returnerer alle kpi typer, der findes i systemet. Denneendpointharurlhttps://[host]/api/KpiCatalog.

N˚ar klienten sender en http forespørgsel til denne api endpoint, kan data, somweb apireturnerer, ses i browserens udviklingsværktøj, som vist i figur 6.3 nedenfor.

Det, vi kan se i figur 6.3, er, at der fra JavaScript kode er foretaget en ajax forespørgsel til web api url .../api/KpiCatalog. Svaret fra web api er opfanget af Chromes udviklerværktøj, hvor det kan ses, at der er returneret et array afjsonobjekter, der repræsentererkpityperne. S˚a ved at lave den slags simple restful http kald til web api, kan jeg nemt og enkelt f˚a mine data p˚a klienten. Grundet denne enkelhed, og fordi det virker s˚a godt medhttpog json, erasp.net web apiet godt valg for prototypen.

6.2.2.1 Data forespørgsel fra Web API

For at bygge et servicelag for applikationen har jeg overvejet følgende:

• httpforespørgslerne

• Routes, der skal dirigere forespørgslerne

6.2. SERVER-SIDE KAPITEL 6. IMPLEMENTERING

Figur 6.3:Web API forespøgsel for KPI typerne.

• apiControllers, som skal svare p˚a dem

N˚ar der skal forespørges data fraapi, laves en Web Request. Webserveren vil s˚a forsøge at matche anmodningen til enRoute, s˚a anmodningen kan dirigeres til en Controller. OgapiControlleren vil s˚a svare med noget data. S˚a det drejer sig om at lave en anmodning, matche enRouteog f˚a Controlleren til at svare.

asp.net web api er ligesomasp.net mvc baseret p˚a konventioner. Dvs. for enurlsom dennehttps://[host]/api/KpiCatalogsiger konventionen, at p˚a web-serveren skal vi kunne findeapiController ved navnKpiCatalog. Anmodningen vil matchegetmetoden i denne Controller.

Listing 6.1:web apiController -http get

1 [A u t h o r i z e]

2 p u b l i c c l a s s K p i C a t a l o g C o n t r o l l e r : A p i C o n t r o l l e r

3 {

4 // GET api / K p i C a t a l o g

5 p u b l i c I E n u m e r a b l e < K p i C a t a l o g I t e m > Get ()

6 {

7 r e t u r n K p i F a c t o r y . G e t K p i L i s t () ;

8 }

9 }

Kodeovesigt 6.1 viser, hvad denneurlmatcher til p˚a server siden. Navnet KpiCatalog matcher til den første del af klassenavnet. Og fordi det er enhttp getanmodning, matcher den tilActionmetoden Get().getmetoden kunne heddergethvadSomHelst().

Men hvordan dirigeres anmodningen ned til Controller? Her kommerRouteind i billedet. Da jeg satteweb apiop, blev der oprettet enRoutevha. en standard template, som er”api/{controller}/{id}”, som siger, at en anmodning tilweb apihar en uri, der starter med api efterfuglt af / [Controller-navn] / [en id].

Standard templaten definere id-delen som værende en valgfri parameter. Derfor kanweb apiframeworket dirigere anmodningenhttps://[host]/api/KpiCatalog tilKpiCatalogControllerved at at bruge standardRoutetemplate.

6.2. SERVER-SIDE KAPITEL 6. IMPLEMENTERING

6.2.2.2 Opdatering af data

I sidste afsnit viste jeg, hvordan en anmodning kan sendes tilweb api baseret p˚ahttp get og returnere data. Jeg kan ogs˚a oprette eller modificere data ved at sendehttp posteller putanmodning tilweb api. Jeg har nogleweb api Controllers, der h˚andterer crud funktioner p˚a mine Dashboard entiter for at understøtte persistens. En af dem erDashboardsController, som ved brug af Entity Frameworkimplementerer operationer p˚a Dashboard entiteter. Kodeover-sigten 6.2 neden for viserhttp post Actionmetoden fra denne Controller.

Listing 6.2:web apiController -http post

1 // P O S T api / D a s h b o a r d s

2 p u b l i c H t t p R e s p o n s e M e s s a g e P o s t D a s h b o a r d ( D a s h b o a r d d a s h b o a r d )

3 {

4 if ( M o d e l S t a t e . I s V a l i d )

5 {

6 db . D a s h b o a r d s . Add ( d a s h b o a r d ) ;

7 db . S a v e C h a n g e s () ;

8

9 H t t p R e s p o n s e M e s s a g e r e s p o n s e = R e q u e s t . C r e a t e R e s p o n s e (

10 H t t p S t a t u s C o d e . Created , d a s h b o a r d ) ;

11 r e s p o n s e . H e a d e r s . L o c a t i o n = new Uri (

12 Url . L i n k (" D e f a u l t A p i ", new { id = d a s h b o a r d . Id }) ) ;

13

14 r e t u r n r e s p o n s e ;

15 }

16 e l s e

17 {

18 r e t u r n R e q u e s t . C r e a t e E r r o r R e s p o n s e (

19 H t t p S t a t u s C o d e . B a d R e q u e s t , M o d e l S t a t e ) ;

20 }

21 }

Jeg kan fra klientsiden sende enhttp postanmodning til dette

apiendpoint. Anmodning vil inkludere noget data (payload), som repræsen-terer et nyt dashboardobjekt. Som det kan ses, bruger jeg DbContext til at interagere med databasen og tilføje det nye dashboard, som bliver oprettet. Jeg returnerer en HttpStatusCode.Created, fordi der blev oprettet nyt dashbo-ard, og jeg returnerer ogs˚a dashboardobjektet, fordi det f˚ar tildelt et nyt id i forbindelse med oprettelse i database.

6.2.3 KpiEngine

KpiEngine, som nævnt tidligere, er det modul p˚a server-siden, jeg m˚atte tilføje for at implementere noget af denkpiberegning- og filtreringslogik, der i dag er en del af Silverlightklienten og derfor ikke tilgængelig p˚a serveren. Elementer i dette modul bliver forklaret i det følgende:

KPI

Jeg har valgt at implementere beregning og filtrering af nogle kpi typer, der er lettere at beregne, i forhold til andre mere kompliceredekpi typer.