C# ve .NET [22]

ASP.NET Core Temelleri: Modern Web Uygulamaları İnşa Etmek (MVC, Razor Pages, API) Giriş: Web Geliştirmenin Evrimi ve ASP.NET Core’un Yükselişi Web teknolojileri, son yirmi yılda baş döndürücü bir hızla gelişti. Statik HTML sayfalarından dinamik, veri odaklı, gerçek zamanlı ve küresel ölçekte hizmet veren karmaşık uygulamalara doğru bir evrim yaşandı. Bu süreçte, geliştiricilerin bu karmaşık uygulamaları verimli, sürdürülebilir ve performanslı bir şekilde oluşturmalarını sağlayan güçlü web çatılarının önemi arttı. Microsoft’un ASP.NET Core’u, bu modern web geliştirme çağının ön saflarında yer alan platformlardan biridir. Geleneksel ASP.NET Framework’ün mirasını taşısa da, ASP.NET Core sıfırdan, günümüzün ihtiyaçları göz önünde bulundurularak tasarlandı: Çapraz Platform: Windows, macOS ve Linux üzerinde geliştirilebilir ve çalıştırılabilir. Bu, geliştiricilere ve işletmelere platform seçimi konusunda benzeri görülmemiş bir esneklik sunar. Açık Kaynak: Kaynak kodunun GitHub’da açık olması, şeffaflık sağlar, topluluk katkısını teşvik eder ve daha hızlı inovasyona olanak tanır. Yüksek Performans: Performans, ASP.NET Core’un tasarım hedeflerinin merkezinde yer alır. Optimize edilmiş çalışma zamanı (CoreCLR), Kestrel web sunucusu ve modern programlama teknikleri sayesinde, en hızlı web çatılarından biri olarak kabul edilir. Modülerlik: NuGet paketleri aracılığıyla yalnızca ihtiyaç duyulan bileşenlerin dahil edildiği modüler bir yapıya sahiptir. Bu, daha hafif uygulamalar ve daha küçük dağıtım boyutları anlamına gelir. Birleşik Platform: .NET 5 ve sonrası ile birlikte, web, masaüstü, mobil, bulut, IoT ve AI gibi farklı uygulama türleri için tek bir .NET platformu sunar. ASP.NET Core, bu birleşik platformun web geliştirme ayağını oluşturur. Modern Mimariler: Bağımlılık Enjeksiyonu (Dependency Injection), Middleware Pipeline, Esnek Yapılandırma ve Günlükleme gibi modern yazılım tasarım prensiplerini temel alır. Bu makalede, ASP.NET Core’un temel mimari taşlarını, istek/yanıt yaşam döngüsünü ve en popüler üç geliştirme modelini — MVC, Razor Pages ve Web API — ayrıntılı olarak inceleyeceğiz. Bu modellerin ne zaman ve neden tercih edilmesi gerektiğini, temel yapılarını ve nasıl kullanılacaklarını anlayarak, ASP.NET Core ile güçlü ve modern web uygulamaları oluşturmak için sağlam bir temel edineceksiniz. Bölüm 1: ASP.NET Core’un Kalbi — Temel Kavramlar ve Mimarisi ASP.NET Core uygulamalarının nasıl çalıştığını anlamak için temelindeki mimari prensipleri kavramak önemlidir. Bu prensipler, hangi geliştirme modelini seçerseniz seçin geçerlidir. 1.1. Middleware Pipeline: İstek/Yanıt Boru Hattı ASP.NET Core’da bir istemciden (tarayıcı, mobil uygulama vb.) gelen her HTTP isteği ve sunucudan giden yanıt, bir middleware (ara yazılım) bileşenleri zincirinden geçer. Bu zincire request pipeline (istek boru hattı) denir. Her middleware bileşeni: Gelen isteği inceleyebilir ve/veya değiştirebilir. Zincirdeki bir sonraki middleware bileşenine isteği iletebilir (veya kısa devre yaparak yanıtı doğrudan oluşturabilir). Zincirdeki sonraki bileşenlerden dönen yanıtı inceleyebilir ve/veya değiştirebilir. Middleware’ler Program.cs (veya eski sürümlerde Startup.cs’teki Configure metodu) içinde app.Use… veya app.Run… gibi metotlarla yapılandırılır. Sıralama önemlidir, çünkü istekler ve yanıtlar bu sıraya göre işlenir. Yaygın Middleware Bileşenleri: UseDeveloperExceptionPage: Geliştirme ortamında detaylı hata sayfaları gösterir. UseExceptionHandler: Üretim ortamında genel hata işleme sayfaları gösterir. UseHsts: Tarayıcıya siteye sadece HTTPS üzerinden bağlanmasını söyler. UseHttpsRedirection: HTTP isteklerini otomatik olarak HTTPS’e yönlendirir. UseStaticFiles: CSS, JavaScript, resim gibi statik dosyaların sunulmasını sağlar. UseRouting: Gelen isteğin URL’sini analiz ederek hangi işleyiciye (endpoint — Controller Action, Razor Page, Minimal API vb.) yönlendirileceğini belirler. UseAuthentication: Kullanıcının kimliğini doğrular. UseAuthorization: Kimliği doğrulanmış kullanıcının belirli kaynaklara erişim yetkisi olup olmadığını kontrol eder. UseEndpoints: UseRouting tarafından seçilen endpoint’i çalıştırır. Örnek (Minimal Hosting Modeli — Program.cs): var builder = WebApplication.CreateBuilder(args); // Servisleri ekle (DI için - aşağıda açıklanacak) builder.Services.AddControllersWithViews(); // MVC için servisler builder.Services.AddRazorPages(); // Razor Pages için servisler var app = builder.Build(); // Middleware pipeline'ı yapılandır if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // Üretim hata sayfası app.UseHsts(); } else { app.UseDeveloperExceptionPage(); // Geliştirme hata sayfası } app.UseHttpsRedirection(); app.UseStaticFiles(); // Statik dosyaları sun (wwwroot klasöründen) app.UseRouting(); // Yönlendirmeyi etkinleştir app.UseAuthentication(); // Kimlik doğrulamayı etkinleştir (varsa) app.UseAuthorization(); // Yetkilendirmeyi etkinleştir // Endpoint'leri tanımla app.

