← Webbserverprogrammering 1 Område 5 · Code-first: modell, databas och formulär Felsökning

Webbserverprogrammering 1 · område 5 · v.50–52

Code-first: modell, databas och formulär

Ett kort område som avslutar terminen och binder ihop tre saker som annars lärs var för sig: modellklassen, databastabellen och formuläret. Attributen skrivs en gång på klassen och styr både vad databasen får och vad formuläret släpper igenom. Och det är här område 4 betalar tillbaka: du byter ut hela datalagret bakom gränssnittet, och ingen komponent märker det.

Inget prov efter det här området

Innehållet prövas i prov 4 på vårterminen, där det byggs vidare med relationer och LINQ. Lämna in och gå på lov.

1. Fyra lektioner

Tisdagarna bär det nya, onsdagarna befäster. Kolumnen längst till höger säger vad du gör om du var borta.

#DatumLängdVad vi görMissade du passet?
31ons 9 dec45 min Code-first: modellen är sanningen. Var tar en ny film vägen? Entiteten får attribut, och DbContext skrivs. Guiden steg 1–3 och begreppen
32tis 15 dec85 min Migration och databas. Paketen, anslutningssträngen, frödata, första migrationen – och tabellen öppnas: vad blev av attributen? Tjänsten byter implementation. Guiden steg 4–9, särskilt steg 8
33ons 16 dec45 min Formulär och validering. EditForm, DataAnnotationsValidator, och varför serversidesvalidering alltid krävs. Guiden steg 10–12 och en rad som är hela skillnaden
34tis 22 dec85 min Färdigställ och lämna in. Sedan terminens fem områden som en kedja, och vårens fyra projekt. Uppgiften med de tre kontrollerna, och terminen och våren

2. Det här ska sitta

3. Ett verktyg till

Hittills har du haft två kommandon: dotnet build och dotnet run. Nu kommer ett tredje, och det har egna fel.

dotnet ef läser dina klasser och skriver databasen

Det körs varken vid bygget eller när sidan öppnas, utan när du själv kör dotnet ef migrations add eller dotnet ef database update. Står du i fel mapp, saknas ett paket eller stämmer inte anslutningssträngen får du veta det där – och applikationen kan mycket väl bygga och starta ändå, mot en databas som inte finns.

NärSer ut somExempel
ByggetRöd text i editorn, dotnet build misslyckasRequired hittas inte, BL0008
Migrationendotnet ef avbryts med ett meddelandeFel mapp, Design-paketet saknas, anslutningssträngen stämmer inte
SidvisningenServern kör. Just den sidan svarar 500no such table, delat DbContext
AldrigAllt fungerar. Beteendet är ändå felBetyg 99 sparas – DataAnnotationsValidator saknas

Två vanor som gör hela skillnaden i det här området:

4. Kom igång

Du börjar inte om. Området bygger vidare på projektet från område 4.

StegDet du gör
1Öppna ditt projekt från område 4 och kontrollera att listsidan och detaljsidan fungerar med dotnet run. Utan tjänsten bakom gränssnittet går det inte att följa med – gör klart område 4 först.
2Kontrollera att dotnet ef --version svarar. Gör den inte det: dotnet tool install --global dotnet-ef, en gång.
3Fyll i högerkolumnen i guidens översättningstabell. Vad heter din entitet, din context, ditt DbSet?
4Gå igenom din huvudentitet fält för fält: vilka har en regel? Det är de som ska ha attribut.
5Lämna den hårdkodade listan kvar tills tjänsten läser ur databasen. Radera den sedan – bygget blir din kontroll.

Mappstrukturen du är på väg mot:

DittProjekt/
├── Components/
│   └── Pages/
│       └── NyPost.razor        formuläret som skapar
├── Data/
│   └── DittProjektContext.cs   DbContext med ett DbSet
├── Migrations/                 genererad – redigeras aldrig för hand
├── Models/
│   └── DinEntitet.cs           klassen, nu med attribut
├── Services/
│   ├── IDinService.cs          samma som i område 4, plus metoden som sparar
│   └── DinService.cs           läser ur databasen
├── appsettings.json            anslutningssträngen
├── dittprojekt.db              databasen – ligger i .gitignore
└── Program.cs                  AddDbContextFactory

Committa efter varje pass. Deadline är tisdag 22 december, och den som committar allt sista kvällen har en historik som inte visar något arbete.

5. Felsökning

Sök på felmeddelandet du fick, eller på ett ord ur det. Kolumnen när säger om felet kommer vid bygget, vid migrationen eller vid sidvisningen – leta på rätt ställe.

18 rader

