Mini Dükkan Projesi Ders 008 Navigasyon Kontrollerinin Oluşturulması

Bir önceki videoda ve yazımda ufak bir hatam var öncelikle onu düzeltmekle işe başlayalım arkadaşlar; index.html dokümanımda attributelerden birisi page-classes olarak yazmışım orası şöyle olacak, sonraki es kısmı gidecek; tüm kodu ekliyorum yine index.html için:

@model UrunlerListesiViewModel

@foreach (var u in Model.Urunler)
{
    < partial name="UrunOzet" model="u" / >
   
}

Şimdi tekrar dersimize dönelim.

Bu dersin video versiyonunu da izleyebilirsiniz:

Uygulamamızda ürünleri kategori bazlı listeleme işlemi yapalım. Bunu 3 aşamada gerçekleştireceğim.

  1. HomeController içindeki Index action metodunu biraz geliştirip, repository içindeki ürünleri filtreleme,
  2. URL şemasını buna bağlı olarak geliştirme,
  3. Sitenin kenar kısmında kategori listesini oluşturma ve buradan kullanıcının gezinebilmesini sağlama, ayrıca mevcut kategoriyi burada vurgulama

Şimdi bu işlemlere başlayalım.

Ürün Listesini Filtreleme İşlemi:

Öncelikle ÜrünlerListesiViewModel sınıfımı düzenliyorum. Kodlarım şu şekilde;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MiniDukkan.Models.ViewModels
{
    public class UrunlerListesiViewModel
    {
        public IEnumerable< Urun > Urunler { get; set; }
        public SayfalamaBilgi SayfalamaBilgi { get; set; }
        public string GuncelKategori { get; set; }
    }
}

Buraya GuncelKategori diye bir property ekledim. Şimdi HomeController classımı güncelleyeceğim. Böylelikle içinde yer alan Index metodu ile kategoriye göre ürünleri filtreleyip, hangi kategorinin seçili olduğunu gösterme işlemini yapıyorum.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MiniDukkan.Models;
using MiniDukkan.Models.ViewModels;

namespace MiniDukkan.Controllers
{
    public class HomeController : Controller
    {
        private IDukkanRepository repository;
        public int SayfaBoyutu = 3;

        public HomeController(IDukkanRepository repo)
        {
            repository = repo;
        }




        public ViewResult Index(string kategori, int urunSayfa = 1)
        => View(new UrunlerListesiViewModel { Urunler = repository.Urunler.Where(u => kategori == null || u.Kategori == kategori).OrderBy(u => u.UrunID).Skip((urunSayfa - 1) * SayfaBoyutu).Take(SayfaBoyutu), SayfalamaBilgi = new SayfalamaBilgi { GuncelSayfa = urunSayfa, SayfaBasiGosterilecekUrun = SayfaBoyutu, ToplamUrunSayisi = repository.Urunler.Count() } }
        ); 
        
        

        
    }
}

Burada 3 noktada değişiklik yaptım. Öncelikle kategori adında bir parametre ekledim. Bunu eklediğim için LINQ sorgumda listeleme işlemi içinde güncelleme yaptım. Burada mantık şu oldu; eğer kategori boş değil ise Kategori ile eşleşen ürünler listelenir.

Buradaki kodda yaptığım son değişiklik ise, UrunlerListesiViewModel classıma eklediğim GuncelKategori propertysinin değerini ayarlama işlemi. Tabi bunu yapınca SayfalamaBilgi.ToplamUrunSayisi değeri yanlış hesaplanacak. Çünkü buradaki kategori filtresi hesaba katılmayacak. Buna döneceğim sonra.

Şimdi bunu yaptık sıra geldi URL düzenleme işlemine.

URL Düzenleme:

Şimdi işin içine kategoriye göre filteleme girince url kısmında bir düzenleme yapmamız gerekiyor. Bunu yapabilmek için routing konfigürasyonunda değişiklik yapmak gerek. Startup classımıza gidiyoruz ve Configure metodunda düzenleme yapıyoruz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MiniDukkan.Models;

namespace MiniDukkan
{
    public class Startup
    {
        public Startup(IConfiguration config)
        {
            Configuration = config;
        }

