Sayfalar

31 Ocak 2013 Perşembe

ASP.NET MVC DERSLERİ ( 3.3 ) VIEWS: VIEWBAG, VIEWDATA, TEMPDATA

Controller sınıfları ve View sayfaları arasında veri taşımamıza yardımcı olacak nesneler vardır. Bunlardan en önemlisi ViewData, ViewBag ve TempData nesneleridir. Öncelikle kısaca tanımlama yapalım, ardından aralarındaki farkları ve ne zaman kullanılacağı konusunda tartışalım.

ViewData: Teknik olarak veri Controller sınıfından View sayfalarına ViewDataDictionary (ViewData) sınıfı ile taşınmaktadır. ViewData nesnesine veri aktarabilir ve bu veriyi okuyabiliriz.

    ViewData["CurrentTime"] = DateTime.Now;

ViewBag: ViewBag ise ASP.NET MVC 3 te C# 4 ile gelen dynamic anahtar kelimesinin getirdiği bir yeniliktir. ViewData nın dinamik (run time binding) halidir. Söz dizimi de daha iyidir.

    ViewBag.CurrentTime = DateTime.Now;

TempData: Bu nesne de diğer ikisinin yaptığı işi yapar.

    TempData["CurrentTime"] = DateTime.Now;

Bu üç nesne arasında küçük ve kritik farklar vardır. Örneğin ViewBag nesnesi dynamic tipinde bir nesne olduğundan bununla alakalı hatalar compile time da değil run time da yakalanır. Teknik anlamda ViewData nesnesinden farkı yoktur. Söz dizim olarak farklıdır.

En büyük ve önemli fark TempData ile diğer ikisi arasındadır. ViewData ve ViewBag nesnesi o anki HTTP istek içerisinde geçerlidir. Yaşam döngüsü bir sonraki isteğe kadardır. Ama TempData bir alt HTTP istek içinde geçerlidir. Yaşam döngüsü o anki ve bir sonraki HTTP istek içerinde geçerlidir. Daha iyi anlamak için farklı bir kaç örnek üzerinde görelim;

ÖRNEK 1

Üç nesnenin örnek kullanımı ve çıktısı.

Controller
public ActionResult Index()
{
    ViewBag.Message1 = "ViewBag mesaj!";
    ViewData["Message2"] = "ViewData mesaj!";
    TempData["Message3"] = "TempData mesaj!";

    return View();
}

View
<h2>@ViewBag.Message1</h2>
<h2>@ViewData["Message2"]</h2>
<h2>@TempData["Message3"]</h2>

Çıktı

    ViewBag mesaj!ViewData mesaj!TempData mesaj!

ÖRNEK 2

TempData nesnesinin farklı özelliği.

Controller/Index
public ActionResult Index()
{
    ViewBag.Message1 = "ViewBag mesaj!";
    ViewData["Message2"] = "ViewData mesaj!";
    TempData["Message3"] = "TempData mesaj!";

    return RedirectToAction("About");
}

Contoller/About
public ActionResult About()
{
    var message = TempData["Message3"];

    return View();
}

Index metodu içerisinde oluşturduğumuz TempData About metoduna aktarılır ama diger iki nesne debug ta baktığımızda null olacaktır. TempData ile geçirdiğimiz veriyi About.cshtml içerisinde bir önceki örnekteki gibi kullanabiliriz.

TempData için sakıncalı bir durum yönlendirdiğimiz About sayfası içerisindeyken sayfası yenilediğimiz zaman veriyi kaybederiz. Bundan dolayı TempData yerine bu işlemleri daha sonra göreceğimiz ViewModel mantığıyla halletmeliyiz. İpucu olması açısından aynı işi yapan ViewModel mantığını da kodla örnekleyelim.

Controller/Index
public ActionResult Index()
{
    // veriyi veri tabanına kaydettikten sonra id sini alıyoruz
    var id = Repository.SaveData("foo");
    // diger sayfaya parametre olarak, veri tabanına son kaydettiğimiz kayıtın id sini veriyoruz.
    return RedirectToAction("About", "Home", new { id = id });
}

Contoller/About
// Index metodundan gelen id değerini alıyoruz.
public ActionResult About(string id)
{
    // gelen id değerinden tekrar kayıtı veri tabanından çekiyoruz.
    var model = new MyViewModel
    {
        Foo = Repository.GetData(id)
    };
    return View(model);
}

Neden veritabanına kayıt yapıp tekrar diğer sayfadan bu kayıta ulaşmaya çalışan bir örneği, önceki TempData örneğinin alternatifi olarak verdik. Çünkü gerçek hayatta aslında bir metottan diger metoda veriyi böyle bir senaryo için aktarmak isteriz. İleride yapaçağımız örneklerle daha da açıklayıcı olacaktır.

Peki bu nesneleri ne zaman kullanmalıyız.
  • Model sınıfımıza ait bir veriyi açılır listeden (drop down list) seçeceksek bu listenin verisi için kullanabiliriz.
  • Küçük ölçekli veriler.
  • Kullanıcıya verilen uyarı mesajları.
  • Örneğin kullanıcı kayıt olduktan sonra kullanıcıya gösterilen profil özeti ekranı.
Kısacası geçici olarak tanımlayabileceğimiz küçük ölçekli verileri içeren bir çok iş için kullanabiliriz.










3 yorum: