web programiranje

Post on 15-Oct-2021

7 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Web programiranjeDr. Goran Aritonović

goran.aritonovic@bpa.edu.rs

kabinet 211

Softver

• Visual Studio 2019 (16.4 ili noviji)

• Visual Studio Code

• SQL Server 2019 (2017) Express

• SQL Server Management Studio Express

2

Uvod u ASP.NET core MVC web aplikacije

ASP.NET Core

• ASP.NET Core je besplatan, open-source web framework

• ASP.NET Core je modularni framework i radi na Windows, Linux, ili Macoperativnom sistemu

• Inicijalni naziv je bio ASP.NET 5 ali mu je ime promenjeno u ASP.NET Core 1.0(Jun 2016)

• Verzija ASP.NET Core 3.1 (decembar 2019)

• Isporučuje se u vidu Nuget paketa

• Omogućava kreiranje web aplikacija i web API-ja

• Lako se integriše sa različitim klijentskim tehnologijama

• Koristi Model-View-Controller (MVC) pattern

4

MVC patern

Models

Modeli su skup klasa koje

opisuju podatke sa kojima

radimo.

Views

Pogledi su komponente

koje generišu korisnički

interfejs aplikacije

MVC patern uključuje sledeće komponente:

Controllers

Kontroleri su komponente koje

upravljaju korisničkim zahtevima,

rade sa modelom, i odabiraju pogled

kome prosleđuju podatke

5

Kreiranje ASP.NET Core web aplikacije -1

6

Kreiranje ASP.NET Core web aplikacije -2

7

Kreiranje ASP.NET Core web aplikacije -3

8

Struktura ASP.NET Core web aplikacije

9

Fajl .csproj

10

Fajl .csproj

11

<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup><TargetFramework>netcoreapp3.1</TargetFramework>

</PropertyGroup>

</Project>

Folder properties fajl launchSettings.json

12

{"iisSettings": {

"windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": {

"applicationUrl": "http://localhost:51651","sslPort": 0

}},"profiles": {

"IIS Express": {"commandName": "IISExpress","launchBrowser": true,"environmentVariables": {

"ASPNETCORE_ENVIRONMENT": "Development"}

},"WebAspCoreUvod": {

"commandName": "Project","launchBrowser": true,"applicationUrl": "http://localhost:5000","environmentVariables": {

"ASPNETCORE_ENVIRONMENT": "Development"}

}}

}

Podešavanje profila

13

Desni klik na projekat-> Properties -> Debug tab

Folder wwwroot

• Unutar podfoldera foldera wwwroot čuvaju se statički fajlovi

• Unutar klase Startup potrebno je omogućiti pristup statičkim fajlovima (konfigurisati middleware)

• Svi fajlovi unutar foldera wwwroot su javno dostupni

14

Fajl Program.cs

15

public class Program{

public static void Main(string[] args){

CreateHostBuilder(args).Build().Run();}

public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args)

.ConfigureWebHostDefaults(webBuilder =>{

webBuilder.UseStartup<Startup>();});

}

Fajl Program.cs

• ASP.NET Core web aplikacija je konzolna aplikacija koj počinje izvršavanja od metode Main() u klasi Program

• Unutar Main() metode se kreira host za aplikaciju

• Default konfiguracija koristi Kestrel web server, koristi IISintegraciju i čita konfiguraciona setovanja iz appsettings.json

• Kestrel web server je podrazumevano uključen u ASP.NET Core projekt šablone

16

Kestrel web server

17

• Kestrel ne podržava deljenje iste IP adrese i porta izmešu više aplikacija• Ne može da hostuje više web sajtova na istoj IP adresi i portu

• Integracija sa IIS web serverom• Reversni proxy server (IIS) prima HTTP zahteve sa interneta i prosleđuje ih kestrelu vršeći

prethodno neku obradu• Scenario koji zahteva reverzni proxy je kada imamo više aplikacija koje dele istu IP adresu i port i

rade na istom serveru

IoC (Inversion of Control) princip dizajna koda

• IoC je princip gde se kontrola toka programa invertuje, umesto da korisnički kod kontroliše tok programa i poziva biblioteke, to radi eksterni framework

• DI (Dependency Injection) dizajn pattern implementira IoC princip koji omogućava kreiranje slabo uparenih klasa

• IoC kontejner je framework koji upravlja automatskim ubacivanjem zavisnosti u aplikaciji tako da programer ne mora voditi računa o tome

• ASP.Core ima ugrađen Dependency Injection container18

Klasa Startup

• Izvršava se kada aplikacija startuje

• Klasa Startup ima dve javne metode ConfigureServices i Configure.

• Metoda ConfigureServices se koristi za registraciju klasa od kojih zavise neke druge klase - servisa

• Servis je klasa koja će biti korišćena u drugoj klasi

• Nakon registracije servis se može koristiti bilo gde u aplikaciji

• U aplikaciji je samo potrebno da u konstruktoru zavisne klase kao parametar definišemo referencu tipa servisa. Okruženje će je automatski ubaciti.

• ConfigureServices metoda kao ulazni parametar ima IServiceCollection koji omogućava registraciju servisa u IoC kontejneru

19

Metoda ConfigureServices

Metoda AddControllersWithViews () konfiguriše servise za uobičajene karakteristike za kontrolere sapogledima

20

public void ConfigureServices(IServiceCollection services){

services.AddControllersWithViews();}

Middleware

• ASP.NET Core uvodi koncept koji se zove middleware

• Middleware je komponenta (klasa) koja se izvršva pri svakom zahtevu

• Middleware se sastoji od komponenti koje obrađuju zahtev putem protočne obrade

• Middleware se konfiguriše unutar Configure metode Startup klase

• Redosled kojim su komponente dodate u metodu Configure određuju redosled kojim se pozivaju pri obradi zahteva i obrnutom redosledu pri odgovoru. Ovaj redosled je bitan za sigurnost, perfomanse aplikacije i njenu funkcionalnost.

21

Protočna obrada zahteva

• Zahtev se prosleđuje od jedne do druge komponente

• Svaka komponenta može odlučiti da ne prosledi zahtev sledećoj komponenti što se zove kratko spojanje protočne obrade zahteva

• Kratko spajanje je često poželjno jer se izbegava nepotreban rad.

• Npr. komponenta za obradu statičkih fajlova može vratiti zahtev za statičkim fajlom i prespojiti ostatak protočne obrade.

22

Metoda Configure()

23

public void Configure(IApplicationBuilder app, IWebHostEnvironment env){

if (env.IsDevelopment()){

app.UseDeveloperExceptionPage();}else{

app.UseExceptionHandler("/Home/Error");}app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>{

endpoints.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");

});}

Metoda Configure()

• Ova metoda specificira kako aplikacija odgovara na HTTP zahteve

• Unutar ove klase se vrši protočna obrada zahteva, postoji tzv. request pipeline

• Metoda Configure ima dva ulazna parametra IApplicationBuilder i IHostingEnvironment.

• IApplicationBuilder obezbeđuje mehanizam da se konfiguriše protočna obrada

