Reklam

ASP.NET Core'da View Component ve Partial View Yapısı Nedir?

ASP.NET Core'da View Component ve Partial View Yapısı Nedir?
Merhaba, bu yazımda ASP.Core’da View Component kavramı üzerinde duracağım. View Component’in ne olduğundan bahsettikten sonra bu yapıyı projelerinizde nasıl kullanabileceğinizden bahsedeceğim. Yazımı anlaşılır kılmak için örnek kodlar ve fotoğraflardan da yararlanacağım. Hazırsanız başlayalım.

Component Yapısı Nedir?

Component, tekrar tekrar kullanılabilen kod bloklarıdır, parçalarıdır. Pek çok web uygulama çerçevesinde bileşen (component) yapıları farklı şekillerde kullanılır. Örneğin Angular, component yapısının kullanıldığı bir web uygulama çerçevesidir. (web application framework)

Component Yapısı Nasıl Çalışır?

Bileşen (Component), genelde bir kodun bütününden alınır ve sonrasında tekrar tekrar kullanılır. Örneğin, bir web sayfanız var. Bir iletişim sayfası oluşturup iletişim formu eklemek istiyorsunuz. Bunun için yeni bir iletişim sayfası açıyorsunuz ve iletişim formunuzu, gerekli tasarımları yaptıktan sonra sayfanıza ekliyorsunuz. Aradan bir süre geçiyor ve aynı tasarımdaki formu bu sefer de ana sayfanıza eklemek istiyorsunuz. Component yapısı tam da burada hayatımızı kolaylaştırıyor. Hemen açıklayayım. Hiç bir yapı kullanmadığınız taktirde ana sayfanıza aynı formu eklemek için aynı HTML kodunu kopyalamanız gerekir. Bunu yaptık da ne sorun var diye düşünüyor olabilirsiniz. Sorun şu ki yarın bir gün siz formun tasarımında ya da işlevinde bir değişiklik yapıp kodunuzu değiştirirseniz, o kodu kopyaladığınız her yerde de değiştirmeniz gerekir. Bileşen yapısı olmadığında da her kopya için değişim yapmanız gerekir.

Daha spesifik bir örnek vereyim. Bir mobil uygulamanız var. Her sayfada aynı butonları kullanmanız gerekiyor. Hadi, hepsini kopyalayıp yapıştırdığınızı düşünelim. Sonrasında ise ani bir kararla tüm butonların işlevinde değişiklik yapılması gerekirse geçmiş olsun. Component yapısının tanımında tekrar tekrar kullanılabilen dememin sebebi de bu aslında. Aklınıza takılan yerler olduysa merak etmeyin. Birazdan bu örneklerden ilkini beraber kodlayacağız.

ASP.NET Core’da View Component Yapısı Nedir?

ASP.NET Core'da kod parçaları yani component’ler partial view ve view component yapılarıyla tutulabilir. View component yapıları, partial view’lere oldukça benzer olsa da onlardan daha işlevseldir. View componentler model binding ile kullanılmaz,. View componentlere gönderilen verilere bağlı olarak çalışırlar.

Yeterince edebiyat yaptığımıza göre hemen işe koyulalım ve view component yapılarını ASP.NET Core projelerinize nasıl entegre edebileceğinize bakalım.

View Component Nasıl Kullanılır?

Kodlama sırasında az evvel bahsettiğim iletişim formu örneği üzerinden yeni bir proje oluşturarak ilerleyeceğim. Bunun için Visual Studio 2022’yi kullanacağım ve Asp.NET Core 6.0 versiyonunda bir proje geliştireceğim. Siz de kendi projelerinizde benzer adımları izleyerek rahatlıkla view component yapılarını kullanabilirsiniz. Hatalar çıkarsa yorum kısmından gönderebilirsiniz.

Proje Kurulumu

İlk aşamada projeyi kuruyoruz. Projeniz varsa bu adımları atlayabilirsiniz tabi ki. 🙂 Projenizi kurduktan sonra başlangıç ekranıyla karşılaşacaksınız. Buradaki Index.cshtml dosyası bizim anasayfamız. 

ASP.NET Core View Component Yapısı Örneği
ASP.NET Core View Component Yapısı Örneği

Reklam

ASP.NET Core View Component Yapısı Örneği
ASP.NET Core’da View Component Yapısı Nedir?

İletişim Sayfası Oluşturalım

Index.cshtml dosyasını hızlıca kopyalayıp yeni bir view oluşturuyoruz. İsmini değiştiriyoruz ve Contact.cshtml yapıyoruz. Sonrasında Contact sayfamız için ContactModel oluşturuyoruz. 

ASP.NET CORE VIEW COMPONENT YAPISI

