Webbserverprogrammering 1 · område 6 · v.2–10
Datadriven applikation – CRUD, relationer och inloggning
Vårterminens första och största projekt. Höstens delar sätts ihop till en riktig applikation: komponenterna visar, tjänsterna gör arbetet, och databasen minns. Din applikation får alla fyra operationerna, en kategori i en egen tabell, en sökning som görs av databasen, och en inloggning som skyddar allt som ändrar något.
- 8 mars Projekt 1 – Datadriven webbapplikation, kl 23:59 Repots adress lämnas i itslearning. Fyra etapper före det, med egna datum.
- 9 mars Prov 4 – databas och datadriven applikation 80 minuter, utan dator. Täcker område 5 och 6.
Tjugosex steg med all kod, uppdelade efter lektionerna. Följ den här om du missat ett pass.
Projekt 1 Datadriven webbapplikationFem etapper med datum, en kontroll per etapp, och kraven för E, C och A med kryssrutor där de hör hemma.
Prov 4 · 9 mars Vad provet prövarFormen, de fyra frågetyperna med körda exempel, och sexton repetitionsfrågor.
1. Fjorton lektioner
Sju genomgångar i början, sedan mest arbetspass. Kolumnen längst till höger säger vad du gör om du var borta.
| # | Datum | Längd | Vad vi gör | Missade du passet? |
|---|---|---|---|---|
| 35 | ons 13 jan | 45 min | Vårterminen: från övningar till projekt. Projekt 1 delas ut och läses tillsammans. Vad en projektplan är, och varför den bedöms. | Uppgiften: så är den uppdelad, etapp 1, och vårens fyra projekt |
| 36 | tis 19 jan | 85 min | CRUD i praktiken. Ändra och ta bort, och listvyn med sortering och sidor i adressen. | Guiden steg 1–4, särskilt de två fällorna i steg 3 |
| 37 | ons 20 jan | 45 min | Relationer i code-first. Kategorin, den främmande nyckeln, och migrationen som kan gå sönder på din egen databas. Projektplanen committad. | Guiden steg 5–9, särskilt steg 6 |
| 38 | tis 26 jan | 85 min | LINQ: filtrera, sortera och söka. SQL-loggningen, sökningen i databasen, och varför databasen inte kan svenska. | Guiden steg 10–13 |
| 39 | ons 27 jan | 45 min | Egen validering. Ett eget attribut, en regel över två fält, och en regel som kräver databasen. | Guiden steg 14–16 |
| 40 | tis 2 feb | 85 min | Inloggning och behörighet. Identity, inloggningssidan, och att skydda sidan i stället för att dölja länken. | Guiden steg 17–23, särskilt steg 21 |
| 41 | ons 3 feb | 45 min | Kodningsstandard och dokumentation. Kodgranskning i par. | Guiden steg 24 och granskningen i etapp 4 |
| 42 | tis 9 feb | 85 min | Arbetspass. Milstolpe 1: kategorin, relationen och migrationen. | Etapp 2, med milstolpens kontroll |
| 43 | ons 10 feb | 45 min | Renderingslägen: statisk och interaktiv. Varför knapparna i en tabell inte gör något. Sportlov veckan efter. | Guiden steg 25–26 |
| 44 | tis 23 feb | 85 min | Arbetspass. Alla fyra operationerna, inför milstolpen dagen efter. | Etapp 3 |
| 45 | ons 24 feb | 45 min | Arbetspass. Milstolpe 2: alla fyra CRUD-operationerna, kontrollerade av någon annan. | Etapp 3, med milstolpens kontroll |
| 46 | tis 2 mars | 85 min | Arbetspass. Avstämning med läraren, en och en, och självgranskningen. | Etapp 4, med självgranskningen och avstämningens fyra kontroller |
| 47 | ons 3 mars | 45 min | Arbetspass och sista finputs. Uppföljningen, README.md, och vad
provet prövar. |
Etapp 5 och vad prov 4 prövar |
| 48 | tis 9 mars | 85 min | Prov 4 – databas och datadriven applikation. 80 minuter, utan dator. | Vad prov 4 prövar |
2. Det här ska sitta
- Du kan säga vilken tjänstemetod som motsvarar var och en av de fyra CRUD-bokstäverna i ditt projekt.
- Du kan förklara varför ändringssidan hämtar posten med
??=, och varför borttagning aldrig sker på en GET. - Du kan namnge de tre egenskaperna i en en-till-många-relation och säga vilken av dem som blir en kolumn.
- Du kan förklara varför navigationsegenskapen är tom utan
Include, och att det sker utan felmeddelande. - Du kan säga när en
IQueryablegår till databasen, och visa ett fall där sökningen i databasen och i C# ger olika svar. - Du kan placera en regel i rätt sorts validering: attribut,
IValidatableObjecteller en kontroll mot databasen. - Du kan skilja autentisering från auktorisering, och visa att en dold länk inte skyddar sidan.
- Du kan förklara varför knapparna i en
QuickGridinte gör något under statisk serverrendering. - Du kan skriva en projektplan, följa den upp, och säga ärligt vad som inte blev som planerat.
3. Fel som inte syns
Hittills har de flesta fel sagt ifrån: bygget misslyckas, migrationen avbryts, sidan svarar 500. Det här området har fler fel än något tidigare som inte säger någonting alls.
| Det du ser | Det som hände | Guiden |
|---|---|---|
| Ändringen sparades, sidan gick tillbaka till listan | Ändringen är borta – = i stället för ??= | Steg 3 |
| Ändringen sparades | Det blev en post till – det dolda fältet för Id saknas | Steg 3 |
| Detaljsidan ser ut som förut | Kategorin skulle ha stått där – Include saknas | Steg 7 |
| Menylänken är borta för den som är utloggad | Sidan svarar ändå, för den som vet adressen | Steg 21 |
| Utloggningsformuläret har en token | Ingen kontrollerar den, och vilken sajt som helst kan logga ut besökaren | Steg 23 |
Varje steg i guiden slutar med en kontroll. I det här området är den inte en formalitet: den är det enda sättet att se felen ovan. Och varje etapp i uppgiften har en kontroll du gör själv, med samma skäl.
4. Kom igång
Du börjar inte om. Området bygger vidare på projektet från område 5.
| Steg | Det du gör |
|---|---|
| 1 | Starta ditt projekt från område 5. Lägg till en post via formuläret, stoppa servern och starta igen. Finns posten kvar är du redo. Ny dator efter lovet? Klona repot och kör dotnet ef database update. |
| 2 | Kontrollera att dotnet ef --version svarar. Gör den inte det: dotnet tool install --global dotnet-ef, en gång. |
| 3 | Läs uppgiften från början till slut, och se hur den är uppdelad i etapper. |
| 4 | Fyll i guidens översättningstabell för din domän. Den blir första delen av projektplanen. |
| 5 | Skriv PROJEKTPLAN.md och committa den senast onsdag 20 januari – etapp 1. |
dotnet ef --version
dotnet ef database update
Mappstrukturen du är på väg mot:
DittProjekt/
├── Components/
│ ├── Layout/
│ │ └── NavMenu.razor AuthorizeView runt administrationens länkar
│ └── Pages/
│ ├── AdminPoster.razor listvyn: sortering och sidor i adressen [Authorize]
│ ├── NyPost.razor formuläret från område 5, med rullista [Authorize]
│ ├── AndraPost.razor samma formulär mot en befintlig post [Authorize]
│ ├── TaBortPost.razor bekräftelse, och en POST som tar bort [Authorize]
│ ├── Kategorisidan.razor en kategori och dess poster
│ └── LoggaIn.razor
├── Data/
│ └── DittProjektContext.cs IdentityDbContext, två DbSet
├── Migrations/ minst tre – redigeras aldrig för hand
├── Models/ huvudentiteten och kategorin
├── Services/ två tjänster, två gränssnitt
├── Validering/ ditt eget attribut
├── PROJEKTPLAN.md
├── README.md
└── UPPFOLJNING.md
Committa efter varje pass. Uppgiften kräver commits på minst åtta olika dagar, och historiken är det som visar hur arbetet gick.
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, vid sidvisningen – eller aldrig, och då är det de tysta felen ovan. Den fullständiga tabellen står i guiden.
18 rader
| Symptom | När | Trolig orsak | Åtgärd |
|---|---|---|---|
SQLite Error 19: 'FOREIGN KEY constraint failed' vid database update | migrationen | Dina egna rader fick 0 som kategori | migrations remove, HasDefaultValue med ett id som finns, ny migration. Steg 6. |
| Migrationen står som (Pending) | migrationen | database update misslyckades eller kördes aldrig | Läs felet och kör database update igen. |
The entity type 'IdentityPasskeyData' requires a primary key | migrationen | base.OnModelCreating(byggare) saknas | Lägg raden först i OnModelCreating. Steg 17. |
The seed entity for entity type … has the navigation … set | migrationen | Frödatan anger kategorin som objekt | Ange den främmande nyckeln, inte navigationsegenskapen. |
CS0182: An attribute argument must be a constant expression | bygget | Något som räknas ut i ett attributs argument | Skriv ett eget attribut. Steg 14. |
RZ10012 om AuthorizeView | bygget | @using saknas | @using Microsoft.AspNetCore.Components.Authorization i _Imports.razor. |
Cannot parse the value 'abc' as type – 500 | sidvisning | En parameter ur adressen är int? | Läs den som string? och tolka med int.TryParse. Steg 2. |
The LINQ expression … could not be translated – 500 | sidvisning | Något i Where finns inte i SQL | EF.Functions.Like, eller filtrera i C# efter hämtningen – och motivera det. |
There is no registered service of type 'SignInManager…' | sidvisning | .AddSignInManager() saknas | Sist i kedjan efter AddIdentityCore. Steg 18. |
Authorization requires a cascading parameter – 500 på varje sida | sidvisning | AddCascadingAuthenticationState saknas | En rad i Program.cs. |
Utloggad hamnar på /Account/Login och får 404 | sidvisning | ConfigureApplicationCookie saknas | LoginPath = "/konto/logga-in". Steg 18. |
| En POST svarar 400 | sidvisning | Antiforgery-token saknas | EditForm eller <AntiforgeryToken />. |
| Fel e-post eller lösenord. med rätt uppgifter | sidvisning | Användaren skapades aldrig – lösenordet var för kort | Minst åtta tecken. Kontrollera AspNetUsers. |
| Ändringen sparas inte | aldrig | = i stället för ??= | Steg 3. |
| En ändring blir en ny post | aldrig | Dolda fältet för Id saknas eller heter fel | name="Film.Id" – modellens namn, punkt, egenskapen. |
| Kategorin syns inte | aldrig | Include saknas | Steg 7. |
| Utloggad kommer åt en sida som ändrar data | aldrig | Bara menylänken är dold | [Authorize] på sidan. Steg 22. |
| Sökningen hittar inget med versaler | aldrig | SQLite viker bara A–Z | Förväntat. Välj var sökningen görs, och skriv varför. Steg 12. |
6. Orden
Orden nedan används från och med nu utan förklaring. Träna tills du kan dem – prov 4 frågar efter flera av dem i klartext.
Ordträning
| Ord | Betyder |
|---|---|
| CRUD | Create, Read, Update, Delete – de fyra sakerna man gör med data. |
| främmande nyckel | En kolumn som pekar på en rad i en annan tabell. GenreId pekar på en genre. |
| navigationsegenskap | En egenskap som håller det relaterade objektet. Ligger inte i någon kolumn, och är tom tills den beställs. |
| en-till-många | Många poster hör till en kategori. En kategori har många poster. |
| Include | Säger åt EF Core att hämta relaterad data i samma fråga. Blir en JOIN. |
| cascade delete | Tas kategorin bort, tas dess poster bort också. ON DELETE CASCADE. |
| LINQ | Metoderna Where, OrderBy, Select med flera – samma namn i C# och mot databasen. |
| IQueryable | En fråga som inte körts än. Den går till databasen först vid ToListAsync. |
| frågesträng | Delen av adressen efter ?, till exempel ?sortera=titel&sida=2. Skrivs av besökaren. |
| ValidationAttribute | Basklassen för [Required] och [Range] – och för dina egna attribut. |
| IValidatableObject | Ett gränssnitt för regler som gäller hela objektet. Körs efter attributen, och bara om de gick igenom. |
| ValidationMessageStore | Stället där formulärets fel samlas. Dit lägger du ett fel som kräver databasen. |
| Identity | ASP.NET Cores system för användare, lösenord och inloggning. |
| hash | En envägsomvandling av lösenordet. Går att jämföra med, men inte att räkna tillbaka. |
| autentisering | Att ta reda på vem du är. Inloggningen. |
| auktorisering | Att avgöra vad du får göra. [Authorize]. |
| AuthorizeView | Visar innehåll bara för den som är inloggad. Bestämmer vad som ritas, inte vad som går att nå. |
| endpoint | En adress som svarar på förfrågningar utan att vara en sida. app.MapPost. |
| antiforgery-token | Ett värde i formuläret som bevisar att det kom från din egen sajt. Skyddar bara om servern kontrollerar det. |
| open redirect | En sida som skickar besökaren vidare till en adress ur frågesträngen, också till andra sajter. |
| renderingsläge | Om en komponent renderas en gång på servern, eller hålls levande över en uppkoppling. |
| krets | Uppkopplingen och komponenten som lever på servern i interaktivt läge. |
| förrendering | Att en interaktiv komponent först renderas statiskt, så att något syns direkt. Livscykeln körs därför två gånger. |