Apr 9, 2025 - 12:01
 0
C# ve .NET [22]

ASP.NET Core Temelleri: Modern Web Uygulamaları İnşa Etmek (MVC, Razor Pages, API)

Giriş: Web Geliştirmenin Evrimi ve ASP.NET Core’un Yükselişi

Web teknolojileri, son yirmi yılda baş döndürücü bir hızla gelişti. Statik HTML sayfalarından dinamik, veri odaklı, gerçek zamanlı ve küresel ölçekte hizmet veren karmaşık uygulamalara doğru bir evrim yaşandı. Bu süreçte, geliştiricilerin bu karmaşık uygulamaları verimli, sürdürülebilir ve performanslı bir şekilde oluşturmalarını sağlayan güçlü web çatılarının önemi arttı. Microsoft’un ASP.NET Core’u, bu modern web geliştirme çağının ön saflarında yer alan platformlardan biridir.

Geleneksel ASP.NET Framework’ün mirasını taşısa da, ASP.NET Core sıfırdan, günümüzün ihtiyaçları göz önünde bulundurularak tasarlandı:

Çapraz Platform: Windows, macOS ve Linux üzerinde geliştirilebilir ve çalıştırılabilir. Bu, geliştiricilere ve işletmelere platform seçimi konusunda benzeri görülmemiş bir esneklik sunar.
Açık Kaynak: Kaynak kodunun GitHub’da açık olması, şeffaflık sağlar, topluluk katkısını teşvik eder ve daha hızlı inovasyona olanak tanır.
Yüksek Performans: Performans, ASP.NET Core’un tasarım hedeflerinin merkezinde yer alır. Optimize edilmiş çalışma zamanı (CoreCLR), Kestrel web sunucusu ve modern programlama teknikleri sayesinde, en hızlı web çatılarından biri olarak kabul edilir.
Modülerlik: NuGet paketleri aracılığıyla yalnızca ihtiyaç duyulan bileşenlerin dahil edildiği modüler bir yapıya sahiptir. Bu, daha hafif uygulamalar ve daha küçük dağıtım boyutları anlamına gelir.
Birleşik Platform: .NET 5 ve sonrası ile birlikte, web, masaüstü, mobil, bulut, IoT ve AI gibi farklı uygulama türleri için tek bir .NET platformu sunar. ASP.NET Core, bu birleşik platformun web geliştirme ayağını oluşturur.
Modern Mimariler: Bağımlılık Enjeksiyonu (Dependency Injection), Middleware Pipeline, Esnek Yapılandırma ve Günlükleme gibi modern yazılım tasarım prensiplerini temel alır.
Bu makalede, ASP.NET Core’un temel mimari taşlarını, istek/yanıt yaşam döngüsünü ve en popüler üç geliştirme modelini — MVC, Razor Pages ve Web API — ayrıntılı olarak inceleyeceğiz. Bu modellerin ne zaman ve neden tercih edilmesi gerektiğini, temel yapılarını ve nasıl kullanılacaklarını anlayarak, ASP.NET Core ile güçlü ve modern web uygulamaları oluşturmak için sağlam bir temel edineceksiniz.

Bölüm 1: ASP.NET Core’un Kalbi — Temel Kavramlar ve Mimarisi

ASP.NET Core uygulamalarının nasıl çalıştığını anlamak için temelindeki mimari prensipleri kavramak önemlidir. Bu prensipler, hangi geliştirme modelini seçerseniz seçin geçerlidir.

1.1. Middleware Pipeline: İstek/Yanıt Boru Hattı

ASP.NET Core’da bir istemciden (tarayıcı, mobil uygulama vb.) gelen her HTTP isteği ve sunucudan giden yanıt, bir middleware (ara yazılım) bileşenleri zincirinden geçer. Bu zincire request pipeline (istek boru hattı) denir. Her middleware bileşeni:

