ViewModeli i DataAnnotations Validacija

Modul 6 - Lekcija 1

Arhitektura ViewModela, robusna validacija unosa podataka i zaštita sistema

⏱️ Trajanje: ~3.5 časa | 📚 Nivo: Srednji/Napredni | 🎯 Praktični primjeri: 6

📖 Arhitektura ViewModela

ViewModel je specijalizovana C# klasa dizajnirana isključivo za prenos određenih podataka na View. Dok domenski modeli (entiteti) predstavljaju strukturu u SQL Bazi podataka (npr. Zaposlenik), ViewModel predstavlja prilagođenu strukturu podataka okrenutu korisniku na ekranu.

Zašto NE Vraćati Entitete direktno na View?

  • Mass Assignment Napadi: Haker može ručno izmijeniti HTML formu kako bi podvalio dodatna Entity polja (npr. IsAdmin=true), koju bi Kontroler spasio u Bazu.
  • Curenje Podataka (Data Leak): Slabo dizajniran API lako proslijedi cijeli entity nazad pregledniku uključujući PasswordHash iz Baze.
  • Neusklađenost (Mismatched shapes): View često zahtijeva selektirane podatke iz 3 tabele, ne možemo to utrpati u jedan Entitet koji odražava samo 1 SQL Tabelu!

⚙️ Proces Mapiranja / Prenošenja

Aplikacija sigurno preuzima podatke iz baze podataka kroz uske Data Entitete.

Zatim se u Kontroleru podaci prepisuju u ViewModel (Mapper), i isključivo se ograničena sigurna i prilagođena C# klasa proslijeđuje na Razor Stranicu.

SQL Baza Entitet Korisnik Id, JMBG PasswordHash Kontroler Mapper ViewModel KreirajKorisnikaVM Ime, JMBG Password (obični)

🏗️ Primjer iz Praxe Javne Uprave

Kao dodatak, u ViewModel klase ne ubacujemo samo gola polja. Mi im i postavljamo moćna pravila o uslovima tih vrijednosti, da bi ih HTML validirao kod klijenta a MVC osigurao na backendu!

public class SluzbenikCreateViewModel
{
    // C# Attributes dozvoljavaju da "ukrasimo" pojedinačna polja pravilima (DataAnnotations)
    [Required(ErrorMessage = "Ime zaposlenika je obavezno.")]
    [StringLength(50, MinimumLength = 2, ErrorMessage = "Ime mora imati između 2 i 50 karaktera.")]
    [Display(Name = "Ime zaposlenika")]
    public string Ime { get; set; }

    [Required(ErrorMessage = "JMBG je obavezan.")]
    [RegularExpression(@"^\d{13}$", ErrorMessage = "JMBG mora sadržavati tačno 13 cifara.")]
    public string JMBG { get; set; }

    [Required(ErrorMessage = "Odabir sektora je obavezan.")]
    [Display(Name = "Sektor rasporeda")]
    public int OdabraniSektorId { get; set; }

    // Dropdown Lista sektora - Samo za iscrtavanje Combobox-a korisniku!
    public IEnumerable<SelectListItem> DostupniSektori { get; set; }
}

✅ DataAnnotations Tabelarni Prikaz

Ovo su ključni atributi za brzu, deklarativnu validaciju nad Propertyjima.

Atribut Opis i Upotreba Primjer Sintaske
[Required] Polje ne smije ostati prazno (ili null). [Required(Error="Izbor obavezan!")]
[StringLength] Ograničava Min / Max broj karaktera. [StringLength(10, MinimumLength=2)]
[RegularExpression] Provjera putem složenih Regex paterna (Email, MAC...) [RegularExpression(@"^[a-zA-Z]+$")]
[Range] Broj ili datum unutar ograničenja. [Range(18, 65)]
[Compare] Poređenje dva stringa (Password Confirm). [Compare("LozinkaGlavna")]

🛠️ Svoji (Custom) Validation Atributi

Šta ako u MUP-u trebamo razviti provjeru algoritma Moduo 11 za JMBG standard unosa? ASP.NET nam dopušta nasljeđivanje ValidationAttribute klase.

public class SamoRadniDanAttribute : ValidationAttribute
{
    // Nadjačana metoda która će vratiti True ili False o ispravnosti 
    public override bool IsValid(object value)
    {
        if (value == null) return true; // Za Required brinu drugi atributi
        
        DateTime datum;
        if (DateTime.TryParse(value.ToString(), out datum))
        {
            if (datum.DayOfWeek == DayOfWeek.Saturday || datum.DayOfWeek == DayOfWeek.Sunday)
                return false; // Validacija pada na Vikend!
                
            return true; // Uspješan prolaz na Radne dane
        }
        return false; 
    }
}

// U VIEW MODELU KORISTITE KAO:
// [SamoRadniDan(ErrorMessage="Molimo unesite isključivo radni dan!")]
// public DateTime DatumPocetkaRada { get; set; }

✅ Zaključak

  • ViewModeli ne samo da štite SQL Bazu od hakovanja, već dramatično rasčlanjuju dizajn stranice i dopuštaju prilagodljivo kombiniranje View Parametrija nezavisno od šablona iz EF C# klase entiteta.
  • ✅ Korištenjem DataAnnotations znački nad propertijima klase (poput [Required] i [Regex]) - omogućavate automatsko provlačenje validacija u Web Pregledniku prije slanja HTTP Requesta uz istovremenu backend verifikaciju.
  • ✅ Moguće je samostalno kreirati duboke složene pravne validacije putem extenzije nad ValidationAttribute klasom.

📚 Sljedeća Lekcija

Vidjet ćemo kako pomoću 'ModelState' elementa i HTML Helpera prikažemo ove isprogramirane poruke crvenim tekstovima na ekranu!