• IHostingEnvironment obezbeđuje informacije o okruženju u kome se aplikacija hostuje

• Metoda ConfigureServices() se poziva pre Configure() metode

24

Prvo pokretanje ASP.NET Core web aplikacije

25

Prvo pokretanje ASP.NET Core web aplikacije

26

ViewData i ViewBag

Klasa HomeController.cs

28

public class HomeController : Controller{

public IActionResult Index(){

return View();}

}

Index pogled klase HomeController

29

@{

ViewData["Title"] = "Home Page";

}

<div class="text-center">

<h1 class="display-4">Welcome</h1>

<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET

Core</a>.</p>

</div>

ViewData

•ViewData je rečnik koji sadrži key-value parove

•Ključevi su stringovi

•Koristi se za prosleđivanje podataka iz kontrolera ka pogledu

•Kada se pristupa podacima iz pogleda moramo izvršiti neophodno kastovanje ukoliko ne čuvamo stringove

30

Prosleđivanje podataka Index pogledu HomeController klase

Kada se unutar akcione metode ne napiše ime pogleda kome se prosleđuju podaci,već samo return View(); onda se podaci prosleđuju pogledu koji ima isto ime kao iakciona metoda.

31

public IActionResult Index()

{

ViewData["brojPonavljanja"]= 5;

ViewData["poruka"] = "Uvod u ASP.NET Core web aplikacije";

return View();

}

Pogled Index.cshtml

32

@{

ViewData["Title"] = "Home Page";

}

<div class="row">

<div class="col-md-6">

@for (int i = 0; i < (int)ViewData["brojPonavljanja"]; i++)

{

<span>Poruka: @ViewData["poruka"]</span><br />

}

</div>

</div>

Generisani html

33

ViewBag

•Koristi se za prenos podataka iz kontrolera ka pogledu•ViewBag je dinamički objekat unutar koga se

dninamički definišu svojstva•ViewBag ne zahteva kastovanje pri iščitavanju

vrednosti iz njega•Svojstvo unutar ViewBaga ne sme da se poklopi sa

ključem ViewData rečnika

34

Definisanje dinamičkih svojstava

35

public IActionResult Index(){

ViewBag.brojPonavljanja = 5;ViewBag.poruka = "Uvod u ASP.NET Core web aplikacije"; return View();

}

Pogled Index.cshtml

36

<div class="row">

<div class="col-md-6">

@for (int i = 0; i < ViewBag.brojPonavljanja; i++)

{

<span>Poruka: @ViewBag.poruka</span><br />

}

</div>

</div>

Prosleđivanje podataka metodi kontrolera

Kreiranje praznog MVC kontrolera

38

Imenovanje kontrolera

39

Klasa PozdravController

40

public class PozdravController : Controller{

public IActionResult Index(){

return View();}

}

Index metoda klase PozdravController

41

public IActionResult Index(){

ViewBag.Poruka = "Zdravo";return View();

}

Index pogled PozdravController klase

42

Desni klik unutar metode Index pa opcija Add-> View

Folder Views/Pozdrav

43

Index.cshtml klase PozdravController

44

@{

ViewData["Title"] = "Index";

}

<h1>Index</h1>

<div class="row">

<div class="col-md-6">

@ViewBag.Poruka

<br />

<a href="/Home/Index">Pocetna</a>

</div>

</div>

Poziv Index akcione metode klase PozdravController posredstvom url adrese

45

http://localhost:5000/Pozdrav/Index

http://localhost:5000/Pozdrav

Akciona metoda Pozdrav1 PozdravController klase

public IActionResult Pozdrav1(int id = 1){

ViewBag.BrojPonavljanja = id;ViewBag.Poruka = "Dobar dan";return View();

}

46

Kreiranje pogleda Pozdrav1

47

Pogled Pozdrav1.cshtml

48

@{

ViewData["Title"] = "Pozdrav1";

}

<h1>Pozdrav1</h1>

<div>

<ul>

@for (int i = 0; i < ViewBag.BrojPonavljanja; i++)

{

<li>@ViewBag.Poruka</li>

}

</ul>

</div>

Poziv Pozdrav1 akcione metode

49

Prosledjivanje parametara akcionoj metodi-1

50

http://localhost:5000/pozdrav/pozdrav1/5

Korišćenje query stringa

51

http://localhost:5000/pozdrav/pozdrav1?id=5

Pitanje 1

52

Odgovor: a

Unutar Main metode klase Program kod ASP.NET Core web aplikacije kreira se:

a. host za web aplikaciju

b. model klasa web aplikacije

c. kontroler za web aplikaciju

Pitanje 2

53

Odgovor: c

Servisi u terminologiji ASP.NET Core web aplikacija su:

a. Klase ASP.NET Core web aplikacije koje zavise od drugih klasa

b. Klase izvedene iz klase Controller

c. Klase od kojih zavise druge klase ASP.NET Core web aplikacije

Pitanje 3

54

Odgovor: a

Registracija servisa - dodavanje servisa u kolekciju servisa

aplikacije, vrši se unutar

a. Metode ConfigureServices klase Startup

b. Metode ConfigureServices klase Program

c. Metode Configure klase Startup

Pitanje 4

55

Odgovor: c

Middleware komponenta se konfiguriše unutar metode:

a. ConfigureServices klase Startup

b. Middleware klase Startup

c. Metode Configure klase Startup

Pitanje 5

56

Odgovor: a

ASP.NET Core web aplikacija ima ugrađen Dependency Injection kontejner kojia. Ubacuje objekat klase servisa u zavisnu klasub. Ubacuje pogled u ASP.NET Core web aplikacijuc. Ubacuje kontroler u ASP.NET Core web aplikaciju

Pitanje 6

57

Odgovor: c

Statički fajlovi kod ASP.NET Core web aplikacija čuvaju se unutar podfoldera sledećeg foldera:

a. Models

b. Data

c. wwwroot

Entity Framework Core

.NET Core konzolna aplikacija

59

Microsoft.EntityFrameworkCore.SqlServer

Project->Manage Nuget Packages

60

EF Core Power Tools

61

Extensios -> Manage Extensios

Baza Magacin

62

Solution Explorer

63

Desni klik na projekat pa opcija Edit

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup><OutputType>Exe</OutputType><TargetFramework>netcoreapp3.1</TargetFramework>

</PropertyGroup>

<ItemGroup><PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />

</ItemGroup>

</Project>

64

Entity Framework Core

• EF Core je međuplatformska verzija Entity Frameworka

• EF Core je objektno-relacioni maper (O/RM) koji omogućava .NET programerima da rade sa bazom korišćenjem .NET objekata.

65

Strategije dizajna modela

• Database-first design, najpre se dizajnira i kreira baza podataka a zatim se generišu entiteti aplikacije

• Model-first design, najpre se dizajniraju entiteti za aplikaciju a zatim se kreira baza podataka na osnovu tih entiteta

66

Pokreni EF Core Power Tools

67

Odabir konekcije

68

Odabir tabela i kreiranje modela

69

Entitetska klasa Kategorija

