ASP.NET Core 6/MVC/Controller'dan View'a Veri Taşıma
Controller'dan view'a çok çeşitli şekillerde veri taşınabilir. En popüler veri taşıma yolu model nesnesi üzerindendir ve daha önceki derslerimizde görmüştük. Bu bölümde model dışında kalan veri taşıma yolları işlenecektir.
ViewBag
değiştirKulanımı aşağıdaki gibidir:
public async Task<IActionResult> Index(long id = 1)
{
ViewBag.AveragePrice = await context.Products.AverageAsync(p => p.Price);
return View(await context.Products.FindAsync(id));
}
ViewBag, Controller sınıfından devralınan dynamic tipinde bir özelliktir. Dolayısıyla bu özelliğe her tipten özellik atanabilir. Bu veriye view'dan da aynı şekilde erişilebilir. Örnek:
<p>Veritabanındaki tüm ürünlerin ortalama fiyatı: @ViewBag.AveragePrice</p>
TempData
değiştirViewBag'de taşınan veri sadece bir request'liktir. Bir verinin birden fazla request-response ikilisi boyunca geçerli olmasını istiyorsak TempData kullanabiliriz. TempData verisi eğer oturum middleware'i etkinleştirilmemişse varsayılan olarak cookie'ler üzerinde depolanır, oturum middleware'i etkinleştirilmişse oturum üzerinde depolanır. Oturum verisinden farklı olarak TempData verileri okunduğu an silinmek üzere işaretlenir, request işleme tamamlandığında da silinir. Dolayısıyla oturum yönetimi yerine kullanılmaması tavsiye edilir. Daha çok yönlendirme yapıldığında ilgili veriye yönlendirilen sayfadan ulaşılabilmesi amacıyla kullanılır. Şimdi projemize CubedController isimli yeni bir controller ekleyelim ve içeriği şöyle olsun:
using Microsoft.AspNetCore.Mvc;
namespace WebApp.Controllers
{
public class CubedController : Controller
{
public IActionResult Index()
{
return View("Cubed");
}
public IActionResult Cube(double num)
{
TempData["value"] = num.ToString();
TempData["result"] = Math.Pow(num, 3).ToString();
return RedirectToAction(nameof(Index));
}
}
}
Bu controller son derece basittir. Cube action'ı model binding yoluyla double tipinde num isimli bir parametre almaktadır. Bu parametreyi ve küpünü TempData üzerinde saklamakta ve istemcinin aynı controller'daki Index action'ına tekrar talepte bulunmasını istemektedir. Index action'ı Cubed isimli bir view'ı render'lamaktadır. Şimdi projemize Cubed.cshtml isimli bir view ekleyelim ve içeriği şöyle olsun:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h6>Cubed</h6>
<form method="get" action="/cubed/cube">
<div>
<label>Value</label>
<input name="num" value="@(TempData["value"])" />
</div>
<button type="submit">Submit</button>
</form>
@if (TempData["result"] != null)
{
<div>
The cube of @TempData["value"] is @TempData["result"]
</div>
}
</body>
</html>
Bu örneğimizde kullanıcı ilk önce Index action'ına talepte bulunduğu zaman bu aşamada TempData sözlüğü boş olacağı için form boş gelmektedir ve formun altında herhangi bir yazı olmayacaktır. Kullanıcı formda ilgili yere sayıyı girip "Submit" butonuna bastığında veri Cube action'ına gidecektir. Cube action'ı ilgili sayıyı ve küpünü TempData sözlüğüne yazıp Index action'ına yönlendirme yapmaktadır. İşte bu noktada TempData kullanılmasaydı veri silinecekti. Ancak TempData'da silinmediği için yönlendirme sonrası Index action'ının renderladığı Cubed view'ı ilgili TempData verilerine ulaşacak ve formda ve formun altındaki yazıda TempData verilerini gösterecektir. Kullanıcı bu aşamada forma yeni bir sayı yazıp tekrar "Submit" butonuna bastığında artık TempData verileri silindiği için süreç en başına dönmektedir.
TempData verileri okunur okunmaz silinmez. Sadece okunduktan sonra silinmek üzere işaretlenir. TempData verisinin kullanıldığı view render'landıktan ve kullanıcıya gönderildikten sonra kullanıcı tarafından yeni request gönderildiğinde artık TempData verileri silinmiş olacaktır. Örneğin kullanıcı yukarıdaki örneğimizde Cubed view'ında sayıyı ve küpünü gösteren metni gördükten sonra sayfayı yenilerse bu bilgiler artık sayfada olmayacaktır.
TempData özelliği üzerinde çalıştırılacak Peek() metodu bir TempData sözlüğünden veriyi silinmek üzere işaretlemeden alır. Keep() metodu ise daha önce normal yolla alınan TempData verisinden sonra ilgili sözlük üzerinde yapılan silinecek işaretini kaldırır. Ancak Keep() metot çağrısından sonra normal yolla tekrar ilgili TempData verisine erişildiyse ilgili TempData verisi tekrar silinmek üzere işaretlenir.
Controller'lar TempData verisine kolayca ulaşmak için özellikleri için TempData attribute'unu kullanabilirler. Örnek:
using Microsoft.AspNetCore.Mvc;
namespace WebApp.Controllers
{
public class CubedController : Controller
{
public IActionResult Index()
{
return View("Cubed");
}
public IActionResult Cube(double num)
{
Value = num.ToString();
Result = Math.Pow(num, 3).ToString();
return RedirectToAction(nameof(Index));
}
[TempData]
public string Value { get; set; }
[TempData]
public string Result { get; set; }
}
}
Bu örneğimizde Cube action'ının TempData'ya yazması için direkt Value ve Result özelliklerine yazması yeterlidir. TempData sözlüğüne view tarafında erişilmede herhangi bir farklılık yoktur.