SymptomNärTrolig orsakÅtgärd
The type or namespace name 'Required' could not be foundbyggetusing-raden saknasusing System.ComponentModel.DataAnnotations; överst i modellklassen.
The type or namespace name 'DbContext' could not be foundbyggetEF Core-paketen är inte hämtadedotnet add package Microsoft.EntityFrameworkCore.Sqlite och .Design.
BL0008bygget[SupplyParameterFromForm] på en egenskap med initierareTa bort = new(). Skapa objektet i OnInitialized med ??=.
dotnet ef känns inte igenmigrationenVerktyget är inte installeratdotnet tool install --global dotnet-ef, en gång per dator.
No project was foundmigrationenDu står i fel mappcd till mappen med .csproj.
Your startup project doesn't reference Microsoft.EntityFrameworkCore.DesignmigrationenBara ett av de två paketen är hämtatBåda behövs. dotnet add package Microsoft.EntityFrameworkCore.Design.
Unable to create a 'DbContext' of typemigrationenAnslutningssträngen hittas inteNyckeln i GetConnectionString måste stämma bokstav för bokstav med appsettings.json.
The model for context has pending changesmigrationenKlassen är ändrad efter senaste migrationendotnet ef migrations add NamnPaAndringen, sedan database update.
SQLite Error 1: 'no such table: Filmer'sidvisningMigrationen är skriven men inte körddotnet ef database update. add räcker inte.
A second operation was started on this context instancesidvisningEtt delat DbContext – AddDbContext i stället för fabrikenAddDbContextFactory, och ett eget context per metod med using.
Cannot consume scoped service 'DittProjektContext' from singletonserverstartContextet injicerat i en singletonSamma fel som i område 4. Använd fabriken.
Sidan svarar 400 på formuläretsidvisningAntiforgery-token saknas – formuläret är byggt för handEditForm lägger in den själv. Kontrollera i sidkällan att __RequestVerificationToken finns.
Formuläret gör ingentingsidvisningFormName saknasEditForm behöver den vid statisk serverrendering.
NullReferenceException i markupensidvisningObjektet skapas aldrigFilm ??= new Film(); i OnInitialized.
OnValidSubmit körs aldrigaldrigNågot fält validerar inte, och du ser inte vilketLägg till <ValidationSummary /> och läs vad som står.
Ogiltiga värden sparasaldrig<DataAnnotationsValidator /> saknas, eller OnSubmit i stället för OnValidSubmitBåda behövs. Utan validatorn läses inga attribut; med OnSubmit sparas allt.
Felmeddelanden på engelskaaldrigErrorMessage saknas på attributetSkriv den, på svenska, på varje attribut.
Sidan visar noll posteraldrigDatabasen är tom – frödata glömd, eller databasen skapad före denRadera .db-filen och kör database update igen.

6. Orden

Orden nedan används från och med nu utan förklaring. Träna tills du kan dem – prov 4 i mars frågar efter flera av dem i klartext.

Ordträning

OrdBetyder
code-firstKlassen skrivs först, databasen byggs efter den. Motsatsen är database-first.
entitetEn klass som motsvarar en tabell. Varje objekt är en rad.
attributEn regel skriven inom hakparenteser ovanför en egenskap: [Required], [Range]. Information, inte kod som körs.
data annotationsSamlingsnamnet för valideringsattributen. Namnrymden System.ComponentModel.DataAnnotations.
DbContextKlassen som håller ihop entiteterna och kopplingen till databasen. En session mot databasen.
DbSet<T>En tabell, sedd från C#. Egenskapens namn blir tabellnamnet – därför plural.
primärnyckelKolumnen som identifierar raden. Id blir det automatiskt.
anslutningssträngTexten som säger var databasen finns. Ligger i appsettings.json, inte i koden.
migrationEn genererad beskrivning av hur databasen ska ändras. Redigeras aldrig för hand.
migrations addSkriver en ny migrationsfil ur skillnaden mellan klasserna och förra migrationen. Rör inte databasen.
database updateKör de migrationer som inte körts. Det är den som rör databasen.
frödataRader som följer med migrationen in i databasen. Seed. HasData i OnModelCreating.
SQLiteEn databas som är en enda fil. Ingen server, inget lösenord – och ingen längd på TEXT.
IDbContextFactoryFabriken som ger varje metod ett eget context. Ett delat DbContext är inte trådsäkert.
EditFormBlazors formulär, som kan validera mot en modell. Lägger in antiforgery-token själv.
DataAnnotationsValidatorKomponenten som läser attributen på modellen. Utan den valideras ingenting.
OnValidSubmitKörs bara när valideringen gick igenom. OnSubmit körs oavsett.
klientvalideringKontroller som körs i webbläsaren. För användarens skull – inte ett skydd.
serversidesvalideringKontrollen som körs på servern efter att formuläret kommit in. Den enda som går att lita på.