BETA KodLabbet är under aktiv utveckling — funktioner kan förändras och fel kan förekomma.
🚧 Under utveckling — Sidan är i beta och alla funktioner fungerar inte fullt ut ännu. · Lämna gärna feedback — skriver du får du Pro gratis för att testa!
Ny plattform för kodlärande

KODLABBET: DITT NÄSTA STEG I IT-KARRIÄREN.

Lär dig programmering från grunden med interaktiva övningar och expertstöd.

60 projekt
AI-guidning
PvP-arena
XP & badges
app.js
function welcome() {
  console.log("user");
  console.log("function1");
}
 
</1——> </>
Kör →
Level upp!
+50 XP
WEBUTVECKLING
PYTHON & DATA
BACKEND / API
PVP ARENA
60
Projekt
5
Språk
AI-frågor (Pro)
100%
Gratis att starta
// vad användarna säger

Riktiga studenter. Riktiga resultat.

Mer än 2 400 kodare har redan börjat sin resa med KodLabbet.

2 418
Registrerade kodare
8 302
Projekt slutförda
147
Aktiva streaks idag
41 209
KodBot-frågor besvarade

🎁 Prova Pro gratis — inget kreditkort krävs

Lås upp ett valfritt Pro-projekt helt gratis och upplev vad Pro-planen har att erbjuda. Ingen bindningstid, inga dolda avgifter.

✅ Omedelbar åtkomst ✅ Inget kreditkort ✅ Behåll framstegen Erbjudandet gäller i 23:47:12
Sedan 89 kr/mån — avbryt när som helst
// projekt

Välj ditt nästa projekt

Bygg riktiga grejer. Anpassa varje projekt till ditt språk, ramverk och terminal.

🔍
Anpassa:
Språk
Ramverk
Terminal
Nivå:
Kategori:
Språk:

Laddar projekt...
// kunskapsbanken

📚 Kunskapsbanken

Kodreferenser, AI-verktyg, kravställning och de senaste nyheterna inom tech — allt på ett ställe.

🔍
Filtrera:

Laddar kunskapsbanken...
📡 LIVE AI-NYHETER:
Laddar senaste AI-nyheter...
🤖
KodBot
Din personliga AI-kodningsassistent
Online
👋

Hej! Jag är KodBot!

Fråga om kod, klistra in kod med fel,
eller välj ett ämne nedan.

🤖
// träningsuppgifter

Generera träningsuppgifter

Klistra in din kursplan så genererar KodBot anpassade övningar efter din nivå — eller skriv bara ett ämne, begrepp eller enstaka ord för att få riktade övningsuppgifter direkt.

0 / 5000 tecken
// priser

Enkel prissättning

Börja gratis. Uppgradera när du är redo.

Månadsvis
Årsvis Spara 40%
🌱
Gratis
Kom igång utan kostnad
kr0/mån
  • 6 projekt (nybörjare)
  • Alla tips & tricks
  • 5 AI-frågor per dag
  • JavaScript + Python
  • 🔒C# & TypeScript-projekt
  • 🔒SQL / MongoDB-projekt
  • 🔒Avancerade filter
  • 🔒Obegränsad AI-chatt
POPULÄRAST ⭐
Pro
För den seriöse kodaren
kr99/mån
Faktureras kr 599/år — spara kr 589
  • Alla 25 projekt
  • C#, SQL, MongoDB-projekt
  • Obegränsad AI-chatt
  • Alla avancerade filter
  • AI anpassad till ditt ramverk
  • Sparad chatthistorik
  • Algoritmer & designmönster
  • XP-leaderboard
🏢
Enterprise
För team och företag
kr499/mån per team
  • Allt i Pro
  • Upp till 20 användare
  • Team-dashboard & statistik
  • Anpassade projekt för ert stack
  • SSO-integration
  • Faktura-betalning

Detaljerad jämförelse

FunktionGratisProEnterprise
Antal projekt625+Obegränsad
AI-frågor/dag5
C#-projekt
SQL & MongoDB
Avancerade filter
AI anpassad till ramverk
Sparad chatthistorik
Team-funktioner

❓ Vanliga frågor

Kan jag avbryta när som helst?
Ja, du kan avbryta din Pro-prenumeration när som helst utan bindningstid. Du behåller tillgången fram till perioden slutar.
Är gratisplanen verkligen gratis för alltid?
Absolut. Gratisplanen är gratis för alltid — inga kreditkortskrav. Du får tillgång till alla gratisprojekt, dagliga utmaningar och KodBot (begränsad).
Vad händer om jag uppgraderar mitt konto?
Direkt vid uppgradering låser du upp alla 25+ projekt, obegränsad KodBot, Pro-utmaningar och prioriterad support. Din progress sparas alltid.
Passar KodLabbet mig som nybörjare?
Ja! Många projekt är byggda specifikt för nybörjare med steg-för-steg-guider och startkod. KodBot hjälper dig när du kör fast.
Vilka programmeringsspråk stöds?
JavaScript, Python och C# är primärspråken. Projekten innehåller ofta startkod i alla tre språk så du kan välja det du föredrar eller lär dig.
Hur kontaktar jag support?
Mejla oss på support@kodlabbet.com så svarar vi inom 24 timmar. Pro-användare får prioriterad support.
// utmaningar