Gelen isteği inceleyebilir ve/veya değiştirebilir.
Zincirdeki bir sonraki middleware bileşenine isteği iletebilir (veya kısa devre yaparak yanıtı doğrudan oluşturabilir).
Zincirdeki sonraki bileşenlerden dönen yanıtı inceleyebilir ve/veya değiştirebilir.
Middleware’ler Program.cs (veya eski sürümlerde Startup.cs’teki Configure metodu) içinde app.Use… veya app.Run… gibi metotlarla yapılandırılır. Sıralama önemlidir, çünkü istekler ve yanıtlar bu sıraya göre işlenir.

Yaygın Middleware Bileşenleri:

UseDeveloperExceptionPage: Geliştirme ortamında detaylı hata sayfaları gösterir.
UseExceptionHandler: Üretim ortamında genel hata işleme sayfaları gösterir.
UseHsts: Tarayıcıya siteye sadece HTTPS üzerinden bağlanmasını söyler.
UseHttpsRedirection: HTTP isteklerini otomatik olarak HTTPS’e yönlendirir.
UseStaticFiles: CSS, JavaScript, resim gibi statik dosyaların sunulmasını sağlar.
UseRouting: Gelen isteğin URL’sini analiz ederek hangi işleyiciye (endpoint — Controller Action, Razor Page, Minimal API vb.) yönlendirileceğini belirler.
UseAuthentication: Kullanıcının kimliğini doğrular.
UseAuthorization: Kimliği doğrulanmış kullanıcının belirli kaynaklara erişim yetkisi olup olmadığını kontrol eder.
UseEndpoints: UseRouting tarafından seçilen endpoint’i çalıştırır.
Örnek (Minimal Hosting Modeli — Program.cs):

var builder = WebApplication.CreateBuilder(args);
// Servisleri ekle (DI için - aşağıda açıklanacak)
builder.Services.AddControllersWithViews(); // MVC için servisler
builder.Services.AddRazorPages(); // Razor Pages için servisler
var app = builder.Build();
// Middleware pipeline'ı yapılandır
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error"); // Üretim hata sayfası
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage(); // Geliştirme hata sayfası
}
app.UseHttpsRedirection();
app.UseStaticFiles(); // Statik dosyaları sun (wwwroot klasöründen)
app.UseRouting(); // Yönlendirmeyi etkinleştir
app.UseAuthentication(); // Kimlik doğrulamayı etkinleştir (varsa)
app.UseAuthorization(); // Yetkilendirmeyi etkinleştir
// Endpoint'leri tanımla
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}"); // MVC için varsayılan rota
app.MapRazorPages(); // Razor Pages için rotaları etkinleştir
// app.MapGet("/", () => "Hello Minimal API!"); // Minimal API örneği
app.Run(); // Uygulamayı başlat ve istekleri dinle
1.2. Bağımlılık Enjeksiyonu (Dependency Injection — DI)

ASP.NET Core, Bağımlılık Enjeksiyonu (DI) desenini temel bir prensip olarak benimser. DI, sınıfların ihtiyaç duyduğu bağımlılıkların (diğer sınıflar veya servisler) dışarıdan (genellikle bir DI konteyneri tarafından) sağlanmasıdır. Bu, gevşek bağlı (loosely coupled) ve test edilebilir kod yazmayı kolaylaştırır.

Temel Adımlar:

Servis Tanımlama: Bağımlılığın temsil ettiği işlevselliği tanımlayan bir arayüz (interface) veya sınıf oluşturulur.
Servis Kaydetme (Registration): Program.cs (veya Startup.ConfigureServices) içinde, DI konteynerine hangi somut sınıfın hangi arayüzü karşılayacağı ve yaşam döngüsünün (lifetime) ne olacağı bildirilir.
Transient: Her istendiğinde yeni bir örnek oluşturulur.
Scoped: Her HTTP isteği başına tek bir örnek oluşturulur (aynı istek içindeki farklı yerlerde aynı örnek kullanılır).
Singleton: Uygulama ömrü boyunca tek bir örnek oluşturulur ve her zaman aynı örnek kullanılır (dikkatli kullanılmalıdır).

  1. Servis Enjekte Etme (Injection): Bir sınıfın yapıcısı (constructor injection en yaygın yöntemdir) veya bazen özellikleri aracılığıyla, DI konteyneri kayıtlı servisin bir örneğini otomatik olarak sağlar.

// 1. Servis Tanımlama (Arayüz)
public interface IMessageService
{
string GetGreeting(string name);
}
// Somut implementasyon
public class GreetingService : IMessageService
{
public string GetGreeting(string name) => $"Merhaba, {name}!";
}
// --- Program.cs ---
var builder = WebApplication.CreateBuilder(args);
// 2. Servis Kaydetme (Scoped yaşam döngüsüyle)
builder.Services.AddScoped();
builder.Services.AddControllersWithViews();
// ... diğer servisler ...
var app = builder.Build();
// ... middleware ...
app.Run();
// --- Controller veya PageModel içinde Kullanım ---
public class HomeController : Controller
{
private readonly IMessageService _messageService;
// 3. Servis Enjekte Etme (Constructor Injection)
public HomeController(IMessageService messageService)
{
_messageService = messageService;
}
public IActionResult Index()
{
string greeting = _messageService.GetGreeting("ASP.NET Core");
ViewBag.GreetingMessage = greeting;
return View();
}
}
ASP.NET Core’un birçok yerleşik servisi (logging, configuration, Entity Framework Core DbContext vb.) zaten DI konteynerine kayıtlıdır ve doğrudan enjekte edilebilir.

