# MVC arhitektura Ovaj materijal dio je ishoda učenja 3 (minimum). ## 9 ASP.NET MVC i prikazi Prikazi: - https://learn.microsoft.com/en-us/aspnet/core/mvc/views/overview?view=aspnetcore-8.0 Pregled sintakse Razora: - https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-8.0 HTML pomoćnici (engl. HTML Helpers): - https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.htmlhelper?view=aspnet-mvc-5.2 Tag pomoćnici (engl. Tag Helpers): - https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-8.0 ### 9.1 Postavljanje vježbe Postavljanje baze podataka: - kreirati bazu podataka `Exercise9` sa sljedećom strukturom > Možete kopirati skriptu sa ove poveznice: https://pastebin.com/xcQKDLN8 ```SQL CREATE DATABASE Exercise9 GO USE Exercise9 GO CREATE TABLE Genre ( [Id] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](256) NOT NULL, [Description] [nvarchar](max) NOT NULL, PRIMARY KEY ([Id]) ) GO SET IDENTITY_INSERT Genre ON GO INSERT INTO Genre (Id, [Name], [Description]) VALUES (1, 'Rock', 'Otherwise known as ‘Rock & Roll,’ rock music has been a popular genre since the early 1950s.'), (2, 'Jazz', 'Identifiable with blues and swing notes, Jazz has origins in European and West African culture.'), (3, 'Electronic Dance Music', 'Typically referred to as EDM, this type of music is created by DJs who mix a range of beats and tones to create unique music.'), (4, 'Dubstep', 'Dubstep is an electronic dance music subgenre that originated in the late 1990s’ in South London.'), (5, 'Techno', 'Techno is yet another sub-genre of electronic dance music. This genre became popular in Germany towards the end of the 1980s and was heavily influenced by house music, funk, synthpop, and futuristic fiction.'), (6, 'Rhythm and Blues (R&B)', 'R & B is one of the world’s top music genres combining gospel, blues, and jazz influences.'), (7, 'Country', 'Country music is another one of the world’s top music genres. Originating in the 1920s, Country has its roots in western music and American folk.'), (8, 'Pop', 'The term ‘Pop’ is derived from the word ‘popular.’ Therefore, Pop music is a genre that contains music generally favored throughout society.'), (9, 'Indie Rock', 'In terms of genre, Indie Rock lies somewhere between pop music and rock and roll.'), (10, 'Electro', 'Electro blends electronic music and hip hop to create music that is similar to disco in sound.') GO SET IDENTITY_INSERT Genre OFF GO CREATE TABLE Song ( Id int NOT NULL IDENTITY (1, 1), [Name] nvarchar(256) NOT NULL, [Year] int NULL, GenreId int NOT NULL, DeletedAt datetime2(7) NULL, CONSTRAINT PK_Song PRIMARY KEY (Id), CONSTRAINT FK_Song_Genre FOREIGN KEY(GenreId) REFERENCES dbo.Genre (Id) ) SET IDENTITY_INSERT Song ON GO INSERT INTO Song (Id, [Name], [Year], GenreId, DeletedAt) VALUES (1, 'A-ha - Take On Me', 1985, 8, NULL), (2, 'Tina Turner - What''s Love Got to Do with It', 1984, 8, NULL), (3, 'Van Halen - Jump', 1984, 1, NULL), (4, 'Franz Ferdinand - Take Me Out', 2004, 9, NULL), (5, 'DJ Snake - Lean On', 2015, 10, NULL), (6, 'Louis Armstrong - What a Wonderful World', 1967, 2, NULL), (7, 'Deleted Song', 1967, 2, '2024-04-27 11:41:00') GO SET IDENTITY_INSERT Song OFF GO ``` Postavljanje solutiona: - Stvorite MVC rješenje bez HTTPS podrške Postavljanje modela i repozitorija: - Instalirajte EF pakete u projekt ``` dotnet add package Microsoft.EntityFrameworkCore --version 7 dotnet add package Microsoft.EntityFrameworkCore.Design --version 7 dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 7 ``` > Ne zaboravite se prebaciti (`cd`) u mapu projekta! - Konfigurirajte EF connection string u `appsettings.json` ```JSON "ConnectionStrings": { "ex9cs": "server=.;Database=Exercise9;Trusted_Connection=True;TrustServerCertificate=True;MultipleActiveResultSets=true" } ``` > Postavite točan connection string! - Napravite reverse engineering baze podataka i postavite servis u `Program.cs` ``` dotnet ef dbcontext scaffold "Name=ConnectionStrings:ex9cs" Microsoft.EntityFrameworkCore.SqlServer -o Models --force ``` > Ako `dotnet ef` nije instaliran, instalirajte taj alat! > - `dotnet tool install --global dotnet-ef --version 7` > Možda ćete trebati ponovno pokrenuti Visual Studio ako ste u učionici. ```C# builder.Services.AddDbContext(options => { options.UseSqlServer("name=ConnectionStrings:ex9cs"); }); ``` "Launch settings" postavke: - Postavite port na 6555 Dodavanje kontrolera: - Koristite predložak "MVC Controller with read/write actions" za stvaranje kontrolera - Nazivi kontrolera: `GenreController`, `SongController` - Proslijedite db kontekst kontroleru pomoću konstruktorskog ubacivanja zavisnosti (engl. dependency Injection - DI) u **oba** kontrolera. - Primjer za `GenreController`: ```C# private readonly Exercise9Context _context; public GenreController(Exercise9Context context) { _context = context; } ``` "Index" akcija: - U `GenreController` koristite akciju `Index()` za prikaz žanrova - Dodajte prazan Razor prikaz `Index.cshtml` - Koristite `ViewBag` za prosljeđivanje žanrova u prikaz ``` public ActionResult Index() { ViewBag.Genres = _context.Genres; return View(); } ``` - U `Index.cshtml` prikazu preuzmite žanrove iz ViewBaga ``` @{ var genres = ViewBag.Genres as IEnumerable; } ``` - U `Index.cshtml` prikazu generirajte HTML kod iz tih podataka - koristite jednostavan ul/li HTML popis ```HTML ``` - U `SongController` koristite akciju `Index()` za prikaz pjesama - za svaku pjesmu prikažite naziv pjesme i godinu kada je pjesma izdana - primjer: "A-ha - Take On Me (1985)" Ažurirajte navigaciju na "layout" stranici: - u \_Layout.cshtml dodajte navigacijske poveznice na popis žanrova i popis pjesama. Primjer za kontroler `Genre`: ```HTML ``` Testirajte navigaciju i stranice. ### 9.2 Stvorite prikaz s CSS stilom Ovdje ćete napraviti podršku za određeni stil u prikazu u kojem Vam je to potrebno. - Dodajte imenovanu sekciju u prikaz ```C# @await RenderSectionAsync("Styles", required: false) ``` > Ovo je način da u "layout" prikazu rezervirate mjesto za JavaScript kod. - Dodajte stil za žanr/indeks: dodajte podmapu `wwwroot/css/genres` i dodajte joj datoteku `index.css` ```CSS ul.genre-list { list-style-type: none; margin: 0; padding: 0; } ul.genre-list li { border: 1px solid black; margin: 1em; padding: 1em; color: #fff; background: rgb(2,0,36); background: linear-gradient(0deg, rgba(2,0,36,1) 0%, rgba(150,174,180,1) 100%); box-shadow: rgba(150,174,180,1) 5px 5px 5px; } ``` - Dodajte poveznicu na stil u prikaz - prikazat će se u rezerviranoj sekciji na "layout" prikazu ```HTML @section Styles { } ``` - Za stiliziranje stranice s pjesmama možete koristiti potpuno isti tijek rada: dodajte stylesheet datoteku i poveznicu u predložak prikaza pjesama `Index.cshtml` ### 9.3 Upotrijebite ViewData i ViewBag za prijenos podataka s kontrolera na prikaz - što god želite proslijediti prikazu, možete to učiniti iz akcije putem `ViewData` ili `ViewBag` strukture - na primjer, u kodu akcije, prosljeđivanje podataka iz akcije u prikaz ```C# ViewData["genres"] = _context.Genres; //...is equivalent to... ViewBag.Genres = _context.Genres; ``` - na primjer, referenciranje podataka u prikazu ```C# @{ var genres = ViewData["genres"] as IEnumerable; //...is equivalent to... var genres = ViewBag.Genres as IEnumerable; } ``` - tada je renderiranje HTML-a jednostavno ```HTML
    @foreach (var genre in genres) {
  • @genre.Name: @genre.Description
  • }