70

namespace ConsoleEfCore.Models{

[Table("Kategorija")]public partial class Kategorija{

public Kategorija(){

Proizvodi = new HashSet<Proizvod>();}

[Key]public int KategorijaId { get; set; }

[Required][StringLength(70)]public string Naziv { get; set; }

[StringLength(120)]public string Opis { get; set; }

[InverseProperty(nameof(Proizvod.Kategorija))]public virtual ICollection<Proizvod> Proizvodi { get; set; }

}}

Entitetska klasa Proizvod

public partial class Proizvod{

[Key]public int ProizvodId { get; set; }

public int KategorijaId { get; set; }

[Required][StringLength(120)]public string Naziv { get; set; }

[Column(TypeName = "decimal(10, 2)")]public decimal Cena { get; set; }

[StringLength(120)]public string Opis { get; set; }

[ForeignKey(nameof(KategorijaId))][InverseProperty("Proizvodi")]public virtual Kategorija Kategorija { get; set; }

}

71

DbContext klasa namespace ConsoleEfCore.Models{public partial class MagacinContext : DbContext{

public virtual DbSet<Kategorija> Kategorije { get; set; }public virtual DbSet<Proizvod> Proizvodi { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){

if (!optionsBuilder.IsConfigured){

optionsBuilder.UseSqlServer("Data Source=.\\SqlExpress;Initial Catalog=Magacin;Integrated Security=True");}

}

}

72

DbContext klasa

• DbContext klasa je most za interakciju entitetskih klasa i baze podataka

• DbSet <TEntity> predstavlja kolekciju entitetskih objekata koji odgovaraju redovima tabele u bazi podataka

• DbContext sadrži svojstva za pristup DbSet-ovima DbSet<TEntity> za sve entitetske klase koje su mapirane u tabele baze

• DbContext klasa:– upravlja konekcijom sa odgovarajućom bazom podataka

– prati promene u objektima unutar DbSet ova

– čuva promene iz DbSetova u bazi podataka

73

Potrebne biblioteke

using System;using System.Collections.Generic;using System.Linq;using ConsoleEfCore.Models;using Microsoft.EntityFrameworkCore;

74

Čitanje podataka sa odloženim izvršavanjem upita

static void PrikaziProizvode(){

using (MagacinContext db = new MagacinContext()){

DbSet<Proizvod> listaProizvoda = db.Proizvodi;

foreach (Proizvod p in listaProizvoda){

Console.WriteLine(p.Naziv);}

}}

75

static void Main(string[] args){

PrikaziProizvode();Console.ReadLine();

}

Čitanje podataka uz materijalizaciju upita

76

static void PrikaziProizvode(){

using (MagacinContext db = new MagacinContext()){

List<Proizvod> listaProizvoda = db.Proizvodi.ToList();

foreach (Proizvod p in listaProizvoda){

Console.WriteLine(p.Naziv);}

}}

Filtriranje podatakastatic void ProizvodiIzKategorije(int id){

using (MagacinContext db = new MagacinContext()){

IQueryable<Proizvod> listaProizvoda = db.Proizvodi.Where(p => p.KategorijaId == id);

foreach (Proizvod p in listaProizvoda){

Console.WriteLine(p.Naziv + " " + p.Cena);}

}}

77

static void Main(string[] args){

ProizvodiIzKategorije(1);}

Upotreba navigacionog svojstvastatic void ProizvodiIzKategorije(int id){

using (MagacinContext db = new MagacinContext()){

IQueryable<Proizvod> listaProizvoda = db.Proizvodi.Where(p => p.KategorijaId == id);

foreach (Proizvod p in listaProizvoda){

Console.WriteLine(p.Naziv + " " + p.Cena + " " + p.Kategorija.Naziv);}

}}

78

Prikaz podataka iz povezane tabele – Include()

static void ProizvodiIzKategorije(int id){

using (MagacinContext db = new MagacinContext()){

IQueryable<Proizvod> listaProizvoda = db.Proizvodi.Include(p => p.Kategorija).Where(p => p.KategorijaId == id);

foreach (Proizvod p in listaProizvoda){

Console.WriteLine(p.Naziv + " " + p.Cena + " " + p.Kategorija.Naziv);}

}}

79

Čitanje jednog redastatic void NadjiProizvod(int id){

using (MagacinContext db = new MagacinContext()){

Proizvod p1 = db.Proizvodi.SingleOrDefault(p => p.ProizvodId == id);if (p1 != null){

Console.WriteLine(p1.Naziv + " " + p1.Cena);}else{

Console.WriteLine($"Ne postoji proizvod ciji je id = {id}");}

}}

80

Čitanje jednog reda-2static void NadjiProizvod(int id){

using (MagacinContext db = new MagacinContext()){

Proizvod p1 = db.Proizvodi.Find(id);if (p1 != null){

Console.WriteLine(p1.Naziv + " " + p1.Cena);}else{

Console.WriteLine($"Ne postoji proizvod ciji je id = {id}");}

}}

81

Primer pisanja upita

82

static void PrikaziKategorije(){

using (MagacinContext db = new MagacinContext()){

foreach (Kategorija k in db.Kategorije){

Console.WriteLine(k.KategorijaId + ": " + k.Naziv);}

}}

Prikaz podataka

static void Main(string[] args){

PrikaziKategorije();Console.WriteLine("Unesite Id kategorije:");

int id = int.Parse(Console.ReadLine());

PrikaziProizvode(id);

Console.ReadLine();}

83

Ažuriranje podataka korišćenjem EF

• DbContext objekat sadrži entity objekte koji predstavljaju podatke u odgovarajućoj bazi podataka

• Ukoliko želimo da modifikujemo podatke u bazi prvo se vrši promena sadržaja DbContext objekta a zatim se od njega traži da sačuva promene u bazi podataka

84

Atačovani i detačovani objektiDbContext

Attached Entity Detached Entity

Attached

Managed by DbContext

Tracked

Can be persisted

Detached

Managed by DbContext

Tracked

Can be persisted

85

Unos podatakastatic int UbaciKategoriju(){

using (MagacinContext db = new MagacinContext()){

Kategorija k = new Kategorija();try{

k.Naziv = "Kucna hemija";k.Opis = "Hemija za kuhinju i kupatilo";//db.Kategorije.Add(k);db.Add(k);db.SaveChanges();return k.KategorijaId;

}catch (Exception xcp){

Console.WriteLine(xcp.Message);return -1;

}

}}

86

Main() metoda

static void Main(string[] args){

int id = UbaciKategoriju();Console.WriteLine($"Ubacena kategorija ciji je Id: {id}");Console.ReadLine();

}

87

Prikaz unetog redastatic void PrikaziKategoriju(int id){

using (MagacinContext db = new MagacinContext()){

Kategorija k1 = db.Kategorije.Find(id);

if (k1 != null){

Console.WriteLine(k1.Naziv + "\n" + k1.Opis);}else{

Console.WriteLine("Ne postoji kategorija");}

}

}

88

Ažuriranje reda -1

89

static Kategorija VratiKategoriju(int id){

using (MagacinContext db = new MagacinContext()){

Kategorija k1 = db.Kategorije.Find(id);

if (k1 != null){

return k1;}else{

return null;}

}}

Ažuriranje reda -2

static int PromeniKategoriju(Kategorija k){

using (MagacinContext db = new MagacinContext()){

try{

db.Update(k);db.SaveChanges();return 0;

}catch (Exception xcp){

Console.WriteLine(xcp.Message);return -1;

}

}}

90

Main() metoda

91

static void Main(string[] args){

Kategorija k1 = VratiKategoriju(6);

k1.Naziv = "Hemija za kucu";k1.Opis = "Hemija za kuhinju, kupatilo i ostalo";int r = PromeniKategoriju(k1);

if (r == 0){

Console.WriteLine("Promenjena kategorija");}else{

Console.WriteLine("Greska pri promeni");}Console.ReadLine();

}

Brisanje reda

public static int ObrisiKategoriju(int id){

using (MagacinContext db = new MagacinContext()){

try{

Kategorija k = db.Kategorije.Find(id);db.Remove(k);db.SaveChanges();return 0;

}catch (Exception){

return -1;}

}}

92

Main() metoda

static void Main(string[] args){

int r = ObrisiKategoriju(6);

if (r == 0){

Console.WriteLine("Obrisana kategorija");}else{

Console.WriteLine("Greska pri brisanju kategorije");}Console.ReadLine();

}

93

Klasa Thread i klasa Task

• Klasa Thread koristi se za rad sa programskim nitima

• Klasa Thread nalaze se u biblioteci System.Threading

• Klasa Task predstavlja operaciju koja ne vraća vrednost izvršava se u posebnoj programskoj niti i obično se izvršava asinhrono

• Klasa Task se nalazi u biblioteci System.Threading.Tasks

• Klasa Task se koristi za izvršavanje više poslova istovremeno, svaki u posebnoj programskoj niti

94

Metode koje se izvršavaju u istoj programskoj nitistatic void Nit1(){

if (Thread.CurrentThread.Name == null){

Thread.CurrentThread.Name = "Pomocna nit";}

Console.WriteLine("".PadRight(50, '_'));Console.WriteLine("Pozdrav iz programske niti");Console.WriteLine($"Ime: {Thread.CurrentThread.Name}, Id: {Thread.CurrentThread.ManagedThreadId}");Console.WriteLine("".PadRight(50, '_'));

}static void Main(string[] args){

Thread.CurrentThread.Name = "Glavna nit";Console.WriteLine("Pocetak Main metode");Console.WriteLine($"Ime: {Thread.CurrentThread.Name}, Id: {Thread.CurrentThread.ManagedThreadId}");Nit1();

Console.WriteLine("Kraj Main metode");Console.ReadLine();

}

95

Metode koje se izvršavaju u istoj programskoj niti

96

Izvršavanje metode u posebnoj programskoj nitistatic void Main(string[] args){

Thread.CurrentThread.Name = "Glavna nit";Console.WriteLine("Pocetak Main metode");Console.WriteLine($"Ime: {Thread.CurrentThread.Name}, Id:

{Thread.CurrentThread.ManagedThreadId}");Action a = Nit1;Task t1 = new Task(a);t1.Start();Console.WriteLine("Kraj Main metode");Console.ReadLine();

}

97

Izvršavanje metode u posebnoj programskoj niti

98

Čekanje da se završi programska nit

static void Main(string[] args){

Thread.CurrentThread.Name = "Glavna nit";Console.WriteLine("Pocetak Main metode");Console.WriteLine($"Ime: {Thread.CurrentThread.Name}, Id:

{Thread.CurrentThread.ManagedThreadId}");Action a = Nit1;Task t1 = new Task(a);t1.Start();t1.Wait();Console.WriteLine("Kraj Main metode");Console.ReadLine();

}

99

Kreiranje zadatka korišćenjemlambda izrazastatic void Main(string[] args){

Console.WriteLine("Pocetak Main metode");Thread.CurrentThread.Name = "Glavna nit";Console.WriteLine($"Naziv: {Thread.CurrentThread.Name}, Id: {Thread.CurrentThread.ManagedThreadId}");Console.WriteLine($"Glavna nit, vreme: {DateTime.Now.ToLongTimeString()}");

//Task t1 = new Task(// () => Console.WriteLine($"Pomocna nit, vreme: {DateTime.Now.ToLongTimeString()}")// );

Task t1 = new Task(() =>{

Console.WriteLine("".PadRight(50,'_'));Console.WriteLine($"Id: {Thread.CurrentThread.ManagedThreadId}");Thread.Sleep(2000);Console.WriteLine($"Pomocna nit, vreme: {DateTime.Now.ToLongTimeString()}");Console.WriteLine("".PadRight(50, '_'));

});

t1.Start();

// t1.Wait();

Console.WriteLine("Kraj Main metode");Console.ReadLine();

} 100

Kreiranje zadatka korišćenjemlambda izraza

101

Vraćanje vrednosti iz zadatka

• Koristi se Task<TResult> klasa

• Koristi se Result svojstvo

102

private void button1_Click(object sender, EventArgs e){

Task<string> t1 = Task.Run(() =>{

Thread.Sleep(5000);return DateTime.Now.ToLongTimeString();

});

// UI je blokitanlabel1.Text = t1.Result;

}

Korišćenje operatora async i await

•Modifikator async označava da je metoda asinhrona

•Unutar asinhrone metode se koristi operator await koji suspenduje izvršavanje metode sve dok se zadatak ne završi

•Omogućavaju poziv asinhrone metode i čekanje rezultata bez blokiranja programske niti

103

Izvršavanje asinhrone operacije u UI programskoj nitiprivate async void button1_Click(object sender, EventArgs e){

Task<string> t1 = Task.Run(() =>{

Thread.Sleep(5000);return DateTime.Now.ToLongTimeString();

});

// linija koda se izvrsava kada je rezultat raspoloziv// UI nije blokiran

label1.Text = await t1;}

104

Kreiranje Awaitable metode

•Ako sinhrona metoda vraća void asinhroni ekvivalent vraća Task

•Ako sinhrona metoda vraća tip T, asinhroni ekvivalent vraća Task<T>

105

Asinhrona metodaprivate async Task<string> CitajAsinhrono(){

Task<string> task1 = Task.Run(() =>{

//simulacija dugotrajnog procesaThread.Sleep(3000);return DateTime.Now.ToLongTimeString();

});

return await task1;}

106

private async void button2_Click(object sender, EventArgs e){

label1.Text = await CitajAsinhrono();}

Pitanje 1

Kod Entity Frameworka Core tehnologije osnovna klasa koja se koristi kao bazna klasa za manipulaciju sa entitetskim objektima naziva se:

a. DbContext klasab. DataSet klasac. EntityContext klasa

Odogovor: a

107

Pitanje 2

Ako je MagacinContext klasa izvedena iz DbContext klase. Neka je db instanaca MagacinContext klase.Klasa MagacinContext ima svojstvo Kategorije pomoću koga se pristupa DbSet objektu tipa DbSet<Kategorija> koji se sastoji od objekata entitetske klase Kategorija.Kako se pronalazi atačovani objekat čiji id ima vrednost 1:

a. Kategorija k1 = db.Kategorije.Find(k=>k.id=1);b. Kategorija k1 = db.Kategorije.Select(1);c. Kategorija k1 = db.Kategorije.Find(1);

Odogovor: c

108

Pitanje 3

Da bi se promene unutar tipiziranog DbContext objekta označenog sa db sačuvale u bazi podatakapišemo sledeću liniju koda:a. db.Save();b. db. SaveToDatabase();c. db.SaveChanges();

Odogovor: c

109

Pitanje 4

Za kreiranje operacije koja se izvršava u posebnoj programskoj niti i koja ne vraća vrednost koristi se klasa:a. Threadb. Taskc. Task<T>

Odogovor: b

110

Pitanje 5

Za asinhronu metodu koja treba da vrati string kao povratni tip se specificira:a. Thread<string>b. Taskc. Task<string>

Odogovor: c

111

Pitanje 6

Kreirana je metoda klasa sledećeg potpisa:private async Task<string> Citaj()Na koji način pozivamo ovu metodu:a. Citaj()b. async Citaj()c. await Citaj()

Odogovor: b

112

MVC model

MVC Model

• Model predstavlja domen aplikacije

• Svrha modela je da da smisao podacima

• Model se može koristiti kao kontejner za podatke koji se prikazuju na web strani

• Najčešće se kao model podataka koristi entitetski model

114

Kreiranje ASP.NET Core web aplikacije

115

Klasa kao model – folder Models

[Table("Osoba")]public class Osoba{

public int OsobaId { get; set; }public string Ime { get; set; }public string Prezime { get; set; }public string Adresa { get; set; }

}

116

using System.ComponentModel.DataAnnotations.Schema;

Interfejs ISkladiste

namespace WebMvcModel.Models{

public interface ISkladiste{

IEnumerable<Osoba> Osobe { get; }}

}

117

Models folder

118

namespace WebMvcModel.Models

{

public class OsobaSkladiste : ISkladiste

{

public IEnumerable<Osoba> Osobe

{

get

{

Osoba os1 = new Osoba { OsobaId = 1, Ime = "Pera", Prezime = "Peric", Adresa = "Prvomajska 4" };

Osoba os2 = new Osoba { OsobaId = 2, Ime = "Mika", Prezime = "Mikic", Adresa = "Glavna 12" };

Osoba os3 = new Osoba { OsobaId = 3, Ime = "Laza", Prezime = "Lazic", Adresa = "Marije Bursac 2" };

List<Osoba> listaOsoba = new List<Osoba>()

{

os1,

os2,

os3

};

return listaOsoba;

}

}

}

}

Klasa Startup metoda ConfigureServices

119

public void ConfigureServices(IServiceCollection services){

services.AddTransient<ISkladiste, OsobaSkladiste>();services.AddControllersWithViews();

}

Kada komponenta poput kontrolera ima potrebe za implementacijom ISkladiste interfejsa ona će dobiti instancu klase OsobaSkladiste. Tranzientni servis se instancira pri svakom zahtevu za implementacijom (posredstvom konstruktora zavisne klase).

Modifikovana klasa HomeController

120

public class HomeController : Controller{

private readonly ISkladiste skladiste;

public HomeController(ISkladiste _skladiste){

skladiste = _skladiste;}public IActionResult Index(){

ViewBag.Poruka = "Lista osoba";

return View(skladiste.Osobe);}

}

Ubacivanje zavisnosti u kontroler

• Kada MVC treba da kreira novu instancu klase HomeController da bi obradio HTTP zahtev on gleda konstruktor i uviđa da on zahteva objekat koji imlementra interfejs ISkladiste

• Da bi odredio koju implentacionu klasu trebakoristi MVC konsultuje Startup klasu koja govori da treba da koristi klasu OsobaSkladiste i da se pri svakom zahtevu treba kreirati nova instanca ove klase

• MVC kreira objekat klase OsobaSkladiste i prosleđuje ga konstruktoru kontrolera

• Proces DI omogućava kontroleru da pristupi skladištu podataka kroz interfejs bez potrebe da zna koja se implementaciona klasa za to koristi

121

Kreiranje Index pogleda bazirano na modelu

122

Direktiva @model

@model IEnumerable<WebMvcModeli.Models.Osoba>

@{

ViewData["Title"] = "Index";

}

Direktiva @model omogućava da se podacima koje je kontroler prosledio pogledu korišćenjem svojstva Model. Podaci koje prosleđuje kontroler su tipizirani, u ovom slučaju objekti klase Osoba.

123

Index pogled -1<h2>Index</h2>

<table class="table table-bordered table-striped">

<thead>

<tr>

<th>

Id

</th>

<th>

Ime

</th>

<th>

Prezime

</th>

<th>

Adresa

</th>

</tr>

</thead>

124

Index pogled -2<tbody>

@foreach (Osoba os in Model) {

<tr>

<td>

@os.OsobaId

</td>

<td>

@os.Ime

</td>

<td>

@os.Prezime

</td>

<td>

@os.Adresa

</td>

</tr>

}

</tbody>

</table>

125

Prikaz Index pogleda

126

Mvc model- code first pristup

Fajl appsettings.json

{

"Logging": {

"LogLevel": {

"Default": "Information",

"Microsoft": "Warning",

"Microsoft.Hosting.Lifetime": "Information"

}

},

"AllowedHosts": "*",

"ConnectionStrings": {

"DefaultConnection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=OsobaDb503;Integrated Security=True;"

}

}

128

Microsoft.EntityFrameworkCore.SqlServer

129

Klasa OsobaContext

130

using Microsoft.EntityFrameworkCore;

public class OsobaContext : DbContext{

public DbSet<Osoba> Osobe { get; set; }}

Metoda AddDbContext<TContext> interfejsa IServiceCollection• Ova metoda omogućava da DbContext<TContext> objekat bude

raspoloživ za ubacivanje od strane DI kontejnera

• Omogućava da DbContextOptions<TContext> objekat bude raspoloživ za ubacivanje od strane DI kontejnera

131

Registrujemo DbContext kao servis

132

Metoda AddDbContext registruje OsobaContext klasu kao servis. Konfiguriše se kontekst da koristi Sql Server bazu podataka. Instanca klase OsobaContext se ubacuje posredstvom DI kontejnera.

using Microsoft.EntityFrameworkCore;

public void ConfigureServices(IServiceCollection services)

{

services.AddTransient<ISkladiste, OsobaSkladiste>();

services.AddDbContext<OsobaContext>(opcije =>

opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))

);

services.AddControllersWithViews();

}

Klasa OsobaContext

public class OsobaContext : DbContext{

public OsobaContext(DbContextOptions<OsobaContext> opcije) : base(opcije){}

public DbSet<Osoba> Osobe { get; set; }}

133

using Microsoft.EntityFrameworkCore;

Konstruktor DbContext klase mora imati kao parametar instancu klase DbContextOptions da bi se kreirao objekat DbContext. Ovu instancu ubacuje DI kontejner. Objekat DbContextOptions sadrži opcije za kreiranje DbContext objekta.

Klasa OsobaSkladisteDb

134

namespace WebMvcModel.Models{

public class OsobaSkladisteDb : ISkladiste{

private readonly OsobaContext db;public OsobaSkladisteDb(OsobaContext _db){

db = _db;}

public IEnumerable<Osoba> Osobe => db.Osobe;}

}

Promena implementacione klase servisa

services.AddTransient<ISkladiste, OsobaSkladisteDb>();

135

Microsoft.EntityFrameworkCore.Tools

136

Code first migracije

• Omogućavaju kreiranje baze podataka na osnovu postojećih entitetskih klasa i DbContext klase

• Omogućavaju promenu baze podataka kada se promeni neka od entitetskih klasa i context klasa

• Komanda Add-Migrations Prva unutar alata Package Manager Console služi da se kreira nova migracija unutar klase Prva

• Nakon dodavanje migracije kreira se folder Migrationsunutar ASP.NET Core MVC web aplikacije

137

Dodavanje migracije

138

PM> Add-Migration Prva

Klasa Prva.cs

139

public partial class Prva : Migration

{

protected override void Up(MigrationBuilder migrationBuilder)

{

migrationBuilder.CreateTable(

name: "Osoba",

columns: table => new

{

OsobaId = table.Column<int>(nullable: false)

.Annotation("SqlServer:Identity", "1, 1"),

Ime = table.Column<string>(nullable: true),

Prezime = table.Column<string>(nullable: true),

Adresa = table.Column<string>(nullable: true)

},

constraints: table =>

{

table.PrimaryKey("PK_Osoba", x => x.OsobaId);

});

}

protected override void Down(MigrationBuilder migrationBuilder)

{

migrationBuilder.DropTable(

name: "Osoba");

}

}

Kreiranje baze na osnovu modela

140

PM> Update-Database Primena migracije na bazu

Generisana baza podataka server (localdb)\MSSQLLocalDb

141

Index strana prikazuje podatake iz baze

142

OsobaController

143

OsobaController

144

Generisani pogledi

145

Index pogled klase OsobaController

146

Unos podataka, poziv Create akcione metode

147

Model klasa sa anotacijama polja

[Table("Osoba")]public class Osoba{

public int OsobaId { get; set; }

[Required(ErrorMessage = "Morate uneti ime")][StringLength(30, ErrorMessage = "Ime je duzine do 30 karaktera")]public string Ime { get; set; }

[Required(ErrorMessage = "Morate uneti prezime")][StringLength(30, ErrorMessage = "Prezime je duzine do 30 karaktera")]public string Prezime { get; set; }

[Required(ErrorMessage = "Morate uneti adresu")][StringLength(60, ErrorMessage = "Adresa je duzine do 60 karaktera")]public string Adresa { get; set; }

}148

using System.ComponentModel.DataAnnotations;

Dodavanje nove migracije

149

PM> Add-Migration Druga

Metoda Up() migracije

150

protected override void Up(MigrationBuilder migrationBuilder)

{

migrationBuilder.AlterColumn<string>(

name: "Prezime",

table: "Osoba",

maxLength: 30,

nullable: false,

oldClrType: typeof(string),

oldType: "nvarchar(max)",

oldNullable: true);

migrationBuilder.AlterColumn<string>(

name: "Ime",

table: "Osoba",

maxLength: 30,

nullable: false,

oldClrType: typeof(string),

oldType: "nvarchar(max)",

oldNullable: true);

migrationBuilder.AlterColumn<string>(

name: "Adresa",

table: "Osoba",

maxLength: 60,

nullable: false,

oldClrType: typeof(string),

oldType: "nvarchar(max)",

oldNullable: true);

}

Primena druge migracijePM> Update-Database

151

Validacija podataka

152

Unos podataka

153

Mvc model- database first pristup

Sql Server Object explorer

155

Tabela u bazi OsobaDb503ver2

CREATE TABLE Osoba(OsobaId int IDENTITY(1,1) PRIMARY KEY NOT NULL,Ime nvarchar(50) NOT NULL,Prezime nvarchar(50) NOT NULL,Adresa nvarchar(60) NOT NULL)

156

EF Core Power Tools -1

157

EF Core Power Tools -2

158

Generisana entitetska klasa

159

public partial class Osoba

{

[Key]

public int OsobaId { get; set; }

[Required]

[StringLength(50)]

public string Ime { get; set; }

[Required]

[StringLength(50)]

public string Prezime { get; set; }

[Required]

[StringLength(60)]

public string Adresa { get; set; }

}

Generisana DbContext klasa

160

namespace WebMvcCoreBazaPrvo.Models

{

public partial class OsobaContext : DbContext

{

public OsobaContext(DbContextOptions<OsobaContext> options)

: base(options)

{

}

public virtual DbSet<Osoba> Osobe { get; set; }

}

}

Modifikovani appsettings.json

161

{

"Logging": {

"LogLevel": {

"Default": "Information",

"Microsoft": "Warning",

"Microsoft.Hosting.Lifetime": "Information"

}

},

"AllowedHosts": "*",

"ConnectionStrings": {

"DefaultConnection": "Data Source=(localdb)\\MSSQLLocalDB;Initial

Catalog=OsobaDb503ver2;Integrated Security=True;"

}

}

Metoda ConfigureServices() klase Startup

162

public void ConfigureServices(IServiceCollection services){

services.AddDbContext<OsobaContext>(opcije =>opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));services.AddControllersWithViews();

}

using WebMvcCoreBazaPrvo.Models;

using Microsoft.EntityFrameworkCore;

Kreiranje OsobaController klase

163

Validacija podataka

164

Modifikovana model klasa

165

public partial class Osoba{

public int OsobaId { get; set; }

[Required(ErrorMessage = "Unesite ime")][StringLength(50, ErrorMessage = "Maksimalno 50 karaktera")]

public string Ime { get; set; }

[Required(ErrorMessage = "Unesite prezime")][StringLength(50, ErrorMessage = "Maksimalno 50 karaktera")]public string Prezime { get; set; }

[Required(ErrorMessage = "Unesite adresu")][StringLength(60, ErrorMessage = "Maksimalno 60 karaktera")]public string Adresa { get; set; }

}

Prikaz validacionih gresaka

166

Pitanje 1

Modeli podataka kod ASP.NET Core MVC web aplikacija definišu se unutar:a. foldera Modelsb. foldera wwwrootc. foldera Views

Odgovor: a

167

Pitanje 2

Unutar pogleda (cshtml) fajla podacima koje prosleđuje kontroler pristupa se:a. korišćenjem svojstva Modelb. korišćenjem ključne reči @modelc. korišćenjem klase ModelData

Odgovor: a

168

Kreiranje MVC kontrolera