1.3. Yapılandırma (Configuration)

Uygulamaların veritabanı bağlantı dizeleri, API anahtarları, loglama seviyeleri gibi çalışma zamanında değişebilen değerlere ihtiyacı vardır. ASP.NET Core, esnek bir yapılandırma sistemi sunar. Yapılandırma verileri çeşitli kaynaklardan okunabilir ve birleştirilebilir:

appsettings.json dosyaları (ve ortama özel appsettings.Development.json, appsettings.Production.json gibi dosyalar)
Ortam değişkenleri (Environment Variables)
Komut satırı argümanları
Kullanıcı gizli dosyaları (User Secrets — geliştirme sırasında hassas veriler için)
Azure Key Vault gibi harici kaynaklar
Yapılandırma değerlerine genellikle IConfiguration arayüzü aracılığıyla erişilir. Bu arayüz de DI kullanılarak enjekte edilebilir. Ayrıca, Options Pattern kullanılarak yapılandırma bölümleri güçlü tipli (strongly-typed) C# sınıflarına bağlanabilir.

// --- appsettings.json ---
{
"Logging": { /* ... / },
"AllowedHosts": "
",
"MySettings": {
"ApiKey": "YOUR_API_KEY",
"RetryAttempts": 3
}
}
// --- C# Sınıfı (Options Pattern için) ---
public class MySettingsOptions
{
public string ApiKey { get; set; }
public int RetryAttempts { get; set; }
}
// --- Program.cs ---
var builder = WebApplication.CreateBuilder(args);
// Options Pattern'i yapılandır
builder.Services.Configure(
builder.Configuration.GetSection("MySettings"));
// ... diğer servisler ...
// --- Servis veya Controller içinde Kullanım ---
public class ExternalServiceCaller
{
private readonly MySettingsOptions _settings;
private readonly ILogger _logger;
// IOptions veya IOptionsSnapshot enjekte edilir
public ExternalServiceCaller(IOptions settingsOptions, ILogger logger)
{
_settings = settingsOptions.Value; // Ayarlara erişim
_logger = logger;
}
public void CallApi()
{
_logger.LogInformation($"API çağrılıyor. Key: {_settings.ApiKey}, Retries: {_settings.RetryAttempts}");
// ... API çağrı kodu ...
}
}
1.4. Yönlendirme (Routing)

Routing, gelen HTTP isteklerinin URL’lerini analiz ederek hangi kodun (endpoint) çalıştırılacağına karar veren mekanizmadır. ASP.NET Core’da iki ana yönlendirme türü vardır:

Convention-Based Routing (Geleneksel Yönlendirme): Özellikle MVC’de kullanılır. Program.cs (veya Startup.Configure) içinde genel URL desenleri tanımlanır. Örneğin, {controller=Home}/{action=Index}/{id?} deseni, /Products/Details/5 gibi bir URL’yi ProductsController’daki Details action’ına, id parametresi 5 olarak yönlendirir.
Attribute-Based Routing (Öznitelik Tabanlı Yönlendirme): Özellikle Web API’lerinde ve MVC’de de sıkça kullanılır. Rotalar, doğrudan controller sınıflarının veya action metotlarının üzerine [Route(…)], [HttpGet(…)], [HttpPost(…)] gibi özniteliklerle tanımlanır. Daha esnek ve API’ler için daha açıklayıcıdır. Razor Pages ise genellikle dosya sistemindeki konumuna göre geleneksel bir yönlendirme kullanır.
Bu temel kavramlar, ASP.NET Core’un nasıl çalıştığının temelini oluşturur ve şimdi spesifik geliştirme modellerine geçebiliriz.

Bölüm 2: Model-View-Controller (MVC) Mimarisi

MVC, web uygulamaları geliştirmek için köklü ve yaygın olarak kullanılan bir tasarım desenidir. Amacı, uygulamanın farklı sorumluluklarını (veri yönetimi, kullanıcı arayüzü, kullanıcı girdisi işleme) birbirinden ayırarak daha düzenli, test edilebilir ve bakımı kolay kod oluşturmaktır.

2.1. MVC’nin Üç Bileşeni

Model: Uygulamanın verilerini ve iş mantığını temsil eder. Veritabanından veri alma, veriyi doğrulama, iş kurallarını uygulama gibi görevlerden sorumludur. Genellikle POCO (Plain Old CLR Object) sınıfları, veritabanı varlıkları (Entity Framework Core) veya ViewModel’ler (View’e özel veri taşıyan sınıflar) şeklinde olur. Model, View veya Controller hakkında doğrudan bilgi sahibi olmamalıdır.
View (Görünüm): Kullanıcı arayüzünü (UI) temsil eder. Kullanıcıya gösterilecek veriyi (genellikle Model’den alır) HTML olarak oluşturmaktan sorumludur. ASP.NET Core MVC’de View’ler genellikle Razor söz dizimi kullanılarak .cshtml dosyalarında oluşturulur. View, kullanıcı girdisini doğrudan işlemez, bu görevi Controller’a bırakır.
Controller (Denetleyici): Kullanıcıdan gelen istekleri (HTTP GET, POST vb.) ilk karşılayan bileşendir.
İsteği analiz eder (URL, form verileri, sorgu parametreleri).
Gerekirse Model ile etkileşime girerek veriyi okur veya günceller.
İşlemin sonucuna göre hangi View’in kullanıcıya gösterileceğine karar verir ve gerekli veriyi (Model veya ViewModel) View’e iletir.
ASP.NET Core MVC’de Controller’lar, Microsoft.AspNetCore.Mvc.Controller sınıfından türeyen ve içinde Action metotları barındıran sınıflardır. Her Action metodu genellikle belirli bir URL ve HTTP metoduyla eşleşir.
2.2. ASP.NET Core MVC Akışı (Örnek)

Kullanıcı tarayıcıdan /Products/Details/5 URL’sini ister.
ASP.NET Core Routing mekanizması, bu URL’yi (varsayılan rota deseniyle) ProductsController’daki Details Action metoduna, id parametresi 5 olarak yönlendirir.
Details Action metodu çalışır.
Action, id=5 değerini kullanarak Model katmanıyla (örneğin, bir veritabanı servisi) etkileşime girer ve ilgili ürün bilgisini alır.
Action, alınan ürün bilgisini (Model veya ViewModel) içeren bir ViewResult döndürmeye karar verir. return View(productModel); gibi bir kodla.
ASP.NET Core, Views/Products/Details.cshtml adlı Razor View dosyasını bulur.
Razor View Engine, View dosyasını ve ona iletilen modeli kullanarak HTML çıktısını oluşturur.
Oluşturulan HTML, HTTP yanıtı olarak tarayıcıya geri gönderilir.
2.3. Razor Söz Dizimi ve View Özellikleri

Razor, C# kodunu HTML içine gömerek dinamik web sayfaları oluşturmayı sağlayan bir şablon motorudur. @ sembolü ile C# kodu başlatılır.

@model ProductViewModel
@{
ViewData["Title"] = "Ürün Detayı";
Layout = "_Layout"; // Ana şablonu belirtir
}

@Model.ProductName

Fiyat: @Model.Price.ToString("C")

@if (Model.IsInStock)
{

Stokta Var!
}
else
{

Stokta Yok.
}

Geri Dön

@await Component.InvokeAsync("RelatedProducts", new { productId = Model.Id })
@model: View’in kullanacağı Model türünü belirtir.
ViewData/ViewBag: Controller’dan View’e küçük veri parçaları aktarmak için kullanılır (güçlü tipli olmadıkları için ViewModel tercih edilir).
Layouts: Ortak sayfa yapısını (header, footer, menü) tanımlayan ana şablonlardır (_Layout.cshtml).
Partial Views: Tekrar kullanılabilir küçük UI parçalarıdır (_ProductCard.cshtml).
Tag Helpers: Sunucu tarafı kodun HTML elemanları oluşturmasını veya değiştirmesini sağlayan özniteliklerdir (, gibi). HTML’i daha temiz tutarlar.
View Components: Partial View’lere benzer ancak kendi arka plan mantığına sahip, daha karmaşık, tekrar kullanılabilir UI bileşenleridir.
2.4. Ne Zaman MVC Kullanmalı?

Karmaşık kullanıcı arayüzleri ve iş akışları olan uygulamalar.
Sorumlulukların net bir şekilde ayrılmasının önemli olduğu büyük projeler veya ekipler.
Test edilebilirliğin yüksek öncelikli olduğu durumlar (Controller’lar ve Model’ler kolayca test edilebilir).
Geleneksel web uygulaması geliştirme deneyimine sahip ekipler.
Bölüm 3: Razor Pages — Sayfa Odaklı Yaklaşım

ASP.NET Core 2.0 ile tanıtılan Razor Pages, MVC’ye daha basit, sayfa merkezli bir alternatif sunar. Özellikle form tabanlı ve veri odaklı basit uygulamalar için geliştirme sürecini hızlandırabilir.

3.1. Razor Pages’in Felsefesi

MVC’deki Controller + View ayırımı yerine, Razor Pages’te her sayfa kendi mantığıyla birlikte gelir. Her .cshtml dosyası (View kısmı) genellikle ilişkili bir .cshtml.cs kod-arkası (code-behind) dosyasına sahiptir. Bu kod-arkası dosyası, PageModel sınıfını içerir ve sayfanın davranışını, verilerini ve olay işleyicilerini yönetir.

3.2. Razor Pages Yapısı

Pages Klasörü: Razor Pages dosyaları genellikle projenin kökündeki Pages klasöründe bulunur. Dosya sistemindeki konumları, URL’lerini belirler (örneğin, Pages/Users/Index.cshtml -> /Users/Index veya /Users).
.cshtml Dosyası: Sayfanın HTML yapısını ve Razor söz dizimini içerir. MVC View’lerine çok benzer. @page direktifi ile başlar.
.cshtml.cs Dosyası (PageModel):
Microsoft.AspNetCore.Mvc.RazorPages.PageModel sınıfından türer.
Sayfanın verilerini tutan public özellikler (properties) içerir (genellikle [BindProperty] özniteliği ile işaretlenir).
HTTP isteklerine yanıt veren handler methods (işleyici metotlar) içerir. İsimlendirme kuralı önemlidir:
OnGet() veya OnGetAsync(): HTTP GET isteklerini işler.
OnPost() veya OnPostAsync(): HTTP POST isteklerini işler.
OnPostDeleteAsync(), OnGetDetailsAsync(int id) gibi isimlendirmelerle belirli eylemler veya parametreler için özelleşmiş işleyiciler tanımlanabilir.
Örnek: Basit bir Kullanıcı Listesi Sayfası

// --- Pages/Users/Index.cshtml.cs ---
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Collections.Generic;
using System.Threading.Tasks;
// varsayılan User ve IUserService tanımları
public class IndexModel : PageModel
{
private readonly IUserService _userService; // DI ile enjekte edilir
public IndexModel(IUserService userService)
{
_userService = userService;
}
// Sayfada gösterilecek kullanıcı listesi
public List Users { get; private set; }
// GET isteği işleyicisi
public async Task OnGetAsync()
{
Users = await _userService.GetAllUsersAsync();
}
// POST isteği işleyicisi (örneğin, yeni kullanıcı ekleme formu gönderildiğinde)
// [BindProperty] özniteliği ile form verileri UserInput modeline bağlanır
[BindProperty]
public UserInputModel UserInput { get; set; }
public async Task OnPostAsync()
{
if (!ModelState.IsValid) // Doğrulama kontrolü
{
// Doğrulama başarısız olursa sayfayı tekrar göster
// Mevcut kullanıcı listesini tekrar yüklemek gerekebilir
Users = await _userService.GetAllUsersAsync();
return Page();
}
// Kullanıcıyı ekle
await _userService.AddUserAsync(UserInput);
// Başarılı ekleme sonrası kullanıcıyı tekrar liste sayfasına yönlendir
return RedirectToPage(); // Mevcut sayfaya GET isteği yapar
}
}
public class UserInputModel { /* ... Kullanıcı ekleme formu için özellikler ... */ }

@page
@model IndexModel
@{
ViewData["Title"] = "Kullanıcılar";
}

Kullanıcı Listesi

Kullanıcı Ekle
@foreach (var user in Model.Users) { }
ID İsim Email
@user.Id @user.Name @user.Email

3.3. Ne Zaman Razor Pages Kullanmalı?

Daha çok sayfa odaklı, form tabanlı uygulamalar (CRUD işlemleri gibi).
MVC’nin getirdiği soyutlama katmanlarına ihtiyaç duyulmayan veya daha basit yapının yeterli olduğu durumlar.
Geliştirme hızının önemli olduğu projeler.
Daha küçük ekipler veya tek geliştiriciler için genellikle daha kolay bir başlangıç noktası olabilir.
MVC ile Karşılaştırma: Razor Pages, belirli bir sayfanın mantığını ve görünümünü tek bir yerde (iki ilişkili dosyada) toplar. MVC ise Controller’da birden fazla Action ve ilişkili View’ler ile daha geniş bir sorumluluğu yönetir. Razor Pages, MVC’nin üzerine inşa edilmiştir ve aynı temel özellikleri (Routing, Model Binding, Validation, Filter’lar vb.) kullanır.

Bölüm 4: Web API’leri Oluşturma

Modern web uygulamaları genellikle sadece HTML döndürmez; aynı zamanda verileri (genellikle JSON veya XML formatında) diğer istemcilere (JavaScript tabanlı SPA’lar — Single Page Applications, mobil uygulamalar, diğer sunucu uygulamaları) sunan HTTP servislerine, yani Web API’lerine ihtiyaç duyar. ASP.NET Core, Web API’leri oluşturmak için mükemmel destek sunar.

4.1. Web API Nedir ve Amacı Nedir?

Web API’leri, HTTP protokolü üzerinden erişilebilen ve genellikle belirli veri kaynakları veya işlevler üzerinde CRUD (Create, Read, Update, Delete) işlemleri gerçekleştiren servislerdir. İstemciler, standart HTTP metotlarını (GET, POST, PUT, DELETE, PATCH vb.) kullanarak API endpoint’lerine istek gönderir ve genellikle JSON formatında veri alıp gönderirler.

4.2. ASP.NET Core’da API Controller’ları

Web API’leri oluşturmanın en yaygın yolu API Controller’ları kullanmaktır:

ControllerBase Sınıfından Türeme: API Controller’ları genellikle Controller yerine ControllerBase sınıfından türer. ControllerBase, View desteği gibi UI’a özgü işlevleri içermez, sadece API’ler için gerekli temel özellikleri barındırır.
[ApiController] Özniteliği: Controller sınıfına bu özniteliğin eklenmesi, bazı API’ye özgü davranışları otomatik olarak etkinleştirir:
Attribute Routing Zorunluluğu: Bu controller için rota tanımlaması özniteliklerle yapılmalıdır.
Otomatik Model Doğrulama: Eğer action metoduna gelen model geçerli değilse (ModelState.IsValid false ise), otomatik olarak 400 Bad Request yanıtı döndürülür. Ekstra kontrol koduna gerek kalmaz.
Otomatik Parametre Kaynağı Çıkarımı: [FromBody], [FromRoute], [FromQuery] gibi öznitelikler olmadan parametrelerin nereden bağlanacağını tahmin etmeye çalışır (örneğin, karmaşık türler için [FromBody]).
Action Metotları ve Sonuçları: Action metotları genellikle veri veya durum kodları döndürür. Yaygın dönüş türleri:
Spesifik Tipler (ActionResult): Başarılı durumda döndürülecek veri türünü belirtir (örneğin, ActionResult). Bu, Swagger/OpenAPI gibi araçların API’yi belgelemesini kolaylaştırır. Başarılı durumda veriyi, hata durumunda ise NotFound(), BadRequest() gibi IActionResult döndürür.
IActionResult: Daha genel bir dönüş türüdür. Ok(data), NotFound(), BadRequest(ModelState), CreatedAtAction(…), NoContent() gibi çeşitli durum kodları ve isteğe bağlı içerik döndürmek için kullanılır.
Örnek API Controller:

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
// varsayılan Product ve IProductService tanımları
[Route("api/[controller]")] // Temel rota: /api/Products
[ApiController] // API davranışlarını etkinleştir
public class ProductsController : ControllerBase
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
// GET: api/Products
[HttpGet]
public async Task>> GetProducts()
{
var products = await _productService.GetAllAsync();
return Ok(products); // 200 OK ve ürün listesi (JSON)
}
// GET: api/Products/5
[HttpGet("{id}")] // Rota parametresi
public async Task> GetProduct(int id)
{
var product = await _productService.GetByIdAsync(id);
if (product == null)
{
return NotFound(); // 404 Not Found
}
return Ok(product); // 200 OK ve ürün detayı (JSON)
}
// POST: api/Products
[HttpPost]
public async Task> PostProduct([FromBody] ProductInputModel productInput)
{
// [ApiController] sayesinde ModelState.IsValid kontrolü otomatik yapılır.
// Eğer geçersizse buraya gelmeden 400 döner.
var createdProduct = await _productService.AddAsync(productInput);
// 201 Created yanıtı ve oluşturulan kaynağın konumunu (Location header) döndür
return CreatedAtAction(nameof(GetProduct), new { id = createdProduct.Id }, createdProduct);
}
// PUT: api/Products/5
[HttpPut("{id}")]
public async Task PutProduct(int id, [FromBody] ProductUpdateModel productUpdate)
{
if (id != productUpdate.Id) // ID eşleşmesi kontrolü
{
return BadRequest("ID uyuşmazlığı."); // 400 Bad Request
}
var success = await _productService.UpdateAsync(productUpdate);
if (!success)
{
return NotFound(); // Güncellenecek ürün bulunamadı
}
return NoContent(); // 204 No Content (başarılı güncelleme, içerik döndürmeye gerek yok)
}
// DELETE: api/Products/5
[HttpDelete("{id}")]
public async Task DeleteProduct(int id)
{
var success = await _productService.DeleteAsync(id);
if (!success)
{
return NotFound(); // Silinecek ürün bulunamadı
}
return NoContent(); // 204 No Content (başarılı silme)
}
}
public class ProductInputModel { /* ... Yeni ürün için özellikler ... / }
public class ProductUpdateModel { public int Id { get; set; } /
... Güncellenecek özellikler ... */ }
4.3. Minimal APIs (.NET 6+)