Contact.cshtml.cs dosyası içerisindeki modelin ismini değiştirmemiz gerekiyor. Eğer kopyalama işlemi sonrası değişiklik yapmazsak hata alacağız.

ASP.NET CORE VIEW COMPONENT YAPISI
ASP.NET CORE VIEW COMPONENT YAPISI

Reklam

İletişim Sayfasına HTML Form Ekleme

Contact.cshtml sayfasına girip içeriğini değiştirmeye başlayabiliriz. İlk önce modelimizi ContactModel ile değiştiriyoruz. Kafa karışıklığı oluşturmamaıs adına ViewData[’Title’]’ı da değiştirebilirsiniz.

Bu işlemlerden sonra Bootstrap kütüphanesinin kullanıldığı örnek bir HTML kodunu sayfama yapıştırıyorum.

ASP.NET CORE VIEW COMPONENT YAPISI

@page
@model ContactModel
@{
    ViewData["Title"] = "Contact Page";
}

<h1>İLETİŞİM FORMU</h1>
<hr />
<form class="row g-3">
    <div class="col-md-12">
        <label for="staticEmail2" class="visually-hidden">Email</label>
        <input type="text" class="form-control" id="staticEmail2" placeholder="email@example.com">
    </div>
    <div class="col-md-12">
        <label for="message" class="visually-hidden">Message</label>
        <textarea type="password" class="form-control" id="message" placeholder="Message"></textarea>
    </div>
    <div class="col-md-12">
        <button type="submit" class="btn btn-primary mb-3">Gönder</button>
    </div>
</form>

En sonunda projemi başlatıp “/contact” adresine gittiğimde şöyle bir sayfayla karşılaşıyorum. Burası da bizim iletişim sayfamız.

Formu Anasayfaya Kopyalayalım

Örneğe bağlı kalacak olursak; formumuzu anasayfamıza yani Index.cshtml içerisine kopyalayalım.

ASP.NET CORE VIEW COMPONENT YAPISI
ASP.CORE View Component Nedir? Nasıl Oluşturulur?
ASP.NET CORE VIEW COMPONENT YAPISI

Reklam

Aynı işleve ve tasarıma sahip olmasını istediğimiz iki formu da anasayfa ve iletişim sayfamıza koyduk. Hiç problem yok gibi. Tüh, iletişim formumuzdan isim verisini almayı unutmuşuz. İki kod için de ayrı ayrı eklememiz gerekiyor. Ekleyelim.

ASP.NET CORE VIEW COMPONENT YAPISI

Bunun yüzlerce sayfa için değiştirilmesi gerektiğini düşünsenize. Büyük bir sorun. Hadi burada view component yapısını kullanarak işimizi kolaylaştıralım.

View Component Entegrasyonu Nasıl Yapılır?

Yazının bundan sonraki kısımlarında view component yapısının nasıl kullanıldığını aynı örneği devam ettirerek anlatacağım. 

ViewComponents Dizini Oluşturma ve Sınıf Ekleme

Uygulamamızın altına ViewComponents isminde bir dizin oluşturalım. Dizine de bir sınıf oluşturalım. İletişim formunu bir bileşen içerisine taşıyacağımızdan dolayı bu sınıfa ContactForm.cs ismini veriyorum.

ASP.NET CORE VIEW COMPONENT YAPISI

namespace ViewComponentLearningApp.ViewComponents
{
    public class ContactForm
    {
	     //ContactForm.cs sınıfı. Henüz view component değil !!
    }
}

Reklam

ViewComponent Sınıfından Türetelim

ContactForm.cs sınıfını view component olarak kullanabilmemiz için ViewComponent sınıfından kalıtmamız gerekiyor. ViewComponent sınıfını kullanabilmemiz içinse using Microsoft.AspNetCore.Mvc; kodunu dosyamıza eklememiz gerekiyor.

using Microsoft.AspNetCore.Mvc;

namespace ViewComponentLearningApp.ViewComponents
{
    public class ContactForm:ViewComponent
    {
     
    }
}

Bağımlılık Ekleme ve Invoke Fonksiyonu

Dependency injection işlemini yapalım. Ardından Invoke() fonksiyonunu ekleyelim. ViewComponent yapısında bu fonksiyonu bir bakıma Controller olarak düşünebilirsiniz. ViewComponent yapıları için gerekli olan verileri, modelleri buradan sağlayacağız.

using Microsoft.AspNetCore.Mvc;

namespace ViewComponentLearningApp.ViewComponents
{
    public class ContactForm:ViewComponent
    {
        // Dependency Injection
        // Bağımlılık ekleyelim.
        public ContactForm()
        {

        }
        // Senkron işlemler için Invoke ya da asenkron işlemler için InvokeAsync komutuyla
        // view component sonucunu burada döndüreceğiz.
        public IViewComponentResult Invoke()
        {
            return View();
        }
        // Asenkron işlemler için kullanabiliriz.
        //public async Task<IViewComponentResult> InvokeAsync()
        //{
        //    return View();
        //}
    }
}