Kreiranje ASP.NET Core Web aplikacije

170

Microsoft.EntityFrameworkCore.SqlServer

171

Microsoft.EntityFrameworkCore.Tools

172

Pojam kontrolera

• Kontroler je C# klasa čije su javne metode odgovorne za obradu HTTP zahteva kod ASP.NET Core MVC web aplikacija

• Ime kontrolerske klase se završava sa Controller

• Kontroler je klasa koja je obično izvedena iz bazne klase Controller

• Metoda kontrolera koja obrađuje HTTP zahtev naziva se akciona metoda ili akcija

• Svaki kontroler sadrži jednu ili više akcionih metoda

• Akciona metoda kontrolera mora biti javna, ne može biti statička, i ne može se overloadovati

• Akciona metoda može vratiti objekat bilo kog tipa

• Uobičajeno je da akciona metoda vraća objekat koji implementira IActionResult interfejs

• Akcija kontrolera prosleđuje podatke odgovarajućem pogledu

173

Rutiranje

• Rute opisuju kako se URL adrese zahteva mapiraju u akcije kontrolera

• Rute se definišu unutar middleware komponente za rutiranje

• Unutar Configure metode poziva se metoda UseEndpoints koja se koristi da se definišu rute

• Metoda MapControllerRoute se koristi za kreiranje default rute