Basit API endpoint’leri oluşturmak için Program.cs içinde lambda ifadeleri kullanarak çok daha az kodla API tanımlamanın bir yoludur. Controller sınıflarına gerek kalmaz. Küçük mikroservisler veya basit endpoint’ler için idealdir.

// --- Program.cs ---
var builder = WebApplication.CreateBuilder(args);
// DI kayıtları (varsa)
builder.Services.AddScoped();
var app = builder.Build();
// Minimal API endpoint tanımlamaları
app.MapGet("/api/minimal/products", async (IProductService service) => {
var products = await service.GetAllAsync();
return Results.Ok(products); // Results sınıfı standart yanıtlar üretir
});
app.MapGet("/api/minimal/products/{id}", async (int id, IProductService service) => {
var product = await service.GetByIdAsync(id);
return product is not null ? Results.Ok(product) : Results.NotFound();
});
app.MapPost("/api/minimal/products", async (ProductInputModel input, IProductService service) => {
var created = await service.AddAsync(input);
// Link generation helper'ları veya doğrudan URL string'i kullanılabilir
return Results.Created($"/api/minimal/products/{created.Id}", created);
});
// ... diğer endpoint'ler (PUT, DELETE) ...
app.Run();
Minimal API’ler de DI, Routing, Authentication/Authorization gibi ASP.NET Core’un temel özelliklerini kullanabilir.