ContactForm View Component’ini Oluşturalım

View component’ler varsayılan olarak belirli konumlarda bulunmalıdır. ViewComponent’ler için bu konumlar şunlardır: (Listedeki ContactForm sizin model isminize bağlı olarak değişecektir.)

  1. /Pages/Components/ContactForm/Default.cshtml
  2. /Pages/Shared/Components/ContactForm/Default.cshtml
  3. /Views/Shared/Components/ContactForm/Default.cshtml

Ben ikinci maddedeki şekilde dizinleme yapmayı tercih ettim. Burada atlanmaması gereken önemli bir kural var. View component’lerin varsayılan (default) görünümleri (views), view component’in ismindeki bir dizin içerisinde listelenmelidir. View component sınıfında herhangi bir isim belirtilmediğinde view dosyanızı Default.cshtml olarak oluşturmalısınız.

Konum listesindeki 2. madde için dizin yapısı fotoğraftaki gibi olmalıdır.

ASP.NET CORE VIEW COMPONENT YAPISI

ContactForm içerisindeki Default.cshtml içerisine girelim ve önceden olan iletişim formumuzu yapıştıralım. 

ASP.NET CORE VIEW COMPONENT YAPISI

ViewComponent’i Razor Sayfalarımızda Kullanalım

View component’imiz hazır ve entegre edilmeyi bekliyor. Hemen devam edelim. Öncelikle biz hangi sayfalarda bu formu kullanmak istiyorduk? Contact ve Index.

Index içerisine nasıl entegre edebileceğimize bakalım. Sonrasında benzer işlemleri Contact sayfasına da uygulayacağız.

  1. Index.cshtml razor sayfasını açalım.
  2. Önceden eklediğimiz formu silelim ve yerine aşağıdaki kodu yapıştıralım. Bu kod, view component çağırmak için kullanılır.
@*View Component yapılarını entegre edebilmemiz için bu kod bloğunu kullanmamız gerekiyor.*@
@await Component.InvokeAsync("ContactForm")

İşte bu kadar. Artık basit bir view component’i nasıl kullanabileceğinizi biliyorsunuz.

Reklam

Farklı İsimlerde View Component Oluşturma

Basit bir view component oluşturduk. Peki aynı modele ihtiyaç duyan ya da sadece tasarımsal olarak ayrışan view component’leri nasıl oluşturabiliriz? Örneğin, e-posta girdisi almadığımız bir iletişim formunu da oluşturalım.

  1. ContactForm dizini içerisine Default.cshtml’den farklı bir isimde view oluşturalım. Ben adını WithoutEmail.cshtml yaptım.

  2. ContactForm ismindeki view component’imizi şu şekilde revize edelim:

    using Microsoft.AspNetCore.Mvc;
    
    namespace ViewComponentLearningApp.ViewComponents
    {
        public class ContactForm:ViewComponent
        {
            public ContactForm()
            {
    
            }
            // "viewName" parametresiyle hangi isimde bir View Component çağıracağımız belirliyoruz.
            // viewName="Default" yapma sebebimse herhangi bir parametre olmadığında Default.cshtml'yi çağırması. 
            // Bunu if else koşullarıyla da yapabilirsiniz ama çok uzatabilir.
            public IViewComponentResult Invoke(string viewName="Default")
            {
                return View(viewName);
            }
           
        }
    }
    
    // Ya da bu şekilde
    using Microsoft.AspNetCore.Mvc;
    
    namespace ViewComponentLearningApp.ViewComponents
    {
        public class ContactForm:ViewComponent
        {
            public ContactForm()
            {
    
            }
            public IViewComponentResult Invoke(string viewName)
            {
                // View Name yoksa Default çağrılacak.
                if (viewName == null)
                {
                    return View();
                }
                // viewName paramtresi gönderildiyse o parametrenin isminde bir component çağrılacak.
                return View(viewName);
            }
        }
    }
    
  3. Şimdi tek yapmamız gereken istediğimiz view component’in ismini göndermek.

    @await Component.InvokeAsync("ContactForm", new { viewName = "WithoutEmail"})
    

Component’e viewName parametresini göndermediğinizde varsayılan olarak Default.cshtml dosyası çağrılır.

View Componente Model Gönderme