        public IConfiguration Configuration { get; set; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddDbContext< MiniDukkanContext >(opts => opts.UseSqlServer(Configuration["ConnectionStrings:MiniDukkanConnection"]));

            services.AddScoped< IDukkanRepository, EFDukkanRepository >();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();

            app.UseRouting();

            app.UseStatusCodePages();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute("katsayfa", "{kategori}/Sayfa{urunSayfa:int}", new { Controller = "Home", action = "Index" });

                endpoints.MapControllerRoute("sayfa", "Sayfa{urunSayfa:int}",
                    new { Controller = "Home", action = "Index", urunSayfa = 1 });


                endpoints.MapControllerRoute("kategori", "{kategori}",
                    new { Controller = "Home", action = "Index", urunSayfa = 1 });



                endpoints.MapControllerRoute("sayfalama", "Urunler/Sayfa{urunSayfa}",
                new { Controller = "Home", action = "Index", urunSayfa = 1 });
                endpoints.MapDefaultControllerRoute();
                    
            });

            HamVeri.VeriDoldur(app);
        }
    }
}

Şimdi bu URL ile ilgili bir tablo vermek istiyorum.

ASP.NET Core Routing sistemi client tarafından gelen istekleri işler ancak aynı zamanda web sayfalarına gömülebilir, URL şemaları ile uyumlu uygun giden URL’leri de oluşturabilmektedir. Routing sistem sayesinde hem gelen istekleri işlemek, hem de giden URL’leri oluşturabilme anlamında URL’leri kontrol edebilmekteyiz ve tutarlılık sağlayabilmekteyiz.

IurlHelper Interfaci ile URL  oluşturma işlevine erişim sağlayabiliriz. Zaten bu proje için önceki yazılara ve videolarıma bakarsanız tag helper içinde bu interface’i ve ilgili action metodumu kullandım.

Şimdi SayfaLinkTagHelper classımda kodlarımı düzenliyorum.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using MiniDukkan.Models.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MiniDukkan.Altyapi
{
    [HtmlTargetElement("div",Attributes ="sayfa-model")]
    public class SayfaLinkTagHelper : TagHelper
    {
        private IUrlHelperFactory urlHelperFactory;

        public SayfaLinkTagHelper(IUrlHelperFactory helperFactory)
        {
            urlHelperFactory = helperFactory;
        }

        [ViewContext]
        [HtmlAttributeNotBound]
        public ViewContext ViewContext { get; set; }

        public SayfalamaBilgi SayfaModel { get; set; }

        public string SayfaAction { get; set; }

        [HtmlAttributeName(DictionaryAttributePrefix = "page-url-")]
        public Dictionary< string, object > PageUrlValues { get; set; }
        = new Dictionary< string, object >();

        public bool PageClassEnabled { get; set; } = false;
        public string PageClass { get; set; }
        public string PageClassNormal { get; set; }
        public string PageClassSelected { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            IUrlHelper urlHelper = urlHelperFactory.GetUrlHelper(ViewContext);

            TagBuilder sonuc = new TagBuilder("div");
            for (int i = 1; i <= SayfaModel.ToplamSayfalar; i++)
            {
                TagBuilder tag = new TagBuilder("a");
                PageUrlValues["urunSayfa"] = i;
                tag.Attributes["href"] = urlHelper.Action(SayfaAction, PageUrlValues);
                //tag.Attributes["href"] = urlHelper.Action(SayfaAction, new { urunSayfa = i });

                if (PageClassEnabled)
                {
                    tag.AddCssClass(PageClass);
                    tag.AddCssClass(i == SayfaModel.GuncelSayfa ? PageClassSelected : PageClassNormal);
                }

                tag.InnerHtml.Append(i.ToString());
                sonuc.InnerHtml.AppendHtml(tag);
            }

            output.Content.AppendHtml(sonuc.InnerHtml);
        }
    }
}

Buradan Index.cshtml dosyamıza gidelim, düzenleme yapalım.

@model UrunlerListesiViewModel

@foreach (var u in Model.Urunler)
{
    < partial name="UrunOzet" model="u" / >
   
}

TagHelper tarafından işlenen div öğesine yeni bir attribute ekledim. Bu attribute URL’yi oluşturmak için kullanılıyor.

Şimdilik bu kadar bir sonraki yazıda görüşmek üzere.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir