Web programiranje
Transcript of Web programiranje
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