Benzer yöntemi kullanarak view component’imize bir model gönderelim.

  1. Contact.cs isminde bir model oluşturalım.

    using Microsoft.AspNetCore.Mvc;
    
    namespace ViewComponentLearningApp.ViewComponents
    {
        public class Contact
        {
            public string? Name { get; set; }
            public string? Email { get; set; }
            public string? Message { get; set; }
        }
    }
    
  2. Invoke() fonksiyonuna parametre olarak ContactViewComponentModel verelim..

    using Microsoft.AspNetCore.Mvc;
    
    namespace ViewComponentLearningApp.ViewComponents
    {
        public class ContactForm:ViewComponent
        {
            public ContactForm()
            {
    
            }
            // Varsayılan bir değeri olmayan parametreleri varsayılan değer verilmiş, viewName gibi, parametrelerin gerisine yazmalısınız.
            public IViewComponentResult Invoke(ContactViewComponentModel model, string viewName="Default")
            {
                // ilk parametre view adı - ikinci parametre: model
                return View(viewName, model);
            }
        }
    }
    
  3. Razor sayfalarımızda view component’i çağırdığımız kod bloklarında bir değişiklik yapalım ve modeli gönderelim. İlk kod bloğu aynı satırda nasıl dahil edileceğini, ikinci kod bloğuysa harici olarak nasıl dahil edileceğini gösteriyor.

    @await Component.InvokeAsync("ContactForm", new { viewName = "WithoutEmail", model = new ViewComponentLearningApp.ViewComponentModel.ContactViewComponentModel()})
    
    @{
        ViewComponentLearningApp.ViewComponentModel.ContactViewComponentModel farkliSatirda = new ViewComponentModel.ContactViewComponentModel()
        {
            Name = "Ömer",
            Email = "info@ofcskn.com",
            Message = "iyi kodlamalar!"
        };
    }
    @await Component.InvokeAsync("ContactForm", new { viewName = "WithoutEmail", model = farkliSatirda})

ViewComponent’in Faydaları Nelerdir?

  1. Tekrarlanan kodları merkezileştirir. Değişim, revize etme gibi pek çok işlemde kolaylık sağlar.
  2. Farklı tasarımlarda olan ama aynı modelleri kullanan view dosyaları oluşturulabilir. Örneğin, iki farklı tasarımda iletişim formu kullanabilirsiniz ve aralarında geçiş yapabilirsiniz.
  3. Enerji ve zaman tasarrufu sağlar. Tekrarın önüne geçildiğinden işimizi kolaylaştırır.
  4. Kendi başına bir controller gibi çalıştığından model göndermeye ihtiyaç duymaz. Sadece parametre gönderilmesi yeterli olur.

View Component ve Partial View Farkı

Partial view bir modelle kullanıldığında o modelin servisler ya da controller aracılığıyla doldurulması gerekir. Bu da her partial view kullanıldığında bir servisin eklenmesi ya da modelin controller’da doldurulması demek oluyor. Aksine view component, bir controller gibi çalıştığından her view component için harici bir model gönderilmesine ihtiyaç kalmaz. Model zaten view component’in Invoke() fonksiyonu içerisinde doldurulur. 

ASP.NET Core projelerinizde view component yapısının ne olduğundan ve nasıl kullanabileceğinizden örnek kodlar vererek bahsettim. Fotoğraflarda, kodlarda veya yazı da anlaşılmayan yerler olduysa yorumlar kısmından iletebilirsiniz. Kendinize iyi bakın. Klavyenize sağlık. 🙂

Ömer Faruk Coşkun - ÖFC
Ömer Faruk Coşkun

İstanbul Üniversitesi-Cerrahpaşa Bilgisayar Mühendisliği öğrencisiyim. Araştırmayı, öğrenmeyi ve aynı zamanda öğrendiklerimi paylaşmayı seviyorum.

Yorumlar

Belirli sürede gönderebileceğinizden fazla yorum gönderdiniz. Bir süre bekleyiniz.
Belirli sürede gönderebileceğinizden fazla yorum gönderdiniz. Bir süre bekleyiniz.
Belirli sürede gönderebileceğinizden fazla yorum gönderdiniz. Bir süre bekleyiniz.
Yorumunuz başarılı bir şekilde gönderilmiştir. Teşekkür ederiz.
Yorumunuz gönderilirken bir hata meydana geldi. Lütfen daha sonra tekrar deneyin. Sorun devam ederse lütfen bizimle iletişime geçin.
hasan
8.10.2023

hocam elimdeki temayı _layout.cshtml içine attım. menu her sayfada aynı olacağı için onları veritabanından dinamik doldurup <partial name="_menu"> şeklinde _layout.cshtml içine bir türlü çağıramadım. @model etiketini kaldırınca geliyor. ama bu kez dinamik olmuyor. kafam çok karıştı.


Ömer
12.10.2023

<partial name="_menu" model="MenuModel"> şeklinde modeli tanımlamadığın taktirde partial view hata verecektir. Onu düzeltirsen sorun çözülür. @model MenuModel etiketinin de _layout.cshtml dosyası içerisinde tanımlanmış olması gerek tabi

Reklam