``` ### 9.4 Prikaz podataka kao uobičajenih elemenata HTML obrasca Upotrijebite akciju `Index` kontrolera `Song` za prikaz nekih uobičajenih elemenata HTML obrasca. Akcija: ```C# ViewBag.Songs = _context.Songs; ViewBag.ExampleText = "Some text"; ViewBag.ExampleNumber = 1987; ViewBag.Genres = _context.Genres; ``` Razor predložak: ```HTML @{ var genres = ViewBag.Genres as IEnumerable; }


``` ### 9.5 Prikazivanje podataka kao HTML elemenata obrasca pomoću HTML pomoćnika HTML pomoćnici (engl. HTML helpers) mogu smanjiti količinu koda koji pišete za prikaz HTML-a u vašem predlošku. Postoje pomoćnici koje jednostavno možete koristiti, poput `@Html.TextBox()`. Postoje i drugi koje trebate putem parametara _nahraniti_ određenim instancama objekata. Primjer je `@Html.DropDownList()` koji prima zbirku instanci `SelectListItem`. Dakle, dodajmo kolekciju instanci objekta `SelectListItem` u `Index` akciju `Song` kontrolera i upotrijebimo to u predlošku. ```C# // Akcija ViewBag.Songs = _context.Songs; ViewBag.ExampleText = "Some text"; ViewBag.ExampleNumber = 1987; ViewBag.Genres = _context.Genres; ViewBag.GenreDropDownItems = _context.Genres.Select(x => new SelectListItem { Text = x.Name, Value = x.Id.ToString() }); ``` ```HTML
@using(Html.BeginForm()) { Text input: @Html.TextBox("ExampleText")
Numeric input: @Html.TextBox("ExampleNumber")
Select genre: @Html.DropDownList("GenreDropDownItems") } ``` ### 9.6 Slanje podataka na poslužitelj pomoću HTML obrasca Zapamtite: - Podaci se šalju na poslužitelj pomoću atributa `method` navedenog u `
` (`GET` ili `POST`) - Podaci se šalju krajnjoj točki poslužitelja koja je navedena u `` atributu `action` - Na poslužitelj se šalju samo podaci koji se nalaze unutar elemenata obrasca s atributom `name` - Primjer: ```HTML