• Ako želimo da pozovemo Details akcionu metodu OsobaController klase i da toj metodi prosledimo id parametar vrednosti 3 potrebno je uneti sledeću adresu u browseru: http://<app>/osoba/details/3

174

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

{

app.UseEndpoints(endpoints =>

{

endpoints.MapControllerRoute(

name: "default",

pattern: "{controller=Home}/{action=Index}/{id?}");

});

}

HomeController

public class HomeController : Controller

{

public IActionResult Index()

{

return View();

}

public IActionResult Privacy()

{

return View();

}

}

175

Interfejs IActionResult

• Ovim interfejsom definiše se ugovor koji predstavlja rezultat izvršavanja akcione metode

• Obično akcione metode vraćaju objekat koji implementira IActionResult interfejs

• Metoda View() bazne klase Controller vraća instancu klase ViewResult

• Metoda Json() vraća objekat klase JsonResult i koristi se kada akciona metoda treba da generiše json string

176

Model klasa Osoba i DbContext klasa OsobaContext

public class OsobaContext : DbContext{

public DbSet<Osoba> Osobe { get; set; }} 177

[Table("Osoba")]public class Osoba{

public int OsobaId { get; set; }

[Required][StringLength(30)]public string Ime { get; set; }

[Required][StringLength(30)]public string Prezime { get; set; }

[Required][StringLength(100)]public string Adresa { get; set; }

}