4.4. Ne Zaman Web API Kullanmalı?

Veri odaklı servisler oluşturmak için (JSON/XML).
Tek Sayfa Uygulamaları (SPA — React, Angular, Vue) için arka uç (backend) sağlamak.
Mobil uygulamalar için backend sağlamak.
Mikroservis mimarileri oluşturmak.
Farklı sistemler arasında veri alışverişi yapmak.
Bölüm 5: Ortak Öğeler ve Teknikler

MVC, Razor Pages ve Web API modelleri farklı yaklaşımlar sunsa da, ASP.NET Core’un birçok temel özelliğini paylaşırlar.

Tag Helpers: Razor görünümlerinde (MVC ve Razor Pages) sunucu tarafı kod ile HTML elemanları oluşturmayı kolaylaştırır.
View Components: MVC ve Razor Pages’te yeniden kullanılabilir, kendi mantığına sahip UI bileşenleri oluşturmak için kullanılır.
Model Binding: Gelen HTTP isteğindeki verileri (rota parametreleri, sorgu dizgisi, form verileri, istek gövdesi) Action veya Handler metotlarındaki parametrelere veya PageModel özelliklerine otomatik olarak eşler. [FromRoute], [FromQuery], [FromBody], [FromHeader], [FromForm] gibi özniteliklerle kaynak belirtilebilir.
Model Doğrulama (Validation): Model sınıfları üzerine eklenen Data Annotation öznitelikleri ([Required], [StringLength], [Range], [EmailAddress] vb.) kullanılarak veri bütünlüğü kuralları tanımlanır. ModelState.IsValid özelliği ile doğrulama sonucu kontrol edilir. [ApiController] özniteliği API’lerde bu kontrolü otomatik yapar. Client-side (istemci tarafı) doğrulama için de destek sunar.
Ortamlar (Environments): ASPNETCORE_ENVIRONMENT ortam değişkeni (genellikle Development, Staging, Production) kullanılarak uygulamanın farklı ortamlarda farklı davranışlar (örneğin, farklı veritabanı bağlantıları, detaylı hata sayfaları) sergilemesi sağlanır.
Statik Dosyalar: wwwroot klasörü, CSS, JavaScript, resim gibi istemciye doğrudan sunulacak statik dosyaların varsayılan konumudur. UseStaticFiles() middleware’i bu dosyaların sunulmasını sağlar.
Bölüm 6: Geliştirme, Test ve Dağıtım