``` Napišimo kod koji može poslati (submit) podatke: - dodajte `action` atribut u obrazac: "/Genre/Index" - dodajte `method` atribut u obrazac: "POST" - dodajte `name` atribute elementima obrasca - dodajte gumb za slanje u obrazac Primjer: ```HTML


``` POST zahtjev treba obraditi odgovarajućom akcijom: ```C# [HttpPost] public ActionResult Index(string ExampleTxt, int ExampleNum, string SelectedGenre) { return RedirectToAction(); } ``` ### 9.7 Korištenje HTML pomoćnika za smanjenje koda Pogledajmo kako korištenje HTML pomoćnika smanjuje kod. Za HTML pomoćnike imenovanje je važno. **Isto ime se koristi i za ViewBag ključ za prikaz vrijednosti i za generirani atribut `name`.** ```C# using(Html.BeginForm()) { Text input: @Html.TextBox("ExampleText")
Numeric input: @Html.TextBox("ExampleNumber")
Select genre: @Html.DropDownList("GenreDropDownItems") } ``` ```C# [HttpPost] public ActionResult Index(string ExampleText, int ExampleNumber, int GenreDropDownItems) { return RedirectToAction(); } ``` > Usporedite količinu koda kada ne koristite HTML pomoćnike i kada koristite HTML pomoćnike. > > Podržani su sljedeći HTML pomoćnici: > > Html.ActionLink() renderira `` > Html.TextBox() / Html.TextBoxFor() renderira `` > Html.TextArea() / Html.TextAreaFor() renderira `` > Html.CheckBox() / Html.CheckBoxFor() renderira `` > Html.RadioButton() / Html.RadioButtonFor() renderira `` > Html.DropDownList() / Html.DropDownListFor() renderira `` > Html.ListBox() / Html.ListBoxFor() renderira multi-select `` > Html.Hidden() / Html.HiddenFor() renderira `` > Html.Password() / Html.PasswordFor() renderira `` > Html.Label() / Html.LabelFor() renderira `