Definisanje konekcionog stringa u appsettings.json fajlu

{"Logging": {

"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"

}},"AllowedHosts": "*","ConnectionStrings": {

"DefaultConnection": "Data Source=.\\SqlExpress;Initial Catalog=OsobaDb1203;Integrated Security=true"}

}

178

Registrujemo DbContext kao servis

179

public void ConfigureServices(IServiceCollection services){

services.AddDbContext<OsobaContext>(opcije =>opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

services.AddControllersWithViews();}

using WebMvcKontroler.Models;using Microsoft.EntityFrameworkCore;

Promenimo DbContext klasu

public class OsobaContext : DbContext

{

public OsobaContext(DbContextOptions<OsobaContext> opcije) : base(opcije)

{

}

public DbSet<Osoba> Osobe { get; set; }

}

using Microsoft.EntityFrameworkCore;

180

Kreiranje baze podataka primenom migracija

PM> Add-Migration Prva

PM> Update-Database

181

Kreirana baza podataka

182

Kreiranje kontrolera

183

Klasa OsobaController

public class OsobaController : Controller{

private readonly OsobaContext _context;

public OsobaController(OsobaContext context){

_context = context;}

}

184

Akcija Index asinhrona verzija

using System.Threading.Tasks;using Microsoft.AspNetCore.Mvc;

using WebMvcKontroler.Models;using Microsoft.EntityFrameworkCore;

185

public async Task<IActionResult> Index(){

return View(await _context.Osobe.ToListAsync());}

Poziv Index akcije kontrolera Osoba

186

Akciona metoda Details// GET: Osoba/Details/5

public async Task<IActionResult> Details(int? id)

{

if (id == null)

{

return NotFound();

}

var osoba = await _context.Osobe

.FirstOrDefaultAsync(m => m.OsobaId == id);

if (osoba == null)

{

return NotFound();

}

return View(osoba);

}187

Poziv Details akcije kontrolera Osoba

188

Dodavanje middleware komponente za obradu odgovara sa kodnim statusom od 400 do 599

189

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

{

...

app.UseStatusCodePages();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

...

}

Loš poziv Details akcione metode

190

GET i POST akciona metoda Create

// GET: Osoba/Createpublic IActionResult Create(){

return View();}

[HttpPost][ValidateAntiForgeryToken]public async Task<IActionResult> Create([Bind("OsobaId,Ime,Prezime,Adresa")] Osoba osoba){

if (ModelState.IsValid){

_context.Add(osoba);await _context.SaveChangesAsync();return RedirectToAction(nameof(Index));

}return View(osoba);

}

191

Model binding

• Model binding je process kreiranja .NET objekata korišćenjem podataka iz HTTP zahteva

• Kreirani objekti se prosleđuju akcionim metodama kontrolera

• Model binder je komponenta MVC aplikacije koja obezbeđuje podatke za akcione metode iz različitih delova HTTP zahteva

• Model binder koristi tri izvora podataka da bi mapirao HTTP zahteve u podatke neophodne akcionim metodama• vrednosti polja forme

• vrednosti parametara iz rute

• vrednosti parametara iz query stringova

192

Svojstva i atributske klase koje koristi metoda Create• ValidateAntiForgeryToken predstavlja atributsku klasu koja sprečava

falsifikovanje zahteva

• ModelState je property kontrolera i sadrži kolekciju (name,value) parova koju su prosleđeni u POST zahtevu do servera, takođe sadrži i kolekciju grešaka za svaku vrednost koja je poslate do servera

• ModelState.IsValid ukazuje da su greške u modelu dodate u ModelState

• Pomoću atributske klase Bind se specificiraraju koja svojstva model klase se koriste u kreiranju .NET objekata od strane model bindera

• Metoda RedirectToAction poziva akciju kontrolera koja se specificira kao string parameter metode

• Ključna reč nameof se koristi da se dobije ime promenljive, tipa ili metode

193

Poziv akcione metode Create kontrolera Osoba

194

Edit GET metoda

public async Task<IActionResult> Edit(int? id){

if (id == null){

return NotFound();}

var osoba = await _context.Osobe.FindAsync(id);if (osoba == null){

return NotFound();}return View(osoba);

}

195

Edit POST metoda

196

private bool OsobaExists(int id){

return _context.Osobe.Any(e => e.OsobaId == id);}