Proje Yapısı: dotnet new komutu veya Visual Studio şablonları kullanılarak oluşturulan projeler genellikle standart bir klasör yapısına sahiptir (örn. Controllers, Views, Models, Pages, wwwroot, Program.cs, appsettings.json).
Araçlar: dotnet CLI ve Visual Studio/VS Code, geliştirme sürecinin temel araçlarıdır (derleme, çalıştırma, hata ayıklama, paket yönetimi).
Test Etme: ASP.NET Core, birim testleri (unit tests — sınıfları izole olarak test etme) ve entegrasyon testleri (integration tests — uygulamanın birden fazla bileşenini veya tüm istek/yanıt döngüsünü test etme) için destek sunar. Microsoft.AspNetCore.Mvc.Testing paketi entegrasyon testlerini kolaylaştırır.
Dağıtım (Deployment): ASP.NET Core uygulamaları çeşitli şekillerde dağıtılabilir:
Çerçeve Bağımlı (FDD): Daha küçük boyut, hedefte runtime gerektirir.
Kendi Kendine Yeterli (SCD): Daha büyük boyut, runtime içerir, hedefte kurulum gerektirmez.
Hosting: IIS (Windows), Nginx/Apache (Linux — reverse proxy olarak) veya doğrudan Kestrel ile çalıştırılabilir. Bulut platformları (Azure App Service, AWS Elastic Beanstalk vb.) ve Konteynerler (Docker) popüler hosting seçenekleridir. dotnet publish komutu dağıtıma hazır çıktıları oluşturur.
Sonuç: ASP.NET Core ile Modern Web’in İnşası

