4 Konstruktion
4.1 Förarbete
4.2.3 Import logfile (Startsida)
Det första steget, i rapportverktyget, är att importera de loggfiler som ska gene-rera slutrapporten. Därför är detta applikationens startsida och innehåller en knapp för att välja filer och en knapp för att ladda upp de valda filerna.
Importera filer - Frontend
I HTML finns det färdiga element för att importera filer och för att formuläret ska fungera som tänkt specificerades att det kommer skickas mer än bara text (enctype="multipart/form-data"). För elementet input type="file" har ett antal olika attribut lagts till; den ska endast föreslå .XML filer (accept=".xml"), det ska gå att ladda upp flera filer samtidigt (multiple) samt att minst en fil måste väljas för att formuläret ska kunna skickas (required).
Det var enkelt att skapa formuläret i HTML men här uppstod ett annat problem, texten som skrivs ut i vyn för fil-elementet anpassar sig efter vilket språk som är inställt på den enhet som visar applikationen. I utvecklingsmiljön är det för-inställda språket svenska vilket gjorde att hela applikationen visades på engels-ka förutom just funktionen för att ladda upp filer. Första försöket till lösning var att ändra de globala inställningarna och ändra standardspråket men det visade sig vara väldigt svårt att komma runt så det slutade med att texten istället skrivs ut med JavaScript och likaså resultatet när filerna laddats upp.
Varje import-fil (Recording) består av ett antal Sweep (varierar mellan 4 till 12 i testfilerna) och varje Sweep består av 113 variabler som ska loopas igenom vid uppladdning. Vid ett test importerades 24 import-filer samtidigt med samman-lagt 201 Sweep vilket motsvarar 22713 variabler att gå igenom. Det tog drygt 50 sekunder och under tiden stod webbläsaren och tänkte vilket skulle kunna misstolkas av användaren. Detta ger en ökad risk för att användaren inte förstår att den måste vänta tills uppladdningen är klar och kanske klickar sig vidare.
För att undvika missförstånd behövdes någon form av information om att filer-na håller på och laddas. Det bästa hade varit en progress bar som visar uppladd-ning i procent men eftersom filuppladduppladd-ningen då måste hanteras frontend och funktion för detta redan var löst i backend togs beslut om att göra en kompro-miss. En ruta som visar ett meddelande om att filerna processas samt en anime-rad progress bar som rör på sig för att ge intrycket av att applikationen arbetar
Figur 8: Favicon
visas på skärmen tills filerna laddats klart (se figur 9). För att ytterligare förstär-ka effekten täcks bakgrunden av en mörk och lätt genomskinlig bakgrundsfärg.
Inforutan och bakgrunden aktiveras med med hjälp av ett JavaScript som trig-gas när formuläret skickas.
Efter att filer laddats upp visas ett meddelande på skärmen som redovisar hur det gått. Det finns många olika meddelanden beroende på hur det gått men tan-ken är att ge så bra feedback som möjligt så att användare lätt ska kunna se och förstå status samt eventuellt åtgärda problem.
Importera filer - Backend
Importfunktionen sparar ner resultat i nästan alla tabeller och för att åstadkom-ma det skapades först modellerna. När det var klart kunde motsvarande tabeller, i databasen, skapas (se kapitel 4.3).
Efter att modellerna var klara skapades ImportController som dels hanterar In-dex-vyn men som också har ett antal metoder för importeringen av data. När ImportController först laddas körs metoden Index() som returnerar vyn och skickar med projekten som finns i databasen. När användaren sedan laddar upp filer skickas formuläret tillbaka till ImportController men nu med POST som header. Via annotation ([HttpPost]) skickas formuläret till rätt Index-metod som nu tar två argument; dels filerna (IFormFile[]) som valts och dels information om miljön som det skickas till (IwebHostEnvironment). Detta göra att import-proceduren startar:
1. Det första som sker när man tryckt på ”Upload files” är att det görs en kontroll så att minst en fil är vald. Detta görs även fast required angetts i formuläret eftersom det i vissa fall går att komma runt required i fron-tend.
2. Nästa steg är att ladda upp filen till en katalog på servern (files) för att kunna läsa in innehållet.
3. Sedan kontrolleras ifall filen är på .XML-format och skulle den inte vara
Figur 9: Meddelande vid import av filer
Den plussar också en variabel som håller reda på ifall filer misslyckats att laddas upp.
4. För att systemet sedan ska kunna hantera .XML formatet så konverteras filen till en instans av Xdocument.
5. Efter det görs en kontroll om det finns stäng-taggar i .XML-filen som inte har en öppnings-tagg och likaså ifall det finns mellanslag eller null-värden och rensar sedan bort det. Vid de första import-testerna upptäck-tes fenomenet med endast stängnings-taggar vilket ligger till grund för detta steg.
6. Alla poster och värden sparas sedan till en lista för att kunna loopas ige-nom.
7. Eftersom all data nu sparats till en lista behövs inte filen längre varpå den stängs och sedan raderas från katalogen files.
8. Listan med data skickas till en metod, (SaveToDb()) som tar listan med .XML-data samt filnamnet som argument (se figur 10).
Syftet är att spara till databasen samtidigt som svaret från funktionen kontrolleras. Om allt går bra plussas en variabel som räknar antalet lyck-ade uppladdningar annars avbryts uppladdningen. Anledningen till att det är löst med en funktion istället för en nästlad loop är att det då går att returnera false och avbryta den yttre loopen vilket i sin tur göra att det går att få mycket bättre kontroll på flödet och meddelandehanteringen.
9. Det första som händer i spara-funktionen är att en kontroll görs för att säkerställa så att ett antal nyckelvärden finns. Eftersom varje tabell an-vänder överstående tabells primär nyckel som främmande nyckel går det inte att spara till databasen om inte dessa värden finns:
• Varje mätprojekt måste ha ett id (TestID).
• Det måste finns ett namn angivet för vilket test det rör sig om (For-mula.TestName).
Figur 10: Metod för att spara till databasen SaveToDb(
IEnumerable<XElement> valueList, string filename
)
• Det måste finnas ett testobjekt angivet i antingen position 1 eller 2 alternativt i båda (Formula.TestObject_A1 och
Formula.TestObject_A2).
• Ett id för Recording måste ha angetts (Formula.Recording).
• Ett nummer måste vara angett för Sweep (Formula.Sweep).
Om något av dessa värden saknas kommer loopen att avbrytas och ett felmeddelande kommer genereras som talar om vilken fil det rör sig om och vilket värde som saknas (se figur 11).
10. Om listan klarar kontrollen i punkt 9 sparas samtliga värden ner i sin re-spektive tabeller. För varje värde görs en kontroll om det finns sparat se-dan tidigare och i sånt fall uppdateras det befintliga värdet istället för att sparas på nytt.
11. Alla poster som innehåller mätvärden sparas till tabellen Value via en metod som heter SaveValue() och som tar fyra argument; raden i .XML-filen som loopen befinner sig på, Sweep-nummer, namnet på värde-vari-abeln samt namnet på enhets-varivärde-vari-abeln (se figur 12).
I metoden SaveValue() görs ytterligare en kontroll ifall mätvärdet är tomt, satt till NaN eller 0. I dessa fall hoppas mätvärdet över och även dess enhet. Detta gör att endast mätvärden med relevant innehåll sparas till databasen och det blir inga mätvärden som sätts till null. Det finns två undantag där mätvärdena inte har någon enhet och för att inte behö-va göra specialanpassningar för dessa två fall, tillåts null-värde på enhet.
12. Det sista som händer är att ett meddelande talar om för användaren vilka eller hur många filer som laddats upp. Om det är mer än två filer talar
Figur 11: Exempel på test av existerande ingångsvärden
if (value.Element("Formula.TestID")?.Value == null) {
ViewBag.Message = "Upload error: TestID value missing in
" + filename;
return false;
}
Figur 12: Metod för att spara mätvärden till tabellen Value SaveValue(
Tabell med befintliga projekt
Förutom importfunktionen innehåller startsidan även en tabell (se figur 13) som visar de projekt som redan finns i databasen. I tabellen visas importdatum, pro-jektens id samt namn. Det finns också två ikoner som dels länkar till Projekt settings respektive Create report, dels sparar sessionen för vilket projekt som valts. Kopplat till ikonerna finns JavaScript-biblioteket Tooltips som göra att tit-le-taggen går att designa om. Syftet är att ge användaren mer information om vad respektive ikon har för funktion. Layouten är anpassad så att den ska passa den grafiska profilen.
Tabellen har en sorteringsfunktion för respektive rubrik (Options undantaget) som fungerar med hjälp av JavaScript-biblioteket DataTables tillsammans med Bootstrap och jQuery. DataTables laddas med hjälp av Content Delivery Ne-twork (CDN) för att säkerställa så att senaste versionen alltid är aktiv. Sorte-ringen fungerar genom att informationen i tabellen läses in för att sedan kunna sorteras och skrivas ut igen med hjälp av AJAX. Det som är extra bra med den-na lösning är att det inte spelar någon roll vilken information som finns i tabel-len. Eftersom innehållet alltid skapas i backend och sedan skrivs ut på skärmen innan sorteringsfunktionen aktiveras på frontend så kommer det alltid att funge-ra oavsett hur många projekt som laddas ner till databasen. En annan bfunge-ra sak med DataTables är att det redan finns färdiga funktioner för bland annat sök-funktion och paginering. Om det blir många projekt i framtiden kan dessa funk-tioner lätt aktiveras genom att ange dem som true i listan med opfunk-tioner.