⚔️ Kodarenas

Utmana vänner och okända kodare i realtid. Lös problem snabbast och vinn XP.

Redo att koda mot varandra? ⚔️

Skapa en privat utmaning och bjud in en vän, eller hoppa in i en öppen arena och möt slumpmässiga motståndare.

// vägledning

Programmeringskoncept

Interaktiva diagram som förklarar hur moderna system fungerar — från containrar och API:er till databaser, Git och molnet.

Utan container Din dator (Windows/Linux/Mac) App APython 3.8 App BPython 3.11Konflikt! Med container (Docker) Din dator — delar OS-kärnan Container 1App APython 3.8 Container 2App BPython 3.11 ✓ Vad finns inne i en container? Din kod(C#, Python…) Beroenden(.NET, NuGet) Inställningar(config, env) Container = Fungerar likadant överallt: på din dator, testserver, molnet

Varför använda containrar?

En container är som en låda som packar ihop din app med allt den behöver. Problemet den löser: Det funkar på min dator men inte på servern. Med Docker ser appen exakt likadan ut oavsett var den körs.

DockerKubernetesIsoleringPortabilitet
API = restaurangmeny + kypare Du(Klienten/appen) GET /weather <- {temp: 22°} API(Kyparen) Server/DB(Köket) Vanliga API-metoder (HTTP) GETHämta data POSTSkapa ny data PUT / PATCHUppdatera data DELETETa bort data Svar från API:et (statuskoder) 200 OKLyckades! 404 Not FoundHittades inte 401 UnauthorizedEj inloggad 500 Server ErrorServern kraschade

Vad är ett API?

API (Application Programming Interface) är ett sätt för program att prata med varandra. Du (appen) beställer något, kyparen (API:et) tar din order, köket (servern) levererar. Du behöver inte veta hur köket fungerar — bara vad du kan beställa.

REST APIJSONASP.NET CoreHTTP
De tre lagren i en webbsida HTMLStrukturen — skelettet<h1>, <p>, <div>= byggstenar CSSUtseendet — klädernafärg, storlek, layout= design JavaScriptBeteendet — musklernaknappar, animationer= interaktivitet WebbsidaDet du ser i webbläsaren Hur servern skickar sidan till dig Webbläsare Request <- HTML/CSS/JS Webbserver(Kestrel) Din kod (Razor/Blazor)genererar HTML

HTML, CSS och JavaScript — vad gör vad?

HTML är skelettet, CSS är kläderna och JavaScript är musklerna. I .NET genererar du HTML via Razor Pages eller Blazor på servern och skickar det till webbläsaren.

BlazorRazor PagesASP.NET CoreHTML/CSS
SQL vs NoSQL — två sätt att lagra data SQL (relationsdatabas)t.ex. SQL Server, PostgreSQLData i tabeller med rader/kolumnerRelationer mellan tabeller (JOIN)Strikta regler / schema NoSQL (dokumentdatabas)t.ex. MongoDB, CosmosDBData som JSON-dokumentFlexibelt schemaSkalas enkelt horisontellt Hur tabeller relaterar (SQL) KunderID (PK)NamnE-post 1 → många OrdrarID (PK)KundID (FK)Belopp SQL Entity FrameworkDin C#-kodvar k = db.Kunder.Where(k => ...) Entity Framework översätter C#-kod till SQL automatiskt

SQL eller NoSQL — vad ska jag välja?

I .NET-världen är SQL Server + Entity Framework Core det vanligaste. SQL passar när du har tydliga relationer (kund har många ordrar). NoSQL passar när datan ser olika ut per post eller behöver skalas enormt.

Entity FrameworkSQL ServerLINQMigrations
Autentisering vs auktorisering Autentisering (AuthN)VEM är du? Logga in, verifiera identitetExempel: lösenord / BankID Auktorisering (AuthZ)VAD får du göra? Roller, rättigheterExempel: Admin vs vanlig användare JWT-token — hur inloggning fungerar i moderna appar Användare loggar in Auth-serververifierar, ger token JWT-tokenHeader.Payload.Sign skickas med Ditt APIvaliderar, ger svar

Autentisering i .NET — vad ska du använda?

I ASP.NET Core används JWT Bearer tokens för API:er och Cookie-autentisering för webbsidor. För Google/Microsoft-inloggning finns OAuth 2.0. ASP.NET Identity är ett färdigt system för användare, roller och lösenord.

ASP.NET IdentityJWT BearerOAuth 2.0Roller
Tre nivåer av molntjänst IaaSInfrastruktur som tjänstDu får: servrar, nätverkDu sköter: OS, app, dataEx: Azure VMSom: hyra ett tomt PaaSPlattform som tjänstDu får: OS + runtimeDu sköter: bara appenEx: Azure App ServiceSom: hyra en lägenhet SaaSProgramvara som tjänstDu får: hela produktenDu sköter: ingetEx: Microsoft 365Som: bo på hotell Viktiga Azure-tjänster för .NET-utvecklare App ServiceDriftsätt .NET-app Azure SQLMolndatabas Blob StorageFiler, bilder Service BusMeddelanden CI/CD: Git push → GitHub Actions bygger → testar → driftsätter

Molnet för .NET-utvecklare

Azure är Microsofts moln och det naturliga valet för .NET-appar. Med Azure App Service driftsätter du appen med ett klick. GitHub Actions eller Azure DevOps automatiserar hela pipeline från kodpush till produktion.

AzureApp ServiceGitHub ActionsCI/CD
Git — tre zoner du alltid arbetar i Working directoryDina filer på diskÄndrade men ej sparade git add Staging areaFörberedda ändringarVälj vad som sparas git commit RepoHistoriksparad Branches — arbeta parallellt utan att störa main main (produktion)Stabil, klar kod feature/ny-funktionJobba isolerat här merge main (uppdaterad)Ny funktion inne De viktigaste Git-kommandona git clone/pullHämta kod git add/commitSpara ändring git pushSkicka till GitHub Pull RequestKodgranskning

Git — det viktigaste att komma ihåg

Git spårar ändringar så att du kan gå tillbaka i historiken, arbeta parallellt med kollegor via branches och slå ihop med merge. GitHub lagrar koden. Flöde: branch → koda → commit → push → Pull Request → merge.

GitGitHubBranchesMerge conflicts
En klass är ritningen — objekt är de byggda husen Klass: Bil Ritningen / mallen Egenskaper (fields/props) string Marke int Hastighet void Kora() – metod new Bil() Objekt 1Marke = "Volvo" Hastighet = 120 Objekt 2Marke = "BMW" Hastighet = 200 Objekt 3Marke = "Tesla" Hastighet = 250 Konstruktor Körs när objektet skapas public Bil(string marke) Marke = marke; this Pekar på det aktuella objektet Klassen = koden du skriver. Objektet = det som lever i minnet när programmet kör.
public class Bil
{
    public string Marke { get; set; }
    public int Hastighet { get; set; }

    public Bil(string marke, int hastighet)
    {
        Marke = marke;
        Hastighet = hastighet;
    }

    public void Kora() => Console.WriteLine($"{Marke} kör!");
}

// Skapa objekt
var b1 = new Bil("Volvo", 120);
var b2 = new Bil("Tesla", 250);
b1.Kora(); // "Volvo kör!"

Klass och objekt — grunden i OOP

En klass är som en husbeskrivning — den berättar hur ett hus ska se ut. Objekt är de faktiska husen byggda från beskrivningen. Du kan skapa hur många objekt du vill från samma klass, och varje objekt har sina egna värden.

classnewkonstruktorproperties
Inkapsling — gom internerna, visa bara det nödvändiga Klass: BankKonto private decimal _saldo ← ingen utifrån kan se/ändra protected string _agare ← bara arv-klasser ser public void SattIn(decimal belopp) ← alla kan använda UtsidanDin kod / API KAN EJ KAN Property get = läs saldo set = validera innan ändring Inkapsling skyddar data från felaktig användning — saldo ska inte kunna bli negativt
public class BankKonto
{
    private decimal _saldo;          // ingen utanför klassen ser detta

    public decimal Saldo             // property – kontrollerad åtkomst
    {
        get => _saldo;
        private set => _saldo = value >= 0 ? value : 0;
    }

    public void SattIn(decimal belopp)
    {
        if (belopp > 0) Saldo += belopp;
    }

    public bool TaUt(decimal belopp)
    {
        if (belopp > Saldo) return false;
        Saldo -= belopp;
        return true;
    }
}

var konto = new BankKonto();
konto.SattIn(1000);
konto.TaUt(200);
// konto._saldo = -999; ← KOMPILERINGSFEL! private

Inkapsling — varför gömma data?

Utan inkapsling kan vem som helst sätta konto.Saldo = -99999. Med private tvingar du all kod att gå genom dina metoder, där du kan validera och kontrollera. Det gör koden tryggare och lättare att ändra internt utan att påverka resten av systemet.

privateprotectedpublicinternal
Arv — barn-klassen får allt från föräldern + eget Basklass: Djur string Namn – int Alder void At() – void Sov() virtual void LaterLjud() arver arver Hund : Djur + string Ras (eget) override LaterLjud() → "Vov!" Katt : Djur + bool InneKatt (eget) override LaterLjud() → "Mjau!" Fagel : Djur + double Vingspann override LaterLjud() → "Tweet!"
public class Djur
{
    public string Namn { get; set; }
    public int Alder { get; set; }

    public void At() => Console.WriteLine($"{Namn} äter.");
    public virtual void LaterLjud() => Console.WriteLine("...");
}

public class Hund : Djur        // Hund ärver Djur
{
    public string Ras { get; set; }
    public override void LaterLjud() => Console.WriteLine("Vov!");
}

public class Katt : Djur
{
    public override void LaterLjud() => Console.WriteLine("Mjau!");
}

var h = new Hund { Namn = "Fido", Ras = "Labrador" };
h.At();        // "Fido äter."   ← ärvd från Djur
h.LaterLjud(); // "Vov!"         ← overridad i Hund

Arv — skriv kod en gång, använd överallt

Med arv slipper du kopiera kod. Allt som är gemensamt (namn, ålder, äta, sova) skrivs en gång i basklassen. Varje barn-klass lägger bara till det som är unikt för den. virtual + override låter barn-klassen byta ut en metods beteende. Obs: C# stöder bara ett arv — en klass kan bara ärva från en basklass.

virtualoverridebasesealed
Polymorfism — samma anrop, olika beteende Lista av Djur Hund, Katt, Fågel i samma lista LaterLjud() Hund → "Vov!" Katt → "Mjau!" Fågel → "Tweet!" Runtime bestämmer C# tittar på objektets verkliga typ när programmet kör = "dynamisk dispatch" Overloading — samma metodnamn, olika parametrar void Skriv(int x) void Skriv(string s) Overloading vs overriding Overloading = samma namn, olika signatur (compile-time)
// Polymorfism — en lista med blandade djur
List<Djur> djur = new()
{
    new Hund { Namn = "Fido" },
    new Katt { Namn = "Misse" },
    new Fagel { Namn = "Tweety" }
};

foreach (var d in djur)
{
    d.LaterLjud(); // C# väljer rätt metod automatiskt!
}
// Vov!
// Mjau!
// Tweet!

// Overloading — samma namn, olika parametrar
public void Skriv(int tal)    => Console.WriteLine(tal);
public void Skriv(string text) => Console.WriteLine(text);
public void Skriv(int x, int y) => Console.WriteLine($"{x},{y}");

Polymorfism — magin i OOP

Polymorfism låter dig skriva generell kod som fungerar med alla typer som ärver från basklassen. Du kan lägga till en Orm-klass i framtiden och loop-koden ovan fungerar fortfarande utan ändringar — den vet inte och behöver inte veta vilken typ det är.

virtual/overrideList<Basklass>overloading
Interface — ett kontrakt: "du MÅSTE ha dessa metoder" interface INotifierare void SkickaNotis(string med) bool ArTillganglig() Bara kontrakt — ingen kod implementerar EpostNotifierare SkickaNotis → e-post via SMTP SmsNotifierare SkickaNotis → SMS via Twilio PushNotifierare SkickaNotis → push till app
public interface INotifierare
{
    void SkickaNotis(string meddelande);
    bool ArTillganglig();
}

public class EpostNotifierare : INotifierare
{
    public void SkickaNotis(string med) => SendEmail(med);
    public bool ArTillganglig() => true;
}

public class SmsNotifierare : INotifierare
{
    public void SkickaNotis(string med) => SendSms(med);
    public bool ArTillganglig() => CheckSmsGateway();
}

// Din service beror bara på interfacet — lätt att byta!
public class OrderService
{
    private readonly INotifierare _notis;
    public OrderService(INotifierare notis) => _notis = notis; // DI
    public void PlaceraOrder() => _notis.SkickaNotis("Order klar!");
}

Interface — varför inte bara arv?

Till skillnad från arv kan en klass implementera hur många interface som helst. Interface är perfekta för Dependency Injection — din kod beror på INotifierare, inte på en specifik klass. Det gör det trivialt att byta implementation eller mocka i tester. Namnge alltid interface med stort I: IRepository, ILogger.

interfaceDItestbarhetkontrakt
Abstrakt klass — halvfärdig basklass abstract class Rapport Kan EJ skapas direkt med new Rapport() void SkrivUt() – KLAR kod (används av alla) abstract string GenereraInnehall() – MÅSTE overridas PdfRapport : Rapport override GenereraInnehall() → PDF-formaterat ExcelRapport : Rapport override GenereraInnehall() → Excel-formaterat
public abstract class Rapport
{
    public string Titel { get; set; }

    // Klar metod – används av ALLA subklasser
    public void SkrivUt()
    {
        Console.WriteLine($"=== {Titel} ===");
        Console.WriteLine(GenereraInnehall()); // anropar subklassens version
    }

    // Abstrakt – MÅSTE overridas av subklassen
    public abstract string GenereraInnehall();
}

public class PdfRapport : Rapport
{
    public override string GenereraInnehall() => "PDF-formaterat innehall...";
}

public class ExcelRapport : Rapport
{
    public override string GenereraInnehall() => "Excel-formaterat innehall...";
}

var r = new PdfRapport { Titel = "Arsredovisning" };
r.SkrivUt();
// === Arsredovisning ===
// PDF-formaterat innehall...

Abstrakt klass vs interface — när vilket?

Abstrakt klass: när subklasserna delar gemensam kod + har egna implementationer. Interface: när du bara vill definiera ett kontrakt utan delad kod, eller när en klass behöver "vara" flera saker. Tumregel: föredra interface i moderna C#-projekt — de är mer flexibla och testbara.

abstractoverrideTemplate Method
Abstrakt klass
Kan ha fält och kod
En per klass (arv)
Har konstruktor
Bra: Template Method
Interface
Bara kontrakt (C# 8+: default)
Obegränsat per klass
Ingen konstruktor
Bra: DI, testning
Monolit vs microservices Monolit Allt i en app + Enkelt att starta med + Enkel att debugga - Svarskalas separat - En krasch slår ut allt - Lång byggtid växer till Microservices Många små oberoende tjänster Order-tjänst Auth-tjänst Notis-tjänst + Skalas, driftsätts och uppdateras separat Hur tjänster pratar med varandra Synkront (HTTP/REST) Tjänst A anropar tjänst B direkt API Gateway En ingångspunkt utifrån Asynkront (Message bus) Events via kö — RabbitMQ, SB Varje microservice har sin EGEN databas — de delar aldrig databas med varandra I .NET: varje tjänst är en ASP.NET Core Web API i sin egen Docker-container

Microservices — när ska du använda dem?

Microservices passar stora system med många team. Varje tjänst kan driftsättas, skalas och uppdateras oberoende. Nackdelen är ökad komplexitet: nätverkskommunikation, distribuerade transaktioner och övervakning kräver mer arbete än en monolit.

DockerAPI GatewayRabbitMQService Bus
Caching — spara svar så du slipper fråga igen Din app frågar CacheSnabbt minne Cache HIT — svar direkt! Cache MISS — hämta från DB DB Tre nivåer av cache In-memory cacheI appens minneSnabbast, försvinner vid restart Distribuerad cachet.ex. RedisDelas mellan flera servrar HTTP cacheI webbläsaren / CDNCache-Control-header Vad man INTE ska cacha Känslig dataLösenord, tokens, kort Data som ändras oftaStale data = fel svar TTL — hur länge?Sätts per datatyp Tumregel: cacha data som läses ofta men sällan ändras

Caching i .NET

ASP.NET Core har inbyggt stöd för IMemoryCache (in-process) och IDistributedCache (t.ex. Redis). Redis är det vanligaste valet när du har flera instanser av din app. Cacha data som läses ofta men sällan ändras — t.ex. produktlistor, konfiguration, sökresultat.

IMemoryCacheRedisStackExchange.RedisTTL
Testpyramiden — tre nivåer av testning E2E-tester Få, långa, dyra Integrationstester Testar flera delar ihop (API + DB) Några Unit-tester Många, snabba, billiga — testar en funktion i taget Många Arrange — Act — Assert (AAA-mönstret) Arrange: förbered data | Act: kör koden | Assert: kontrollera resultatet

Testning i .NET — verktyg och mönster

I .NET-ekosystemet är xUnit det vanligaste ramverket för unit tests. Moq används för att "mocka" beroenden (t.ex. en databas) så att du kan testa en klass isolerat. Integrationstester i ASP.NET Core görs med WebApplicationFactory som startar hela appen i minnet. Sträva efter många snabba unit tests och färre långsamma integrationstester.

xUnitMoqFluentAssertionsWebApplicationFactory
Fyra design patterns du möts ofta i .NET Repository pattern Gömmer databaskoden bakom ett lager Service → IProductRepo → ProductRepo Lätt att byta databas eller mocka i test Vanlig i .NET med Entity Framework Dependency Injection Skicka beroenden utifrån, skapa inte själv Inbyggt i ASP.NET Core (services) builder.Services.AddScoped<IRepo, Repo>() Gör koden testbar och utbytbar Singleton Exakt en instans i hela appen services.AddSingleton<ICache, Cache>() Bra för: cache, konfiguration, logger Obs: trådsäkerhet måste hanteras Factory pattern Skapa objekt utan att veta exakt typ ShapeFactory.Create("circle") Bra för: plugins, parsers, notiser Döljer skapandelogiken SOLID — fem principer bakom alla patterns S: En uppgift O: Öppen/stängd L: Ersättbar I: Sma interface D: Beroenden Förklara SOLID

Design patterns — varför lära sig dem?

Design patterns är beprövade lösningar på vanliga problem. Du behöver inte memorera dem alla — men Repository och Dependency Injection möter du i nästan varje .NET-projekt. DI är inbyggt i ASP.NET Core och är grunden till hur hela ramverket fungerar. Lär dig dessa två först, resten kommer naturligt.

RepositoryDISingletonFactorySOLID
Synkront (blockerar) Tråden jobbar BLOCKERAD – väntar på DBIngen annan kan använda tråden Tråden jobbar igen Asynkront (frigörs) Tråden jobbar await – tråden FRIGJORD Tråden hanterar andra requests DB klar → fortsätter här TaskInget returvärde Task<T>Lovar ett värde T ValueTaskPresterande variant CancellationTokenAvbryt pågående jobb

Regel: om en metod gör I/O (DB, HTTP, fil) – gör den async. Annars blockerar du tråden i onödan.

// SYNKRONT – blockerar tråden
public string HämtaData()
{
    var result = db.Users.ToList();  // tråden väntar här
    return result;
}

// ASYNKRONT – frigörs tråden under väntan
public async Task<List<User>> HämtaDataAsync(CancellationToken ct)
{
    var result = await db.Users.ToListAsync(ct);  // tråden är fri!
    return result;
}

// Parallellt – flera saker samtidigt
public async Task ParallellAsync()
{
    var t1 = HämtaAnvändareAsync();
    var t2 = HämtaProdukterAsync();
    await Task.WhenAll(t1, t2);  // båda kör samtidigt!
}

// Vanligt misstag – .Result blockerar och kan deadlocka!
var data = HämtaDataAsync().Result;  // GÖR INTE SÅ
var data = await HämtaDataAsync();   // GÖR SÅ ISTÄLLET

Async/await – varför är det viktigt?

En webbserver har ett begränsat antal trådar. Om varje request blockerar sin tråd medan den väntar på databasen kan servern bara hantera några tiotal requests samtidigt. Med async/await frigörs tråden och kan hantera hundratals requests parallellt – utan extra trådar.

async/awaitTaskWhenAllCancellationToken
De vanligaste säkerhetshoten i webbutveckling SQL InjectionAngriparen skickar SQL i ett formulärSkydd: parametriserade queries / EF Core XSS – Cross-Site ScriptingAngriparen injicerar JavaScript i sidanSkydd: HTML-encode utdata, CSP-header CSRF – förfalskad requestOnd sajt gör request i ditt namnSkydd: Anti-forgery token (inbyggt i MVC) CORSWebbläsaren blockerar cross-origin-requestsSkydd: tillåt bara kända ursprung Din webbläsare Krypterad data (ingen kan läsa) Din server
// SQL Injection – GÖR INTE SÅ
var sql = $"SELECT * FROM Users WHERE Name = '{input}'";
// Om input = "'; DROP TABLE Users;--" → katastrof!

// GÖR SÅ – parametriserad query (EF Core)
var user = await db.Users
    .Where(u => u.Name == input)  // EF skyddar automatiskt
    .FirstOrDefaultAsync();

// XSS – Razor HTML-encodar automatiskt
<p>@Model.AnvändarInput</p>           // SÄKER – encodas
<p>@Html.Raw(Model.AnvändarInput)</p> // FARLIG – kör rå HTML

// CORS i ASP.NET Core
builder.Services.AddCors(opt => opt.AddPolicy("MittAPI", p =>
    p.WithOrigins("https://minapp.se")
     .AllowAnyMethod()
     .AllowAnyHeader()));

// HTTPS-omdirigering
app.UseHttpsRedirection();
app.UseHsts();

Säkerhet – den viktigaste regeln

Lita aldrig på indata från användaren. Validera, sanitera och encoda alltid. EF Core och Razor skyddar dig mot de vanligaste attackerna automatiskt – men du måste förstå varför, så att du inte kringgår skyddet av misstag med Html.Raw eller råa SQL-strängar.

SQL injectionXSSCSRFHTTPSCORS
Vad händer när du skriver "google.se" i webbläsaren? 1. DNS-uppslag"google.se" → IP 2. TCP-kopplingSYN → SYN-ACK → ACK 3. TLS-handskakKrypterar förbindelsen 4. HTTP reqGET /sida HTTP/2 Nätverkslagren – OSI-modellen förenklad 7. Applikation – HTTP, SMTP, DNS (det du ser) 4. Transport – TCP (tillförlitlig) / UDP (snabb) 3. Nät – IP-adresser, routing mellan nätverk 1–2. Fysiskt – kabel, WiFi, ethernetpaket 80=HTTP 443=HTTPS 22=SSH 5432=PostgreSQL 1433=SQL Server 6379=Redis
// DNS-uppslag i C#
var addresses = await Dns.GetHostAddressesAsync("google.se");

// HTTP-request i C# med HttpClient
var client = new HttpClient();
var response = await client.GetAsync("https://api.example.com/data");
var json = await response.Content.ReadAsStringAsync();

// Kontrollera statuskod
if (response.IsSuccessStatusCode)
    Console.WriteLine("OK!");
else
    Console.WriteLine($"Fel: {response.StatusCode}");

// TCP-socket (lågnivå – sällan behövs direkt)
using var socket = new TcpClient("example.com", 80);
// HttpClient hanterar allt detta åt dig automatiskt

Nätverk – vad en .NET-utvecklare behöver veta

Du behöver inte kunna bygga en router – men att förstå DNS (namn → IP), TCP (tillförlitlig koppling), HTTP (protokollet ovanpå) och portar hjälper enormt när saker inte fungerar. HttpClient i .NET sköter allt detta åt dig, men det är guld värt att förstå vad som händer under huven.

HttpClientDNSTCP/IPPortar
Stack vs Heap – var lever din data? StackSnabbt, automatiskt, begränsat int x = 5 (värdetyp) bool aktiv = true Pekare till heap-objekt Rensar sig själv när metod avslutas HeapStörre, dynamiskt, GC hanterar new Bil() (referenstyp) string, List, array, klass Allt du skapar med new GC söker upp och rensar Garbage Collector – automatisk minnesstädning Generation 0Nya objekt – rensas ofta Generation 1Överlevt Gen 0 Generation 2Långlivade objekt – rensas sällan
// Värdetyper (struct) – bor på stack
int x = 42;
bool aktiv = true;
DateTime now = DateTime.Now;

// Referenstyper (class) – bor på heap
var bil = new Bil("Volvo");   // "bil"-variabeln på stack pekar på heap
var lista = new List<int>();

// IDisposable – frigör ej-hanterade resurser (filer, DB, HTTP)
// using-satsen anropar Dispose() automatiskt när blocket avslutas
using var fil = File.OpenRead("data.txt");
using var conn = new SqlConnection(connStr);
// Dispose() anropas automatiskt här – även vid exception

// Många kopior vs delad referens
int a = 5;
int b = a;   // kopia – b = 5, ändrar a påverkar inte b

var bil1 = new Bil("Volvo");
var bil2 = bil1;   // SAMMA objekt! ändrar bil2 → ändrar bil1 också

Minneshantering – vad du behöver tänka på

.NET sköter minneshantering automatiskt via Garbage Collector – du behöver sällan tänka på det. Men du måste använda using för resurser som databasanslutningar, filer och HTTP-klienter, annars läcker de. Förstå skillnaden mellan värdetyper (kopieras) och referenstyper (delas) – det förklarar många konstiga buggar.

GCIDisposableusingstruct vs class
Big O – hur snabbt växer problemet? O(1)Konstant – bäst O(log n)Binär sökning O(n)Linjär – en loop O(n log n)Merge sort O(n²)Dubbla loopar – undvik Datastrukturer – när använder man vad? List<T>Ordnad samlingLäs: O(1) Sök: O(n)Bra: generell lista Dictionary<K,V>Nyckel → värdeSök: O(1) – supersnabbtBra: uppslagstabeller HashSet<T>Unika värdenInnehåller: O(1)Bra: dubbletter Queue/StackFIFO / LIFOLägg/ta: O(1)Bra: köhantering Vanliga sökalgoritmer Linjär sökning O(n)Gå igenom ett i taget – enkel men långsammare Binär sökning O(log n)Halvera utrymmet varje steg – krav: sorterat
// Dictionary – O(1)-uppslag
var priser = new Dictionary<string, decimal>
{
    ["Mjölk"] = 15.90m,
    ["Bröd"] = 29.50m
};
decimal pris = priser["Mjölk"];   // O(1) – blixtsnabbt

// HashSet – kontrollera unikhet O(1)
var besökta = new HashSet<int>();
besökta.Add(42);
bool finnsDen = besökta.Contains(42);   // O(1)

// List – O(n) sökning – använd bara när ordning spelar roll
var lista = new List<string> { "A", "B", "C" };
bool finns = lista.Contains("B");   // O(n) – går igenom alla

// Binär sökning på sorterad lista
var sorterad = new List<int> { 1, 3, 5, 7, 9, 11 };
int index = sorterad.BinarySearch(7);   // O(log n)

// LINQ använder rätt algoritm internt
var snabb = dict.ContainsKey("Mjölk");       // O(1)
var långsammare = lista.Any(x => x == "B");  // O(n)

Algoritmer – den praktiska kunskapen

Du behöver inte implementera quicksort från grunden, men du måste veta att Dictionary.ContainsKey är O(1) medan List.Contains är O(n) – det är skillnaden mellan en app som svarar på millisekunder och en som hänger sig under last. Välj rätt datastruktur för rätt problem.

DictionaryListHashSetBig O
try/catch/finally – fånga fel innan de kräschar appen tryKod som kankasta exceptionKörs alltid fel! catchFångar och hanterarSpecifik typ förstException sist (generell) finally – körs ALLTID, oavsett om det gick bra eller inteStäng filer, databasanslutningar – cleanup-kod Result-mönstret – alternativ till exceptions för väntade fel Exception – för oväntade felNullRef, filsaknas, nätverkskrasch Result<T> – för väntade felFel login, validering, affärslogik
// Try/catch/finally
public async Task<User> HämtaAnvändareAsync(int id)
{
    try
    {
        return await db.Users.FindAsync(id)
            ?? throw new NotFoundException($"Användare {id} hittades inte");
    }
    catch (NotFoundException)
    {
        throw;  // Skicka vidare – låt anroparen hantera
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "Oväntat fel vid hämtning av användare {Id}", id);
        throw;
    }
    finally
    {
        // Körs ALLTID – bra för cleanup
    }
}

// Eget exception
public class NotFoundException : Exception
{
    public NotFoundException(string msg) : base(msg) { }
}

// Result-mönstret – inga exceptions för kända fel
public record Result<T>(T? Value, string? Error, bool IsSuccess);

public Result<User> LoggaIn(string epost, string lösenord)
{
    var user = db.Users.FirstOrDefault(u => u.Epost == epost);
    if (user == null) return new(null, "Användare finns ej", false);
    if (!VerifyPassword(lösenord, user.Hash))
        return new(null, "Fel lösenord", false);
    return new(user, null, true);
}

// Anroparen kollar resultatet – inga try/catch behövs
var result = LoggaIn("test@test.se", "abc");
if (result.IsSuccess)
    Console.WriteLine($"Välkommen {result.Value!.Namn}!");
else
    Console.WriteLine($"Fel: {result.Error}");

Felhantering – exceptions vs Result

Kasta exceptions för oväntade fel (nätverkskrasch, null-referens, saknad fil). Använd Result-mönstret för väntade affärslogik-fel (fel lösenord, validering, resurs hittades inte). Fånga aldrig Exception och svälj felet tyst – logga alltid. finally garanterar städning oavsett vad som händer.

Exceptiontry/catchResult<T>finally
Hur allt hänger ihop i ett modernt system AnvändareBrowser / App FrontendHTML / Blazor APIASP.NET Core BackendAffärslogik (C#) DatabasSQL / Entity FW Allt körs i... Docker-containrarFungerar likadant lokalt, test och i molnet (Azure / AWS)

Alla delar ihop

I ett modernt system: Användaren ser en HTML-sida, som pratar med ett API, som kör C#-kod, som hämtar data från en databas — allt packat i containrar för att köras var som helst.

// daglig utmaning

🔥 Dagens utmaning

En ny koduppgift varje dag. Bygg din streak och tjäna bonus-XP!

0
🔥 Streak
0
🏅 Bäst
0
✅ Totalt
0
⚡ XP idag
AKTIVITETSKALENDER
TIDIGARE UTMANINGAR

🏅 Badges

📅 Aktivitet (30 dagar)

📁 Mina projekt

📋 Kursuppgifter

Nytt lösenord

Välj ett nytt lösenord för ditt konto.

Tillbaka till inloggning

Logga in

Välkommen tillbaka!

Inget konto? Skapa ett gratis
🔒

Pro-funktion

Kräver Pro-konto.

Pro inkluderar:
  • ✅ Alla 25 projekt (C#, SQL, MongoDB...)
  • ✅ Obegränsad AI-chatt
  • ✅ Avancerade kategorifilter
  • ✅ AI anpassad till ditt ramverk
7 dagar gratis. Avbryt när som helst.

Ny utmaning

Välj språk, skriv en utmaning eller låt AI skapa en åt dig.

🌐 Öppen
👥 Bara vänner
📩 Bjud in specifik

Admin

KodLabbet kontrollpanel

✍️ Skriv en recension

Hjälp andra kodare — dela din upplevelse av KodLabbet

0 / 500

⌨️ Kortkommandon

Navigering
Hem
GH
Projekt
GP
Dashboard
GD
KodBot
GK
Priser
G$
Sökning & Övrigt
Projektsökning
/
Stäng modal
Esc
Visa kortkommandon
?
Växla tema
T

✏️ Redigera profil

⚙️ Notis-inställningar
E-post
Push
In-app

Redigera användare

Lämna feedback

Sidan är i beta — din åsikt hjälper oss förbättra. Skickar du feedback ger vi dig Pro-access gratis så du kan testa allt!

eller
Skriv på LinkedIn istället