Bu bölümde bir veritabanına model üzerine yüklenen kayıtları web sayfası üzerinde gösterilmesini inceleyeceğiz. Öncelikle kodlar bir görelim, ardından kodları açıklayalım.
Index.cshtml bir dosyanın ilk erişilen dosyasıdır. Başka bir deyişle tarayıcı üzerinden hem https://localhost:5001/Movies/Index hem de https://localhost:5001/Movies/ yazarak ulaşabiliriz. Bu dosya Index.cshml.cs bağlı çalışır. Verileri .cs uzantılı dosya üzerinden alır.
index.cshtml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.EntityFrameworkCore; using RazorPagesMovie.Models; namespace RazorPagesMovie.Pages.Movies { public class IndexModel : PageModel { private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context; public IndexModel(RazorPagesMovie.Models.RazorPagesMovieContext context) { _context = context; } public IList<Movie> Movie { get;set; } public async Task OnGetAsync() { Movie = await _context.Movie.ToListAsync(); } } } |
RazorPagesMovie.Models.RazorPagesMovieContext veritabanı işlemleri için bir köprüdür. IndexModel sınıfı yapıcı üzerinden bu değeri alır. OnGetAsync() metodu sayfa istediğinde devreye girer ve Movie listesi (IList<Movie>) üzerine ToListAsync() fonksiyonu ile kayıtları taşır. SQL kullanan geliştiriciler ilk başlangıçta bir “SELECT” sorgusu arar. Ancak EF Core gibi ORM araçları fonksiyonlar üzerinden SQL sorguları otomatik olarak üretir ve nesneleri oluşturur. Burada diğer bir konu ise işlemin async yani asenkron olmasıdır. Senkron bir yapıda tüm kullanıcıların istekleri sırasıyla cevaplanır. Ama asenkron yapıda işi kısa sürede gerçekleşen bir isteğin cevabı hemen gönderilir. Sizinde takdir edeceğiniz gibi, İnternet gibi bir ortamda asenkron bir yapı kullanmak daha iyi olacaktır. Ancak, örneğin sonuçların beklenmesi gibi öyle durumlar vardır ki asenkron yapı dışına çıkılması gerekir. await ifadesi ile tüm sonuçlar beklenir, ardından sonuçlar döndürülür. Şimdi Movie değişkenine aldığımız sonuçları index.cshtml üzerinden ulaşalım.
index.cshtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
@page @model RazorPagesMovie.Pages.Movies.IndexModel @{ ViewData["Title"] = "Index"; } <h1>Index</h1> <p> <a asp-page="Create">Create New</a> </p> <table class="table"> <thead> <tr> <th> @Html.DisplayNameFor(model => model.Movie[0].Title) </th> <th> @Html.DisplayNameFor(model => model.Movie[0].ReleaseDate) </th> <th> @Html.DisplayNameFor(model => model.Movie[0].Genre) </th> <th> @Html.DisplayNameFor(model => model.Movie[0].Price) </th> <th></th> </tr> </thead> <tbody> @foreach (var item in Model.Movie) { <tr> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @Html.DisplayFor(modelItem => item.ReleaseDate) </td> <td> @Html.DisplayFor(modelItem => item.Genre) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> | <a asp-page="./Details" asp-route-id="@item.ID">Details</a> | <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a> </td> </tr> } </tbody> </table> |
@page Razor kodlarının çalışması içindir.
@model directive, Razor sayfasına gelecek modeli belirler. @model RazorPagesMovie.Pages.Movies.IndexModel ifadesi ile index.cshtml.cs dosyasındaki sınıfa ulaşılır.
ViewData[“Title”] = “Index” ifadesi ile _Layout bölümündeki Title değişkenine veri gönderilir. Burada ViewData anahtar ve değerden oluşur. ViewData[“Title”] şeklinde çağırım yapılarak değer görüntülenebilir. (get işlemi) ViewData[“Title”] = “Index” şeklinde ise değer güncellenebilir veya yaratılabilir. (set ifadesi)
<a asp-page=”Create”>Create New</a> ifadesi https://localhost:5001/Movies/Create yani Movies içindeki Create.cshtml çağırır. Oluşan html çıktısı <a href=”/Movies/Create”>Create New</a> şeklindedir. Burada asp-page=”Create” ifadesi aslında Razor’a özel bir durumdur. Bu konuya Tag Helpers denir. Razor üzerinde özel etiketlerle işlemleri kolaylaştırma olarak görülebilir. Tag Helpers etiketlerinin hepsi sunucu tarafında uygun HTML kodlarına çevrilir ve istemci tarafına saf HTML gönderilir.
@Html.DisplayNameFor(model => model.Movie[0].Title) İlk kaydın kayıt ismini çeker. Burada Model üzerinde kullandığımız Title kelimesi döner. Ancak, kayıt ismini model üzerinde değişik yaparak değiştirilebilir. Validation konusunda bu konuyu açacağız. DisplayNameFor HTML Helpers, görülen adı görüntülemek için lambda ifadesinde yer alan Title özelliğini inceler. Lambda ifadesi bu durumda bir değerlendirme işlemi yapmaz. Bunun anlamı model, model.Movie veya model.Movie [0] null veya boş olduğunda bir erişim ihlali üretmez. Ancak tüm ifadeye geçildiğinde (örneğin @Html.DisplayFor(modelItem => item.Title)) lambda ifadesi değerlendirildiği zaman, modelin özellik değeri değerlendirilir. @Html.DisplayNameFor ve @Html.DisplayFor birbirinden ayrı olduğunun dikkatini çekerim. İlk ifade isim ikinci ifade ise veriyi çekmek için kullanılır.
Bir Movie listesinde birden fazla kayıt olması beklenir. Bu durumda tüm kayıtları çekmek için @foreach (var item in Model.Movie) kullanılmıştır. item bir Movie nesnesidir. item.Title ile movie nesnesi içindeki Title değişkenine ulaşılır. @Html.DisplayFor(modelItem => item.Title) ile Movie listesindeki item.Title değeri görüntülenir.
Son bölümde Edit, Details ve Delete linkleri vardır. @item.ID birincil anahtar iken bu işlemlerin yapılması için önemli bir değerdir. asp-route-id oluşan linkin sonuna bir GET ifadesi gibi eklenir. Örneğin, <a asp-page=”./Edit” asp-route-id=”@item.ID”>Edit</a>ifadesinin html çıktısı <a href=”/Movies/Edit?id=1″>Edit</a> şeklinde bir link oluşur.