Anlatıma geçmeden önce AspNet Core 8.0 ile geliştirdiğimiz bu projeye ait linkleri aşağıda sıraladım.
AspNet Core 8.0 projesi için linkler
Ayrıca bir önceki yazıyı okumadıysanız;
Bu derste müşterilerimizin yaptığı yorumları anasayfada göstermek için component haline getirdiğimiz kısmı tümü ile ele alıyor olacağız.
Data tarafında SQL query ile tablo oluşturma
Bu adım için elbette Docker’da SQL container’ı çalışıyor olmalı. Azure Data Studio kullandığım için ADS’yi açıp database’e bağlanıyorum. Ardından db’ye sağ tuş ile tıklayıp yeni query butonuna basıyorum.
Ardından açılan query alanında aşağıdaki kodları yazıyorum. Hepsini açıklayacağım;
CREATE TABLE Testimonial
(
TestimonialID int PRIMARY KEY IDENTITY(1,1),
NameSurename NVARCHAR(100),
Title NVARCHAR(100),
Comment NVARCHAR(500),
Status bit,
)
Burada CREATE TABLE ile bir tablo oluşturacağımızı bildirdik. Ardından tablomuzun ismini yazdık ve parantezler içerisinde de tablomuzun sütunları ile ilgili alanları tanımladık.
Bir ID’ye ihtiyacım olduğu için primary key olarak işaretledim ve identity kımsında 1den başlayarak 1er 1er artması gerektiğini söyledim. NameSurename alanını NVARCHAR(100) olarak belirttim. Bu data tarafında 100 karakterli bir metin alanı oluşturmamıza yarıyor. Status sütununda ise boolean bir değer tutabilmek için 1 yada 0 değeri alan bit kavramını kullandık.
Bu işlem sonucu f5 veya Run butonu yardımı ile queryi çalıştırıyoruz.
Ardından “Commands completed successfully.” yazısını gördüysek tablo oluşturma işlemimiz başarılı bir şekilde gerçekleşti anlamına geliyor. Sol tarafta db’yi refresh yaparsak tablolar klasöründe yeni tablomuzu görüntüleyebiliriz.
OurClientsComponent API tarafını hazırlayalım
İlk olarak Dtos hazırlamak ile başlayabiliriz.
API Katmanı > Dtos > TestimonialDtos
adında bir klasör oluşturuyoruz ve sadece listeleme ile uğraşacağımız için ResaultTestimonialDto adında bir class oluşturalım.
namespace RealEstate_Dapper_Api.Dtos.TestimonialDtos
{
public class ResaultTestimonialDto
{
public int TestimonialID { get; set; }
public string NameSurename { get; set; }
public string Title { get; set; }
public string Comment { get; set; }
public bool Status { get; set; }
}
}
Şimdi repository tarafını da yazalım.
API Katmanı > Repositories > TestimonialRepositories
adında bir klasör oluşturalım ve içerisine interface ile sınıfımızı oluşturalım.
ITestimonialRepository interface’imiz şu şekilde olacak;
using RealEstate_Dapper_Api.Dtos.TestimonialDtos;
namespace RealEstate_Dapper_Api.Repositories.TestimonialRepositories
{
public interface ITestimonialRepository
{
Task<List<ResaultTestimonialDto>> GetAllTestimonialAsync();
}
}
Repository’mizin kendisi ise şu şekilde olacak;
using Dapper;
using RealEstate_Dapper_Api.Dtos.TestimonialDtos;
using RealEstate_Dapper_Api.Models.DapperContext;
namespace RealEstate_Dapper_Api.Repositories.TestimonialRepositories
{
public class TestimonialRepository:ITestimonialRepository
{
private readonly Context _context;
public TestimonialRepository(Context context)
{
_context = context;
}
public async Task<List<ResaultTestimonialDto>> GetAllTestimonialAsync()
{
string query = "Select * From Testimonial";
using(var connection = _context.CreateConnection())
{
var values = await connection.QueryAsync<ResaultTestimonialDto>(query);
return values.ToList();
}
}
}
}
Özellikle dikkat etmemiz gereken kısımları kalın olarak işaretledim. İlk olarak repositorymiz interface’den kalıtım almalı. Ardından implement interface yöntemi ile GetAllTestimonialAsync metodunu otomatik çağırabiliriz. Context oluşturmamız gerekiyor. Amacımız dataya bağlanmak çünkü. Constructor(yapıcı) metod ile her repository isteğinde context nesnesi oluşturması gerektiğini bildiriyoruz. Ardından metodumuza gelelim. GetAllTestimonialAsync metodu async olarak işaretlememiz gerekiyor ve dönüş tipi ResaultTestimonialDto olmalı. query değişkeninde Testimonial tablosunu yazdığımızdan emin olmalıyız. values kısmında QueryAsync metoduna dönüş tipi olarak ResaultTestimonialDto belirtmeyi unutmuyoruz.
Data tarafına örnek veri girişi yapmayı unutmayın.
Kendi kullandığım örnek datanın JSON hali;
[
{
"testimonialID": 1,
"nameSurename": "Eyüp Furkan Tüylü",
"title": "İnşaat Mühendisi",
"comment": "Bu şirketle çalışmak harikaydı. Profesyonellikleri ve hızları beni etkiledi. İşlerini gerçekten iyi yapıyorlar.",
"status": true
},
{
"testimonialID": 2,
"nameSurename": "Ayşe Yılmaz",
"title": "Muhasebeci",
"comment": "Bu emlak projesiyle tanıştığımda, ilk izlenimim sadece olumlu değil, aynı zamanda heyecan vericiydi. Harika bir konumda bulunan dairem, modern tasarımı ve lüks olanakları ile yaşam standartlarımı yükseltti. Emlak ekibi, her adımda yardımcı oldu ve sorularımı her zaman yanıtladı. Bu proje sayesinde rüya evime kavuştum ve çok mutluyum.",
"status": true
},
{
"testimonialID": 3,
"nameSurename": "Mehmet Demir",
"title": "Yazılım Mühendisi",
"comment": "Bu emlak projesi, hem yatırım hem de konut amaçlı harika bir seçenekti. Dairem yüksek kaliteli malzemelerle inşa edilmişti ve manzara inanılmazdı. Proje sahipleri, sürecin her aşamasında şeffaf ve güvenilirdi. Bu yatırım, geleceğim için harika bir karar oldu.",
"status": true
},
{
"testimonialID": 4,
"nameSurename": "Zeynep Kaya",
"title": "Öğretmen",
"comment": "Bu emlak projesi, ailem için mükemmel bir ev bulma sürecimizi kolaylaştırdı. Çocuklarımız için güvenli ve konforlu bir ortam sağlıyor. Emlak danışmanları, ihtiyaçlarımıza uygun bir çözüm bulmamıza yardımcı oldular ve her detayı düşündüler. Bu projeyi herkese tavsiye ederim.",
"status": true
},
{
"testimonialID": 5,
"nameSurename": "Ali Şahin",
"title": "İş insanı",
"comment": "Bu emlak projesinin sunduğu yatırım fırsatı beni etkiledi. Hem ticari hem de konut alanında bu projede yatırım yaptım ve sonuçlar harika oldu. Değerli emlak ekibi, her zaman profesyonel ve yardımseverdi. Teşekkürler!",
"status": true
},
{
"testimonialID": 6,
"nameSurename": "Sevgi Arslan",
"title": "Ev Hanımı",
"comment": "Bu emlak projesi, ailem için güvenli ve sıcak bir yuva bulmamıza yardımcı oldu. Dairemizin tasarımı ve kalitesi gerçekten etkileyici. Emlak danışmanları, bizim için en iyi seçeneği bulmamızda bize büyük destek sağladılar. Bu projeyi seçtiğimiz için çok mutluyuz.",
"status": false
}
]
Controller Tarafında EndPoint oluşturalım
API Katmanı > Controllers > TestimonialsController
adında ApiController oluşturuyoruz.
using Microsoft.AspNetCore.Mvc;
using RealEstate_Dapper_Api.Repositories.TestimonialRepositories;
namespace RealEstate_Dapper_Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TestimonialsController : ControllerBase
{
private readonly ITestimonialRepository _testimonialRepository;
public TestimonialsController(ITestimonialRepository testimonialRepository)
{
_testimonialRepository = testimonialRepository;
}
[HttpGet]
public async Task<IActionResult> TestimonialList()
{
var values = await _testimonialRepository.GetAllTestimonialAsync();
return Ok(values);
}
}
}
Dikkat etmeniz gereken yerleri bold olarak işaretledim. Route api/controller adı şeklinde olacak. ApiController olduğunu belirttik. ControllerBase’den miras/kalıtım alacak. Bu sayede ControllerBase’de tanımlanan her şey burada da geçerli olacak.
repositoryden bir nesne türettik ve yapıcı metoda yardımı ile bu controller’a her gelen istek için bunu oluşturmasını söyledik.
HttpGet metodu olacağını söyledik. Asenkron bir işlem olacak yani veri gelirken uzun sürebileceğini bildirdik. Task ile async kullandığımız için IActionResult’u sarmaladık. EndPoint’imizin adını TestimonialList olarak belirledik. await ile repositoryden dönecek cevabı bekledik ve ok(values) ile datayı döndük.
Elbette program.cs içerisinde şu kodu da eklemeyi unutmuyoruz. Yoksa hata alırız;
builder.Services.AddTransient<ITestimonialRepository, TestimonialRepository>();
Ön-yüz tarafını hazırlayalım
İlk olarak Dtos kısmını hazırlayalım. Bunun için aslında API katmanındaki klasörü kopyalayıp UI katmanı içindekine yapıştırabiliriz. Şöyle adım adım anlatayım size;
API katmanının içerisinde Dtos klasörünü açın ve TestimonialDtos’u seçin. Ardından CTRL C veya macOS için cmd C yapın.
UI katmanının içerisinde Dtos klasörüne tıklayın. Ardından CTRL V veya macOS için cmd V yapın.
Şimdi değiştirmemiz gereken bir kod var bunun için UI katmanındaki TestimonialDtos içerisindeki ResaultTetimonialDto.cs dosyasını açalım ve en üstteki namespace alanını güncelleyelim.
namespace RealEstate_Dapper_UI.Dtos.TestimonialDtos
Burada API yazıyordu. Biz bunu UI olarak değiştirdik.
DefaultOurClientsComponentPartial adını değiştiriyoruz.
Kısa yol olarak ideler size bunun imkanını sunuyor. İsmi seçtikten sonra refactor diyerek bunu yapabilirsiniz. Eksik kısımlar varsa onları da değiştirmelisiniz.
Değiştirmeniz gerekenler;
- Default > Index.cshtml içerisindeki InvokeAsync kısmı
- ViewComponents > _DefaultOurClientsComponentPartial dosya ismi ve içerideki class ismi
- Views > Shared > Components > _DefaultOurClientsComponentPartial klasörü adı
Bunların değiştiğinden emin olun.
Ardından ViewComponents > HomePage içerisindeki _DefaultOurTestimonialComponentPartial.cs i güncelliyoruz.
using System;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using RealEstate_Dapper_UI.Dtos.TestimonialDtos;
namespace RealEstate_Dapper_UI.ViewComponents.HomePage
{
public class _DefaultOurTestimonialComponentPartial:ViewComponent
{
private readonly IHttpClientFactory _httpClientFactory;
public _DefaultOurTestimonialComponentPartial(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var client = _httpClientFactory.CreateClient();
var responseMessage = await client.GetAsync("http://localhost:5010/api/Testimonials");
if(responseMessage.IsSuccessStatusCode)
{
var jsonData = await responseMessage.Content.ReadAsStringAsync();
var values = JsonConvert.DeserializeObject<List<ResaultTestimonialDto>>(jsonData);
return View(values);
}
return View();
}
}
}
Şimdi unutmadan _ViewImports.cshtml’e gidip dtomuzun yolunu belirtelim.
@using RealEstate_Dapper_UI.Dtos.TestimonialDtos
Artık componenti güncelleyebiliriz.
UI Katmanı > Views > Shared > Components > _DefaultOurTestimonialComponentPartial klasöründe Default.cshtml’i açalım ve kodlarımızı yazmaya başlayalım.
@model List<ResaultTestimonialDto>
<section class="w3l-index3" id="about">
<div class="midd-w3 py-5">
<div class="container pb-lg-5 pb-md-4 pb-2">
<div class="row">
<div class="col-lg-5 pr-lg-0">
<div class="w3l-left-img1">
</div>
</div>
<div class="col-lg-7 pl-lg-0">
<div class="w3l-right-info">
<h6 class="title-small">Referanslarımız</h6>
<div class="client-grid">
<div class="client-title">
<h3 class="title-big">Müşterilerimizin görüşlerine değer veriyoruz.</h3>
</div>
<div class="clients-info">
<h3 class="title-big">150</h3>
<p>Mutlu Müşteriler</p>
</div>
</div>
<div class="w3l-clients" id="testimonials">
<div id="owl-demo1" class="owl-carousel owl-theme mt-4 pt-2 mb-4">
@foreach (var item in Model)
{
<div class="item">
<div class="testimonial-content">
<div class="testimonial">
<div class="testi-des">
<div class="peopl align-self">
<h4>@item.NameSurename</h4>
<p class="indentity">@item.Title</p>
</div>
</div>
<blockquote>
<q>
@item.Comment
</q>
</blockquote>
</div>
</div>
</div>
}
</div>
</div>
<a href="#agents" class="btn btn-style btn-primary mt-5">Acentamız ile iletişime geçin.</a>
</div>
</div>
</div>
</div>
</div>
</section>
İşlem başarılı bir şekilde tamamlandı! Bir sonraki derste görüşmek üzere.