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 “Popüler Lokasyonlar” kısmını ele alıyor olacağız.
SQL Tarafında Tablo Oluşturalım
Popüler lokasyonları tutabilmek için SQL tarafında bir tabloya ihtiyacımız var. Bunun için SQL’de bir query yazarak tablomuzu oluşturacağız.
CREATE TABLE PopularLoaction
(
LocationID int PRIMARY KEY IDENTITY(1,1),
CityName NVARCHAR(100),
ImageUrl NVARCHAR(max),
)
Bunu çalıştırarak tablonun oluşmasını sağlayabiliriz.
Örnek verilerin görselleri için wwwroot klasörünün altında cityimages adında bir klasör tanımlıyoruz. Burada ben aşağıdaki görselleri kullandım. Siz farklı görselleri kullanabilirsiniz.
Şimdi SQL’e giderek data girişi yapalım.
Datamız bu şekilde olacak.
[
{
"locationID": 1,
"cityName": "Budapeşte",
"imageUrl": "/cityimages/budapest.jpeg"
},
{
"locationID": 2,
"cityName": "Dresden",
"imageUrl": "/cityimages/dresden.jpeg"
},
{
"locationID": 3,
"cityName": "Lviv",
"imageUrl": "/cityimages/lviv.jpeg"
},
{
"locationID": 4,
"cityName": "Lyon",
"imageUrl": "/cityimages/lyon.jpeg"
},
{
"locationID": 5,
"cityName": "Miami",
"imageUrl": "/cityimages/miami.jpeg"
},
{
"locationID": 6,
"cityName": "Montenegro",
"imageUrl": "/cityimages/montenegro.jpeg"
},
{
"locationID": 7,
"cityName": "Roma",
"imageUrl": "/cityimages/rome.jpeg"
},
{
"locationID": 8,
"cityName": "Sofya",
"imageUrl": "/cityimages/sofia.jpeg"
}
]
DTO Tarafını Oluşturalım
API Katmanı > Dtos > PopularLocationDtos
adresinde “ResaultPopularLocationDto” adında bir sınıf oluşturuyoruz.
namespace RealEstate_Dapper_Api.Dtos.ResaultPopularLocationDtos
{
public class ResaultPopularLocationDto
{
public int LocationID { get; set; }
public string CityName { get; set; }
public string ImageUrl { get; set; }
}
}
ve sınıf içerisinde datadan dönecek sütunların adlarını prop olarak tanımlıyoruz. Ekleme güncelleme kısmlarını sonra yapacağımız için diğer DTO’ları tanımlamadan repositoreies tanımlama işlemine geçiyoruz.
Repository Tanımlama
API Katmanı > Repositories > PopularLocationRepository
isminde bir dosya oluşturalım ve içerisinde interface ile class’ımızı tanımlayalım.
İlk olarak interface eklemek ile başlayalım. Interface’in adı “IPopularLocationRepository” olacak.
İçeriği ise şu şekilde olacak;
using RealEstate_Dapper_Api.Dtos.ResaultPopularLocationDtos;
namespace RealEstate_Dapper_Api.Repositories.PopularLocationRepository
{
public interface IPopularLocationRepository
{
Task<List<ResaultPopularLocationDto>> GetAllPopularLocationAsync();
}
}
Şimdilik sadece listeleme işlemini yapacağımız için burada sadece GetAllPopularLocationAsync metodunu tanımladık.
Ardından aynı dosya içerisinde bir de class tanımlayacağız. Adı ise “PopularLocationRepository” olacak.
using RealEstate_Dapper_Api.Dtos.ResaultPopularLocationDtos;
using RealEstate_Dapper_Api.Models.DapperContext;
namespace RealEstate_Dapper_Api.Repositories.PopularLocationRepository
{
public class PopularLocationRepository:IPopularLocationRepository
{
private readonly Context _context;
public PopularLocationRepository(Context context)
{
_context = context;
}
public Task<List<ResaultPopularLocationDto>> GetAllPopularLocationAsync()
{
throw new NotImplementedException();
}
}
}
Interface’den kalıtım alıp implement interface işlemini yapıyoruz. Ardından Context oluşturuyoruz ve constructor metod ile contex’i atıyoruz.
Ardından metodumuzda ilgili kodları yazacağız.
public async Task<List<ResaultPopularLocationDto>> GetAllPopularLocationAsync()
{
string query = "Select * From PopularLocation";
using (var connection = _context.CreateConnection())
{
var values = await connection.QueryAsync<ResaultPopularLocationDto>(query);
return values.ToList();
}
}
GetAllPopularLocationAsync metodumuzda listeleme işlemi yapacağımız için içeriği buna göre düzenledik.
query değişkeninde PopularLocation tablosundaki tüm verileri getireceğimiz sql query’sini yazdık. Alt taraftaki işlemde ise db ile context yardımı ile bir bağlantı oluşturup içeride de query’i dataya gönderip sonucunu ResaulPopularLocationDto cinsinden birr nesne olarak bekledik. values değişkeni bir liste tuttuğu için return kısmında sonuna tolist metodunu ekledik.
Controller Tarafını Oluşturalım
API Katmanı > Controllers > PopularLocationsController
adında bir api controller tanımlıyoruz.
using Microsoft.AspNetCore.Mvc;
namespace RealEstate_Dapper_Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PopularLocationsController : ControllerBase
{
// END POINTS
}
}
Data ile bağlantıyı sağlaması için repositorymizi çağıralım ve yapıcı metodu kullanalım.
private readonly IPopularLocationRepository _locationRepository;
// YAPICI METOD
public PopularLocationsController(IPopularLocationRepository locationRepository)
{
_locationRepository = locationRepository;
}
Ardından listeleme metodu için end pointi tanımlayalım.
[HttpGet]
public async Task<IActionResult> PopularLocationList()
{
var values = await _locationRepository.GetAllPopularLocationAsync();
return Ok(values);
}
Genel olarak controller şu şekilde gözükmeli;
using Microsoft.AspNetCore.Mvc;
using RealEstate_Dapper_Api.Repositories.PopularLocationRepository;
namespace RealEstate_Dapper_Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PopularLocationsController : ControllerBase
{
private readonly IPopularLocationRepository _locationRepository;
public PopularLocationsController(IPopularLocationRepository locationRepository)
{
_locationRepository = locationRepository;
}
[HttpGet]
public async Task<IActionResult> PopularLocationList()
{
var values = await _locationRepository.GetAllPopularLocationAsync();
return Ok(values);
}
}
}
Şimdi progrma.cs üzerinde bu ifade ile IPopularLocationRepository interface’ini PopularLocationRepository sınıfına bağlamış oluyoruz. Yani, bu ifade, IPopularLocationRepository arayüzünün bir örneğini oluşturur ve her talep edildiğinde yeni bir örnek sağlar (transient). Bu, her yeni talep edilen hizmet için yeni bir nesnenin oluşturulacağı anlamına gelir.
UI Tarafındaki İşlemler
Şimdi sırada hazırladığımız API’ye ön-yüzde istek atarak gelen verileri işlemek var. Bunun için “_DefaultProductListExploreCitiesComponentPartial” viewcomponent’i üzerinde çalışacağız.
UI Katmanı > ViewComponents > HomePage > _DefaultProductListExploreCitiesComponentPartial
dosyasını açıyoruz ve içeriğini BottomGrid’deki gibi düzenleyeceğiz. Kodlarımız aşağıdaki şekilde olmalı. Burada http protokolü üzerinden api’ye istek atacağımız için IHttpClientFactory’den bir nesne oluşturduk ve constructor metod ile bunu viewcomponentimizde kullanabilir hale getirdik. client nesnesi tanımladık ve bunun _httpClientFactory nesnesinin alt metodu olan CreateClient’i kullanmasını söyledik. Ardından apimize bir GetAsync metodu ile istek attık ve dönen veriyi responsemessage değişkeni içerisinde tuttuk. Sonrasında bir if sorgusu yazarak responseMessage.IsSuccessStatusCode’un true olup olmadığına baktık. Bu API’nin sağlıklı çalışmasına göre değişkenlik gösteriyor. Eğer doğru istek attıysak ve api doğru çalıştıysa true dönecektir. if sorgusunun içerisinde ise responseMessage’ın content kısmını alıyoruz ve jsonData değişkeninde tutuyoruz. Ardından values değişkeninde JsonConvert kütüphanesinin deserializeObjcet metodu ile jsonData’yı DTO’muza çeviriyoruz ve return ile componentin içerisine bu dataları gönderiyoruz. Unutmadan UI Katmanı içerisinde Dtos klasörü içerisinde PopularLocationDtos aldında “ResaultPopularLocationDto” oluşturup kodlarını da şu şekilde yapmalısınız.
namespace RealEstate_Dapper_UI.Dtos.PopularLocationDtos
{
public class ResaultPopularLocationDto
{
public int LocationID { get; set; }
public string CityName { get; set; }
public string ImageUrl { get; set; }
}
}
Ardından _DefaultProductListExploreCitiesComponentPartial kodlarına bir göz atın. Hata olmaması için faydalı olacaktır.
using System;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using RealEstate_Dapper_UI.Dtos.BottomGridDtos;
using RealEstate_Dapper_UI.Dtos.PopularLocationDtos;
namespace RealEstate_Dapper_UI.ViewComponents.HomePage
{
public class _DefaultProductListExploreCitiesComponentPartial:ViewComponent
{
private readonly IHttpClientFactory _httpClientFactory;
public _DefaultProductListExploreCitiesComponentPartial(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var client = _httpClientFactory.CreateClient();
var responseMessage = await client.GetAsync("http://localhost:5010/api/PopularLocations");
if(responseMessage.IsSuccessStatusCode)
{
var jsonData = await responseMessage.Content.ReadAsStringAsync();
var values = JsonConvert.DeserializeObject<List<ResaultPopularLocationDto>>(jsonData);
return View(values);
}
return View();
}
}
}
Şimdi datalar artık html kodlarımızın olduğu yere kadar iletiliyor. Geriye tek bir işlem kaldı. O da foreach ile ekrana yazdırmak. Çünkü bir liste geliyor ve listeyi foreach yardımı ile dönüyoruz.
@using RealEstate_Dapper_UI.Dtos.PopularLocationDtos
_viewImports içerisine yukarıdaki kodu eklemeyi unutmayın.
@model List<ResaultPopularLocationDto>
<section class="locations-1 popular" id="locations">
<div class="locations py-5">
<div class="container py-lg-5 py-md-4">
<div class="heading text-center mx-auto">
<h6 class="title-small">Explore cities</h6>
<h3 class="title-big">Popular Locations</h3>
</div>
<div class="row pt-5">
@foreach (var item in Model)
{
<div class="col-lg-3 col-md-4 col-6 mb-3">
<a href="#url">
<div class="box16">
<img class="img-fluid" style="height: 150px; width: 270px;" src="@item.ImageUrl" alt="">
<div class="box-content">
<h3 class="title mb-1">@item.CityName</h3>
<span class="post">0 listings</span>
</div>
</div>
</a>
</div>
}
</div>
</div>
</div>
</section>
Evet. Şu anda bu ders için her şey tamamlandı. Bir sonraki derste görüşmek üzere…