ASP.NET Core, modern web geliştirmenin zorluklarına yanıt veren güçlü, esnek ve performanslı bir çatıdır. Temelindeki sağlam mimari prensipleri (Middleware, DI, Configuration, Routing) üzerine inşa edilen MVC, Razor Pages ve Web API geliştirme modelleri, farklı ihtiyaçlara ve projelere uygun çözümler sunar.

MVC: Karmaşık, test edilebilir ve iyi yapılandırılmış UI uygulamaları için idealdir.
Razor Pages: Sayfa odaklı, form tabanlı uygulamalar için daha basit ve hızlı bir geliştirme deneyimi sunar.
Web API: Veri odaklı servisler, SPA ve mobil uygulama backend’leri ile mikroservisler oluşturmak için vazgeçilmezdir.
Bu üç model, aynı temel ASP.NET Core özelliklerini paylaştığı için, bir projede hibrit yaklaşımlar kullanmak veya modeller arasında geçiş yapmak da mümkündür. Çapraz platform desteği, açık kaynak yapısı, yüksek performansı ve zengin ekosistemi ile ASP.NET Core, günümüzün ve geleceğin web uygulamalarını inşa etmek için geliştiricilere birinci sınıf bir deneyim sunmaktadır. Bu temelleri anlayarak, ASP.NET Core’un sunduğu geniş olanaklardan faydalanmaya hazırsınız.

Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Özgeçmiş
Github
Github
Linkedin