ViewData kavramı ve ViewModel Deseni

19 Ağu

ViewData yardımıyla Controller tarafından View tarafına veri geçirme işlemi

Bu yazımızda mvc ortamında kullanılan ViewModel deseni üzerinde duracağız. View katmanına Controller sınıfından ViewData, TempData, ViewBag gibi nesneler yardımıyla veri geçirebilmekteyiz. Örneğin bir dropdodwnlist bileşeninin içeriğini taşıyan kolleksiyon nesnesi bu yapılar vasıtasıyla View sayfasına taşınabilmektedir. Örneklendirmeyi NerdDinner uygulaması üzerinden yapılmaktadır.

Controller Tarafı:

public ActionResult Edit(int id) {

Dinner dinner = dinnerRepository.GetDinner(id);

ViewData[“Countries”] = new SelectList(PhoneValidator.Countries,

dinner.Country);

return View(dinner);

}

View Tarafı:

Html.DropDownList(“Country”, ViewData[“Countries”] as SelectList)

Yukarıda görüldüğü gibi ViewData nesnesi Country listesini view tarafına taşımaktadır.

ViewModel Deseni

Yukarıda bahsettiğimiz şekilde conroller sınıfından view şablonuna veri geçirmek kısa vadede pratik ve hızlı bir çözümdür. Küçük projelerde kullanılabilecek iyi bir yöntem olarak görülebilir. Fakat bu yöntemin uzun vadede bazı dezavantajları vardır. Bunlardan biri geliştirici string tabanlı bir yazım yöntemi kullandığı için (ViewData[“Countries”]) herhangi bir yazım yanlışında derleme zanında hata yakalanamayacaktır. Bir diğer dezavantaj ise ViewData nesnesinin bir SelectList tipine çevrilrme gereği duyulmasıdır.

Bu dezavantajlara alternatif olarak sunulan bir çözüm ise VievModel deseninin kullanılmasıdır. Yani View şablonunda ihtiyaç duyulacak bileşenlere göre bir sınıf oluşturularak Strongly-typed yöntemi ile View sayfası bu sınıftan üretilir. View sayfasında kullanacağımız dropdown gibi bileşenler için SelectList nesneleri yazdığımız sınıf içine tanımlanır. Controller sınıfı yardımıyla optimize edilmiş ViewModel sınıfı Viewtarafına sunulmuş olur.

public class DinnerFormViewModel {

// Properties

public Dinner Dinner { get; private set; }

public SelectList Countries { get; private set; }

// Constructor

public DinnerFormViewModel(Dinner dinner) {

Dinner = dinner;

Countries = new SelectList(PhoneValidator.Countries,

dinner.Country);

}

}

Yukarıda Nerddinner projesinden bir ViewModel örneği gösterilmiştir. Yani view şablonunda Dinner nesnesi ve country listesini tutacak birde SelectList nesnesi oluşturulmuştur.

Güncelleme işlemi için action metodlarını aşağıdaki gibi tanımlayabiliriz.

[Authorize]

public ActionResult Edit(int id)
{

Dinner dinner = dinnerRepository.GetDinner(id);

return View(new DinnerFormViewModel(dinner));

}

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Edit(int id, FormCollection collection) {

Dinner dinner = dinnerRepository.GetDinner(id);
try {

UpdateModel(dinner, “Dinner”);

dinnerRepository.Save();

return RedirectToAction(“Details”, new { id=dinner.DinnerID });

}

catch {

ModelState.AddModelErrors(dinner.GetRuleViolations());

return View(new DinnerFormViewModel(dinner));

}

}

Dikkat 1

Bu noktada dikkat etmemiz gereken önemli bir nokta: View sayfasının DinnerFormViewModel sınıfından türemiştir.

Dikkat 2

Eğer view sayfası Dinner sınıfından türetilseydi UpdateModel() metodu şu şekilde olacaktı.

UpdateModel(dinner);

Ancak DinnerFormViewModel sınıfından türetildiği için şu şekilde olmuştur.

UpdateModel(dinner, “Dinner”);