Sayfalar

13 Mart 2013 Çarşamba

ASP.NET MVC DERSLERİ ( 4.2 ) MODEL GÜNCELLEME

Scaffolding kullanarak oluşturduğumuz controller moetodları ve view sayfaları içerisinde Edit adında action metod ve bunun için bir view sayfası var. Öncelikle Index sayfasının içerisinde aşağıdaki gibi linkler eklendiğini görüyoruz.

Index.cshtml
...
<td>
    @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
    @Html.ActionLink("Details", "Details", new { id=item.Id }) |
    @Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
...

Index sayfası içerisindeki bu linkler controller sınıfındaki GET metodlarına istekte bulunur. Örneğin Edit sayfasının ilk yüklenmesi için aşağıdaki ilk metod çalışır.
//
// GET: /Haber/Edit/5

// index sayfası içerisindeki edit butonuna tıklayınca
// tetiklenen metod. link içerisinde parametre olarak
// gönderilen değer bu metoda geçirilir.
public ActionResult Edit(int id = 0)
{
    // linkten gelen haber id sine ait olan haber bulunur.
    Haberler haberler = db.Haberlers.Find(id);
    if (haberler == null)
    {
        return HttpNotFound();
    }
    // edit sayfası içerisindeki yazarlar ve kategorileri dropdownlistten çekmek için
    // yazarları ve kategorileri ViewBag nesnesi ile view sayfasına taşıyacağız.
    ViewBag.YazarId = new SelectList(db.Yazarlars, "Id", "YazarAdi", haberler.YazarId);
    ViewBag.KategoriId = new SelectList(db.Kategorilers, "Id", "KategoriAdi", haberler.KategoriId);
    return View(haberler);
}

//
// POST: /Haber/Edit/5