[HttpPost][ValidateAntiForgeryToken]public async Task<IActionResult> Edit(int id, [Bind("OsobaId,Ime,Prezime,Adresa")] Osoba osoba){

if (id != osoba.OsobaId){

return NotFound();}

if (ModelState.IsValid){

try{

_context.Update(osoba);await _context.SaveChangesAsync();

}catch (DbUpdateConcurrencyException){

if (!OsobaExists(osoba.OsobaId)){

return NotFound();}else{

throw;}

}return RedirectToAction(nameof(Index));

}return View(osoba);

}

Poziv Edit GET metode kontrolera Osoba

197

Delete GET metoda

public async Task<IActionResult> Delete(int? id){

if (id == null){

return NotFound();}

var osoba = await _context.Osobe.FirstOrDefaultAsync(m => m.OsobaId == id);

if (osoba == null){

return NotFound();}

return View(osoba);}

198

Delete Post metoda

[HttpPost, ActionName("Delete")][ValidateAntiForgeryToken]public async Task<IActionResult> DeleteConfirmed(int id){

var osoba = await _context.Osobe.FindAsync(id);_context.Osobe.Remove(osoba);await _context.SaveChangesAsync();return RedirectToAction(nameof(Index));

}

ActionName klasa ukazuje da se radi o akciji Delete

199

Poziv akcije Delete kontrolera Osoba

200

Primer filtriranja podataka

201

EF Core Power Tools

202

EF Core Power Tools

203

Model klasa Kategorija

[Table("Kategorija")]

public partial class Kategorija

{

public Kategorija()

{

Proizvodi = new HashSet<Proizvod>();

}

public int KategorijaId { get; set; }

[Required]

[StringLength(70)]

public string Naziv { get; set; }

[StringLength(120)]

public string Opis { get; set; }

public virtual ICollection<Proizvod> Proizvodi { get; set; }

}204

Model klasa Proizvod

public partial class Proizvod

{

public int ProizvodId { get; set; }

public int KategorijaId { get; set; }

[Required]

[StringLength(120)]

public string Naziv { get; set; }

[Column(TypeName = "decimal(10, 2)")]

public decimal Cena { get; set; }

[StringLength(120)]

public string Opis { get; set; }

public virtual Kategorija Kategorija { get; set; }

}

205

DbContext klasa

public partial class MagacinContext : DbContext

{

public MagacinContext(DbContextOptions<MagacinContext> opcije)

: base(opcije)

{

}

public virtual DbSet<Kategorija> Kategorije { get; set; }

public virtual DbSet<Proizvod> Proizvodi { get; set; }

}

206

appsettings.json

{"Logging": {

"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"

}},"AllowedHosts": "*","ConnectionStrings": {

"DefaultConnection": "Data Source=.\\SqlExpress;Initial Catalog=Magacin;Integrated Security=true"}

}

207

DbContext kao servis

public void ConfigureServices(IServiceCollection services)

{

services.AddDbContext<MagacinContext>(opcije =>

opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

services.AddControllersWithViews();

}

208

Klasa HomeController

private readonly MagacinContext db;

public HomeController(MagacinContext _db)

{

db = _db;

}

public IActionResult Index()

{

return View(db.Kategorije.ToList());

}

209

Metoda za filtriranje

public IActionResult VratiProizvode(int id=0)

{

IQueryable<Proizvod> listaProizvoda = db.Proizvodi;

if (id != 0)

{

Kategorija k1 = db.Kategorije.Find(id);

if (k1 != null)

{

ViewBag.Kategorija = k1.Naziv;

listaProizvoda = listaProizvoda.Where(p => p.KategorijaId == id);

}

else

{

ViewBag.Kategorija = "";

return View();

}

}

else

{

ViewBag.Kategorija = "Svi proizvodi";

}

return View(listaProizvoda);

}

210

Index pogled

211

VratiProizvode

212

@model IEnumerable<WebCoreFiltriranje1.Models.Kategorija>

@{

ViewData["Title"] = "Index";

}

<h1>Index</h1>

<table class="table">

<thead>

<tr>

<th>

Naziv

</th>

<th>

Opis

</th>

<th></th>

</tr>

</thead>

<tbody>

@foreach (Kategorija k in Model) {

<tr>

<td>

@k.Naziv

</td>

<td>

@k.Opis

</td>

<td>

<a href="@($"/Home/VratiProizvode/{k.KategorijaId}")">Vidi proizvode</a>

</td>

</tr>

}

</tbody>

</table>

Index.cshtml

213

@model IEnumerable<WebCoreFiltriranje1.Models.Proizvod>

@{

ViewData["Title"] = "VratiProizvode";

}

<div class="jumbotron">

<h1>

@ViewBag.Kategorija

</h1>

</div>

@if (ViewBag.Kategorija != "")

{

<table class="table">

<thead>

<tr>

<th>

Naziv

</th>

<th>

Cena

</th>

<th>

Opis

</th>

<th>

Kategorija

</th>

<th></th>

</tr>

</thead>

VratiProizvode.cshtml

214

<tbody>

@foreach (Proizvod p in Model)

{

<tr>

<td>

@p.Naziv

</td>

<td>

@p.Cena

</td>

<td>

@p.Opis

</td>

<td>

@p.Kategorija.Naziv

</td>

</tr>

}

</tbody>

</table>

}

else

{

<p>Ne postoji kategorija</p>

}

<br>

<a href="/Home/Index">Prikazi kategorije</a>

215

Pitanje 1

MVC web aplikacija se izvršava na adresi http://localhost:5000. Ako želimo da pozovemo Details akcionu metodu OsobaController klase i da toj metodi prosledimo vrednost 3 kao ulazni parametar ove metode, potrebno je uneti sledeću adresu u browseru:a. http://localhost:5000/Osoba/Details/3b. http://localhost:5000/OsobaController/details/3c. http://localhost:5000/Osoba/details/?=3

Odgovor: a

216

Pitanje 2

Komponenta ASP.NET MVC web aplikacije koja je odgovorna za obradu zahteva naziva se:a. modelb. pogledc. kontroler

Odgovor: c

217

Pitanje 3

Zaokruži netačno tvrđenje. Kontrolerska klasa:a. Ima ime koje se završava sa rečju Controllerb. Može biti izvedena iz klase Controllerc. Mora biti opisana atributskom klasom [Authorize]

Odgovor: c

218

Pitanje 4

Interfejs pomoću koga se specificira povratni tip akcione metode kontrolera je :a. IDbContextb. IActionResultc. IJson

Odgovor: b

219

Pitanje 5

Ako akciona metoda kontrolera nije opisana atributskom klasom onda se ona može pozvati:a. GET zahtevb. POST zahtevc. I GET i POST zahtevom

Odgovor: c

220

Pitanje 6

221

Odgovor: a

Proces kreiranja .NET objekata na osnovu parametara HTTP zahteva u metodama

kontrolera naziva se

a. Model binding

b. Controller binding

c. Pogled binding

Pitanje 7

222

Odgovor: b

Validnost podataka koji su prosleđeni do akcione metode

kontrolera proverava se korišćenjem izraza

a. ModeBinding.IsValid

b. ModelState.IsValid

c. Model.IsValid

top related