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;
AspNet Core ile geliştirdiğimiz projenin bu bölümünde anasayfaya datan verileri getirme ile başlıyoruz.
Anasayfa’ya İlanları Getirme
İlanlarımızı önceki derslerden hatırlayacağınız üzere birer viewcomponent haline getirmiştik. Bunun için ilgili dosyaları açıyoruz;
- UI Projesi > ViewComponent > _DefaultHomePageProductList.cs
- UI Projesi > Views > Shared > Components > _DefaultHomePageProductList > Default.cshtml
Bu iki dosyada ufak değişiklikler yaparak datalarımızı getireceğiz.
Product’larımızı döndürdüğümüz bir api’miz zaten mevcuttu. Hatta biz bunu biraz daha ilerletip kategori adı ile birlikte getiriyorduk. End Point’in adı ise;
- api/Products/ProductListWithCategory
https://localhost:7034/api/Products/ProductListWithCategory
İlk olarak verileri ViewComponent içerisinde çağırmak için _DefaultHomePageProductList.cs dosyasına geçelim.
Ardından alt tarafta oluşturduğumuz Invoke metodunu şu şekilde değiştirelim;
public async Task<IViewComponentResult> InvokeAsync()
{
return View();
}
Ardından http üzerinden işlemler yapabilmek için kodumuza bir adet private nesne tanımlayacağız ve constructor ile örnek alındığında oluşmasını sağlayacağız.
using System;
using Microsoft.AspNetCore.Mvc;
namespace RealEstate_Dapper_UI.ViewComponents.HomePage
{
public class _DefaultHomePageProductList:ViewComponent
{
private readonly IHttpClientFactory _httpClientFactory;
public _DefaultHomePageProductList(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<IViewComponentResult> InvokeAsync()
{
return View();
}
}
}
Kalın işaretlediğim kodlar class’ımıza ekliyoruz.
Şimdi ise artık istek atma kısmına geldi. InvokeAsync metodu içerisinde şu kodları tanımlıyoruz;
var client = _httpClientFactory.CreateClient();
var responseMessage = await client.GetAsync("https://localhost:7034/api/Products/ProductListWithCategory");
client değişkeni sayesinde api’ye http üzerinden bir istek atıp cevabını alabileceğiz. responseMessage değişkeninde ise istek attığımız apiden dönen response’u tutacağız.
Dönen veriyi bir class’ta tutmak her zaman için faydalıdır. Bunun için bir DTO tanımlaması yapacağız. Dto genellikle api’den dönen verileri sınıflandırmak için kullandığımız bir metoddur. Bunun için UI projesinin içerisinde bir klasör tanımlıyoruz. Adı “Dtos”. Dtos içerisinde de ProductDtos adında bir klasör oluşturuyoruz ve içerisinde “ResultProductDtos.cs” adında bir class oluşturuyoruz.
ResultProductDtos class’ı bize api’den dönen verilerin bire bir aynısı verecek. Bu sayede apiden istek atıldığında dönen veriyi otomatik olarak ResultProductDtos’ta tutabileceğiz ve üzerinde işlem yapabileceğiz.
using System;
namespace RealEstate_Dapper_UI.Dtos.ProductDtos
{
public class ResultProductDtos
{
public int productID { get; set; }
public string title { get; set; }
public int price { get; set; }
public string city { get; set; }
public string district { get; set; }
public string categoryName { get; set; }
}
}
API’mizden dönen veriye göre class’ımızı yukarıdaki gibi oluşturduk. Siz api’de başka prop’lar dönüyorsanız onları da eklemelisiniz.
Burada unutmamanız gereken api’den string dönüyorsa burada string tanımlamalısınız. Eğer değerin tipi yanlış ise hata verecektir.
Newtonsoft.Json eklenmesi
Burada JSON dönüştürme işlemi gerçekleştireceğiz. Bunun için UI katmanına bir kütüphane ekleyeceğiz. Bunu da elbetteki NuGet Packages’dan yapacağız. UI projesinin üzerine sağ tuş ile tıklayıp açılan sekmede Manage NuGet Packages’ı seçiyoruz. Bir popup açılıyor ve burada Browse sekmesine gelip “Newtonsoft.Json” ı buluyoruz veya aratadabiliriz.
Kırmızı ile işaretlediğim kütüphaneyi tikleyip sağ alt taraftan Add Package butonuna basın.
Invoke Async metodunda değişiklikler
Artık responseMessage’dan dönen veriyi kontrol etmeye ve yönetmeye hazırız. Bir if sorgusu yazarak api’den dönen statünün 200’lü olduğundan emin oluyoruz ve işlemlerimize başlıyoruz.
public async Task<IViewComponentResult> InvokeAsync()
{
var client = _httpClientFactory.CreateClient();
var responseMessage = await client.GetAsync("https://localhost:7034/api/Products/ProductListWithCategory");
if(responseMessage.IsSuccessStatusCode)
{
var jsonData = await responseMessage.Content.ReadAsStringAsync();
var values = JsonConvert.DeserializeObject<List<ResultProductDtos>>(jsonData);
return View(values);
}
return View();
}
Kodumuzda if sorgusunun koşulu olarak responseMessage’ın statuscode’unun 200’lü bir değer olup olmadığına baktık. Eğer 200’lü bir değer ise iç kısımda jsonData değişkeni içerisine responseMessage’ın content kısmında yer alacak olan json veriyi ekledik. Çünkü responseMessage kısmında sadece datamız yok. header, message, error gibi bilgileri de içeriyor. Eğer responseMessage’da dataya ulaşmak istiyorsak responseMessage.Content dememiz gerekiyor.
var jsonData = await responseMessage.Content.ReadAsStringAsync();
Artık jsonData içerisinde apiden gelen verimiz var. Hemen bunu oluşturmuş olduğumuz Dto’ya dönüştürmemiz gerekecek. Bunun için;
var values = JsonConvert.DeserializeObject<List<ResultProductDtos>>(jsonData);
kodunu kullanıyoruz. values değişkeni içerisine JsonConvert metodunu kullanarak ( Newtonsoft.Json kütüphanesinden geliyor), deserialize işlemi uyguladık. DeserializeObject metodu JSON veriyi okur ve bizim istediğimiz sınıfa dönüştürür. Bu okuma esnasında bizden neye dönüştüreceğini ve neyi dönüştüreceğini bekliyor.
<List<ResultProductDtos>>
Bu kısımda neye dönüştüreceğimizi belirtiyoruz. Bir Liste olacağını ve bu listenin içindeki öğelerin ResultProductDtos sınıfından türeyeceğini belirtiyoruz.
(jsonData)
kısmında ise neyi dönüştüreceğimizi yani apiden gelen veriyi vermiş oluyoruz.
Ufak bir hatırlatma, DeserializeObject işleminin tam tersi metodu olan SerializeObjet metodu ise metin değeri okur ve JSON’a dönüştürür.
_DefaultHomePageProductList > Default.cshtml düzenlenmesi
Artık verimiz metodumuzdan dönüyor. Son bir işlem olan Default.cshtml dosyamızı düzenleyerek ekranda göstermek kaldı.
Kodumuzda birden fazla ilan vardı. Biz bunu datadan alıp göstereceğimiz için temizlememiz gerekiyor. Sadece bir tanesi kalsa yeterli olacaktır.
<section class="locations-1" id="locations">
<div class="locations py-5">
<div class="container py-lg-5 py-md-4 py-2">
<div class="heading text-center mx-auto">
<h3 class="title-big">Günün Favori İlanları</h3>
</div>
<div class="row pt-md-5 pt-4">
<div class="col-lg-4 col-md-6">
<a href="property-single.html">
<div class="box16">
<div class="rentext-listing-category"><span>Buy</span><span>Rent</span></div>
<img class="img-fluid" src="~/starter/assets/images/p1.jpg" alt="">
<div class="box-content">
<h3 class="title">$25.000.000</h3>
<span class="post">51 Merrick Way, Coral Gables, USA</span>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
</section>
Şu kod parçası bizim işimizi görecek. Bunun üzerinde foreach loop kurarak tüm öğelerimizi ekranda göstereceğiz.
@model List<RealEstate_Dapper_UI.Dtos.ProductDtos.ResultProductDtos>
Bu sayfaya bir ResultProductDots listesi döndüreceğimiz için en üste bu kodu ekliyoruz. Ardından foreach döngüsünü yazalım ve örnek bir veri yazıp kontrol sağlayalım. Kodumuzun son hali şu şekilde olmalı;
@model List<RealEstate_Dapper_UI.Dtos.ProductDtos.ResultProductDtos>
<section class="locations-1" id="locations">
<div class="locations py-5">
<div class="container py-lg-5 py-md-4 py-2">
<div class="heading text-center mx-auto">
<h3 class="title-big">Günün Favori İlanları</h3>
</div>
<div class="row pt-md-5 pt-4">
@foreach (var item in Model)
{
<div class="col-lg-4 col-md-6">
<a href="property-single.html">
<div class="box16">
<div class="rentext-listing-category"><span>Buy</span><span>Rent</span></div>
<img class="img-fluid" src="~/starter/assets/images/p1.jpg" alt="">
<div class="box-content">
<h3 class="title">@item.price</h3>
<span class="post">51 Merrick Way, Coral Gables, USA</span>
</div>
</div>
</a>
</div>
}
</div>
</div>
</div>
</section>
AspNet Core’da Program.cs üzerinde tanımlama
ViewComponent’imiz data ile Http üzerinden veri alışverişi yaptığı için Program.cs kısmında bir tanımlama yapmamız gerekiyor.
Program.cs dosyasını açalım ve “// Add services to the container.” yorum satırının hemen altına şu kodu ekleyelim.
builder.Services.AddHttpClient();
Bu kod sayesinde _DefaultHomePageProductList içerisindeki InvokeAsync metodunda kullandığımız http isteği atmamızı sağlayan şu kod çalışabilecek;
var client = _httpClientFactory.CreateClient();
Bu kodu zaten _DefaultHomePageProductList klasöründe çağırmıştık. Herhangi bir yere eklemenize gerek yok. Sadece ne işe yaradığını anlatmaya çalışıyorum.
Test Edelim
Her şeyi hazırladık. Test edelim ve verilerimiz geliyor mu kontrol edelim. Eğer price değerlerimiz geliyorsa diğer verileri de Default.cshtml içerisinde tanımlarız.
Uygulamayı çalıştırdığımızda şu şekilde bir hata aldık. Buradaki hatanın sebebi price’ın data’dan decimal geliyor olması. Ancak hatırlarsanız biz ResultProductDtos’da bunu int olarak tanımlamıştık. ResultProductDtos içerisindeki price alanını decimal olarak tanımladığımızda sorun ortadan kalkacaktır.
Bunun ardından kaydetip çalıştırdığımızda;
Uygulamamız çalışıyor.
Şimdi hemen Default.cshtml dosyasında diğer verileri de güncelleyerek bu dersi tamamlamış olalım.
API kısmında düzenlemeler yapmamız gerekiyor. İlan görseli, satılık mı kiralık mı bilgisi gibi değerler gelmiyor. Gelecek derslerde bunlar da yapılacak.