ASP.NET Core hattı
Model binding: HTTP’den C# nesnesine
Rota, sorgu dizesi ve gövde nasıl metot parametrelerine dönüşür ve aşırı bağlama nasıl önlenir?
Kavramı anlayalım
Model binding, isteğin farklı yerlerindeki değerleri metot parametrelerine dönüştürür. Rota değerleri ve sorgu dizesi basit tiplere, JSON gövde ise karmaşık tiplere bağlanır. [ApiController] ile karmaşık tipler varsayılan olarak gövdeden okunur; [FromRoute], [FromQuery], [FromBody], [FromHeader] kaynağı açıkça belirtir.
Bağlama sırasında tür dönüşümü yapılır. ‘abc’ değeri int bir parametreye bağlanamazsa hata ModelState’e eklenir ve [ApiController] isteği otomatik olarak 400 ile reddeder. JSON gövde System.Text.Json ile okunur; gövde boyutu da sınırlanabilir.
Güvenlik açısından en önemli kural: veritabanı entity’sini doğrudan bağlama hedefi yapmamaktır. Kullanıcı gövdeye beklemediğin alanları (IsAdmin, Price, OwnerId) ekleyebilir ve hepsi entity’ye yazılır; buna aşırı bağlama (over-posting / mass assignment) denir. Bunun yerine yalnız izin verilen alanları içeren bir istek modeli (DTO veya record) kullanılır.
İstekten gelen her değer güvenilmez girdidir; neyin nereden ve hangi biçimde alındığı açık olmalıdır.
EF Core entity’sini [FromBody] ile bağlayıp doğrudan SaveChanges çağırmak.
Bir mektubun şehirdeki yolculuğu
İsteği bir mektup, sunucuyu bir şehir gibi düşün. Senaryo seç, oynat ve mektubun hangi kapıdan geçip nerede durdurulduğunu izle.
İletişim formu gönderiliyor ama e-posta alanına ‘ayse-at-ornek’ yazılmış.
Aynı konu. Üç farklı derinlik.
// GET /api/posts?page=2&category=Backend
[HttpGet]
public IActionResult List([FromQuery] int page = 1, [FromQuery] string? category = null) => …Sorgu dizesi değerleri basit parametrelere bağlanır.
Bu sayfa gerçek bir sunucuya veya veritabanına bağlanmaz. Kod örnekleri .NET 8, Next.js ve SQL Server için temsilîdir; süreler simülasyondaki örnek değerlerdir, ölçüm değildir. Örnekleri yalnız kendi geliştirme ortamında dene; gerçek bağlantı dizesi, token veya parola paylaşma.
Önce kendin dene.
Profil güncelleme uç noktası şu an User entity’sini bağlıyor. Kullanıcı yalnız DisplayName ve Bio’yu değiştirebilmeli. Güvenli hale getir.
Çözümü ve açıklamasını göster
public sealed record UpdateProfile([MaxLength(60)] string DisplayName, [MaxLength(500)] string? Bio);
[HttpPut("me")]
public async Task<IActionResult> Update(UpdateProfile input, CancellationToken ct)
{
var user = await db.Users.SingleAsync(u => u.Id == CurrentUserId, ct);
user.DisplayName = input.DisplayName;
user.Bio = input.Bio;
await db.SaveChangesAsync(ct);
return NoContent();
}Yalnız izin verilen alanlar modelde bulunur ve entity’ye tek tek atanır. Kimlik URL’den değil oturumdan alınır.