// view sayfasında güncelleme işlemleri belirlenip
// form post olduğunda bu metod tetiklenir.
// Edit.cshtml içerisinde düznelediğimiz model
// bu metoda parametre olarak gelir.
[HttpPost]
public ActionResult Edit(Haberler haberler)
{
    //  modelin eksiksiz olduğunu yani
    // formun eksiksiz doldurulduğunun
    // doğrulaması yapılıyor.
    if (ModelState.IsValid)
    {
        // eğer model geçerli ise bu modeli veritabanı modeline ekleyip
        // değişiklik varsa güncelliyoruz.
        db.Entry(haberler).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    // güncelleme işlemi başarısızsa ViewBag nesnelerimizi tekrardan ilkleyip
    // yine Edit.cshtml sayfasına gönderiyoruz.
    ViewBag.YazarId = new SelectList(db.Yazarlars, "Id", "YazarAdi", haberler.YazarId);
    ViewBag.KategoriId = new SelectList(db.Kategorilers, "Id", "KategoriAdi", haberler.KategoriId);
    return View(haberler);
}

Edit.cshtml sayfasına dikkat çekmek istediğim nokta dropdownlist elemanı olacaktır. View sayfasında;
<div class="editor-label">
    @Html.LabelFor(model => model.YazarId, "Yazar")
</div>
<div class="editor-field">
    @Html.DropDownList("YazarId", String.Empty)
    @Html.ValidationMessageFor(model => model.YazarId)
</div>

gibi bir tanımlama var. ViewBag nesnesinin adı ile dropdownlist nesnesi içerisindeki YazarId aynı olduğu zaman isim eşleşmesi ile ViewBag nesnesini buluyor. Burada tabi ViewBag nesnesinin ne tipte veri tipi tuttuğunu View sayfası bilmiyor. Bundan dolayı ViewModel mantığını kullanan geliştiriciler bunu farklı bir yöntemle yapıyor.

Edit sayfası içerisinde kullanacağımız bir view bağımlı model oluşturuyoruz.
public class HaberEditViewModel
{
    public Haberler Haber{ get; set; }
    public SelectList Yazarlar { get; set; }
    public SelectList Kategoriler { get; set; }
}

Edit(GET) metodu içerisinde bu sınıfın bir nesnesini oluşturup, ViewBag yerine artık bu sınıfın SelectList elemanlarını doldurup, Editcshtml View sayfasına parametre olarak geçiriyoruz.

İkinci bir önemli konu ModelBinding;

Model Binding

Edit.cshtml sayfası içerisinde @model MVCTEST.Models.Haberler şeklinde bir tanımlama var. Bu tanımlama ile metoddan gelen modeli view içerisinde aldığımızı söyluyoruz ve strongly-typed-helper lar kullanarak bu modelin özelliklerini değiştiriyoruz. Html-helper nesnelerini ileride göreceğiz ama bu konu için şu kadarını bilin, sonunda "For" soneki olan helperlar strongly-typed dır. Yani bizim özelliğini değiştirdiğimiz elemanlar direk olarak modele bağlanmış olur.

View sayfasını post ettiğimizde Edit Post metodu çalışır. Bu metod parametre olarak Haberler nesnesini alır ki bu da bizim view sayfasınada özelliklerini değiştirdiğimiz modeldir. Yani MVC strongly-yped-helper lar ile otomatik olarak girdileri modele bağlar. Bu yönteme imlicit model binding denir ve genelde de bu kullanılır.

Explicit model binding ise, model parametre olarak gönderilmez ama Post Edit metodu içerisinde TryUpdateModel onksiyonu ile model binding yapılır.
[HttpPost]
public ActionResult Edit()
{
    var haber = new Haberler();
    TryUpdateModel(haber);
    if (ModelState.IsValid)
    {
        .....

13 yorum:

  1. Üstad çok güzel anlatıyorsun. Eline koluna sağlık.

    Umarım bu dersler yarım kalmadan devam eder ve sayende bizlerde A'dan Z'ye çeşitli örnek ve uygulamalarla MVC'yi iyice öğreniriz.

    10 yıldır ASP yazıyorum. .net'de sadece WebForm'lar var diye düşünüyordum ve hiç sevmemiştim.

    MVC ile Razor ile tanışınca dedim şimdi oldu.
    C# ve Java zaten biliyordum. Senin derslerini de bulunca çok iyi oldu, teşekkürler.

    YanıtlaSil
  2. Teşekkür ederim.

    İnşallah dediğiniz gibi yarım bırakmam. Sonuna kadar bitirmeyi çok istiyorum. Ders eklemek biraz zor oluyor. Bildiğim şeyleri yazarken, neyin nerden geldiğini, neden böyle olduğunu detaylı olarak tekrardan araştırarak yazmaya çalışıyorum.

    Kodların hepsini tekrardan test ederek ekliyorum. Çünkü eksik birşey kalmasın istiyorum.

    YanıtlaSil
    Yanıtlar
    1. helal. başarılar kardeş

      Sil
  3. O konuda bende seve seve yardımcı olurum.

    Dediğin gibi bildiğin bir şeyi, hiç bilmeyen birine anlatırken zorlanabilirsin.

    Ben hiç bilmeyen biri olarak anlaşılmayan yerleri belirtirim buradan zaten.

    Ayrıca kodlarıda denediğim için, sıkıntı varsa söylerim.

    Kolay gelsin. Biz teşekkür ederiz.

    YanıtlaSil
  4. Hocam internet sitesi yaparken bazı aldığım notların olduğu bir blogum var.

    Ziyaretçilere kapalı, sadece kendim için notlar alıyorum. Daha sonra aradığımı bulmakta işe yarıyor.

    Hepsi sizin bildiğiniz şeylerdir. Blogum şöyle..
    http://184.168.19.38/10000/aspnotlar/

    YanıtlaSil
  5. dostum bu örneğin projesini paylaşma imkanın var mı

    YanıtlaSil
    Yanıtlar
    1. Aslında tek bir proje yok, makale yazarken gerekli olan projeyi ve sınıfları oluşturup test edip kodları ekliyorum, bu anlattıklarımın ve anlatacaklarımın tamamını içeren açık kaynak bir uygulama var. Eğitim için hazırlanmış bir uygulama bunu indirip inceleyebilirsiniz.

      http://mvcmusicstore.codeplex.com/

      Ayrıca sadece konuya özel bir uygulama isterseniz, uygulamayı hazırlar ve paylaşırım...

      Sil
    2. Proje paylaşımına başladım.

      http://alirizaadiyahsi.blogspot.com/2013/04/aspnet-mvc-ornek-proje-baslangic-haber.html

      Sil
  6. if (ModelState.IsValid) {
    Urun u = new Urun();
    u.Adi = adi;
    u.Aciklama = aciklama;
    u.Fiyat = fiyat;
    dbb.SaveChanges();
    }

    Burdaki ModelState.IsValid ne işe yarıyor açıklayabilirmisiniz şimdiden teşekkürler

    YanıtlaSil
    Yanıtlar
    1. Model için tanımlanmış validation ları kontrol eder. Örneğin, ürün adı boş olamaz diye tanımladıysanız ve boş bırakırsanız, bu if i gecemez.

      Sil
    2. Teşekkür Ederim

      Bir Soru Daha Soracagım Şu Kodu Ne işe Yaradıgını(UpdateModel) Açıklayabilirmisiniz?

      Urun urunler = new Urun();
      UpdateModel(urunler);

      Sil
    3. Manuel Model Binding. Cok onemli degil, otomatik binding var zaten. Yani zaten modeli, biz action a parametre olarak gonderiyoruz, dolayısıyla buna gerek kalmıyor.

      Sil