14 Aralık 2015 Pazartesi

MVC (model-view-controller) yeni başlayanlar için

     Bu yazımızda asp.net webform üzerinde biraz geliştirme yapmış ve daha önce asp.net MVC konusunu duymus fakat baslayamamıs olan arkadaşlarımıza giriş düzeyinde bir anlatım olacaktır.
     Bu işe yeni başlayan MVCyi yeni öğrenecek arkadaşlarımızın çoğunluğunun aklına ilk gelen asp.net MVC nin asp.net webformun gelişmiş hali veya yeni bir versiyonu olduğudur. Fakat bu kesinlikle yanlış bir düşüncedir. Fakat web form ile web uygulamaları yapılırken MVC bir mimari yaklaşımdır, bizim kodlarımızın daha doğru ve daha temiz olması mimari açıdan uygulamalarımızın daha hızlı daha güvenli çalışmasını sağlamaktadır.
     Microsoft Asp.net Webform dan sonra MVC mimarisi uzerinde Asp.net MVC geliştirdi. Bu gelişimi yaparken bizlere webformun ayrı MVCnin ayri tutulacağını ve birbirinin yerini almayacağını duyurmuştu. Bu nedenle ki günümüzde web uygulamaları hem webform ile yapılmakta hem de MVC ile yapılmaktadır. Tabi ki gelecekte web uygulamaların MVC üzerine inşaa edileceği öngörülüyor benim düşüncem de bu öngörünün doğru ve mantıklı olduğudur.
    Peki ya ASP.net Web Formu 12 yıldır populer kılan neden nedir?
    Bunun asıl nedenlerinden biri Microsoftun sahip olduğu vede tüm platformlarda kullandığı ide si VisualStudio. .Net yazılımcıları ilk yıllarından buya bu ide üzerinde uygulamalarını geliştirmiştir. Bunun yanında VB.net ten buyana süre gelen bir yazım alışkanlıkları vardır "Code Behind". Yazılımcılar kendi uygulamalarını UI tarafında sürükle bırak yöntemine alışmış ve daha sonra mantık ve veritabanı işlerini çift tık ile UI arkasına geçerek burada tamamlamışlardır. Bu nedenle web formlarda bir aspx ve birde aspx.cs uzantılı dosyalar mevcuttur. Bu şekilde kodlama bir süre sonrasında alışkanlık haline gelmiştir. Bu alışkanlıklardan günümüzde vazgeçmek hiçte kolay değildir.
    Her şey iyi güzel iken Web Formun sahip olduğu eksiklikler nelerdi?
    Web Formun en önemli iki eksikliğe de sahipti. Bunlar:
-Cevap süresi: yani serverın kullanıcının isteğine verdiği cevabın süresi
-Bant genişliği: Servera nekadar datanın gönderildiğidir.(Viewstate'tin fazla data taşıması sistemi ağırlastırmaktadır.)
MVC Contorller
1.  Yeni bir .net MVC projesi(empty) oluşturalım.
2.  Solution explorer dan controler klasorunun uzerine sağ tıklayım yeni controler ekleyelim
3. "MVC 5 Controller – Empty" seçip change authentication kısmından No authentication seciyoruz ve tamam diyoruz. MVC projemiz oluşuyor.
4.  Sıra yeni Controller eklemeye geldi. Controllers sekmesine sağtıklayıp add new Controller diyoruz ve MVC 5 Controller Empty seçiyoruz. Ismine TestController deyip tamam diyoruz.
5. Controller içerisine alttaki actionı ekliyoruz. 
public string YaziYaz()
{
return "Hello World is old now. It’s time for wassup bro ;)";
}
Run dedikten sonra Tarayıcımızda “ControllerName/ActionName” olarak çağırıyoruz. localhost:25654/Test/YaziYaz ve çıktısını goruyoruz :) 

Not: Buraya kadar sizlere .net webform ve asp.net MVC arasındaki ilişkiyi web formların eksik kısımlarını ve yeni bir MVC projesi oluşturup Merhaba Dunya yazmayi gosterdim. 

 TestControler ve Test ilişkisi
TestControler bizim classımızın ismidir Test ise bizim controllerımızın ismidir. Yani biz url de controller ismini yazmank istediğimizde sadece ../Test dememiz yeterli olacaktır.

Action method nedir
Bunlar controler içerisinde bulunan public methodlarımızdır. Kullanıcının istekte bulundugu ve bu isteğe karşı verilen yanıtları içerir.
Yukarıdaki örneğimizde YaziYaz() action methodumuz bizim string değer döndürür.
Web Form projelerinde geri dönüş tipleri html olurdu fakat .net MVC ile biz istediğimiz tipte bir geri dönüş değeri elde ederiz.

public class TestController : Controller
{
public string YaziYaz()
{
return "Hello World is old now. It’s time for wassup bro ;)";
}
//müsteri donduren bir action method
public Musteri getMusteri()
{
Musteri m = new Musteri();
m.adi = "sahin";
m.soyadı = "yaral";
return m;
}
}
public class Musteri
{
public string adi { get; set; }
public string soyadı { get; set; }
}
}
TestController icersine aşağıdaki kodları yazdıktan sonra tarayıcımızda projemizin (NameSpace.ClassName) uzantısını goruruz. Nedeni ise ToString() methodunu ezmemiş olmamızdır.

public class Musteri
{
public string adi { get; set; }
public string soyadı { get; set; }
public override string ToString()
{
return this.adi + "***"+ this.soyadı;
}
}
Yukarıdaki seklinde duzenleyip tekrar F5 yapıyoruz ve action methodtan istedigimiz donuş tipini elde ediyoruz. 
MVC View
Mimari olarak UI katmanıda denir. Kullanıcılara sunulan ara yüzü içermektedir.
1. TestController içerisinde GetView() adinda birtane ActionResult method oluşturalım.
2. Daha sonra bu GetView() uzerinde sağ tıklayarak AddView diyoruz.
3. UseLayoutpage secimini kaldırıyoruz ismini MusteriView olarak koyuyoruz ve add butonuna tıklıyoruz

Views->Test->MusteriView.cshtml olarak oluşturduğumuz viewi görebiliriz.
Not: F5 ile çalıştırma da dikkat edilmesi gereken iki nokta var
Eğerki view üzerinde debug ediyor iseniz controller tarafinda view adında ait bir methodunuz yok ise hata alırsınız!
Controler üzerinde debug ederseniz home klasörüne gider ve buradan siz kendiniz urli yazıp ulaşmalısınız.
Oluşturduğumuz bir method içerisinde durumu kontrol ederek istediğimiz view'i çağırabiliriz.
Aynı Sekilde bir view birden cok method tarafından çağırılabilir.

//bir methodiçerisinde birden cok view çağırılabilir.
public ActionResult ilkView()
{
Random r = new Random();
int sayi=r.Next(0, 10);
if (sayi<5 br="" clear="none">{
return View("YaziYaz");
}
else
{
return View("MusteriView");
}
}
ActionResult ve ViewResult Arasındaki bağlantı
ViewResult actionResult tın iki alt sınıfıdır. Nasıl iki alt sınıfı derseniz eğer: 
ViewResult ViewResultBase'in alt sınıfıdır. ViewResultBase ise actionResult'ın alt sınıfıdır. Burada polymorphism devreye giriyor. Aşağıdaki örneği inceleyelim
 public ActionResult ilkView()
        {
            Random r = new Random();
            int sayi=  r.Next(0, 10);
            if (sayi<5 br="" clear="none">            {
                return Content(YaziYaz());
            }
            else
            {
            return View("MusteriView");
            }
        }
Bu ornekte ActionResult kullandık çünkü ilk durum ViewResult döner iken ikinci durum ContentResult donuyor. ContentResult ta ActionResult'ın alt sınıfıdır. Bizde Polymorphism nimetlerinden faydalanıyoruz.

ViewResult ve ContentResult
ViewResult bizlere yanıt olarak tum htmli döndürmektedir fakat ContentResult ise bize dönüş değeri olarak sadece string degerler doner fakat ikiside actionResult sınıfındandir.

Not: ActionName ile ViewName eşit ise return view içerisine olusturdugumuz view in ismini yazmamıza gerek yoktur.
Routing
Bizim URLimizde yer alan değerlerin anlamsız rakam ve yazılar barındırmasını engeller. Yani sadece klasor goruntusunu verir ve son olarak bulundugumuz sayfanın ismini verir.
RouteConfig
Bizim routemap ayarlarımızın yapıldığı config dosyasıdır. Url haritamızın default değerleri ve routemap yapımızı belirleriz.Birden fazla maproute olusturabiliriz fakat name alanları birbirinden farklı olmalıdır.

MVC Model
Model bizim verilerimizin tutuldu sınıflardır. Örnek üzerinden inceleyelim
1. Model klasörüne sağ tıklayım add->new class diyoruz ve ilk model sınıfımızı oluşturuyoruz. İsmine Calısanlar diyoruz.
2. İçerisine adı soyadı maas ve baslama tarihi parametrelerini ekliyoruz.
public class Calisanlar
{
public string Ad { get; set; }
public string Soyad { get; set; }
public int Maas { get; set; }
public DateTime BaslamaTarihi { get; set; }
}
3. Controllerdan model sınıfımıza erisiyoruz. Erişebilmek için öncelikle using olarak model sınıfımızı eklemeyi unutmuyoruz. 
ViewData Bizim controller ve viewler arasında veri aktarımımızı sağlar.  asp.net ve mvc3 e kadar kullanılmıstır mvc3 ten sonra yerini dinamik yapıya sahip olan ViewBag almıştır.

public ActionResult getCalisanDetay()
{
Calisanlar c = new Calisanlar();
c.Ad = "safak";
c.Soyad = "yaral";
c.Maas = 1234;
c.BaslamaTarihi = DateTime.Now;

//viewdatamızı oluşturup çalısanımızı viewimize gonderiyoruz
ViewData["Calisan"] = c;
return View("Calisan");
}
4. Yeni bir view olusturmak icin getCalisanDetya() uzerine sağ tıklayip addview diyoruz ve ismine Calisan diyoruz.
5. ViewCalisanların içerisini aşağıdaki gibi düzenliyoruz ve f5 ile çalıştırıyoruz. 

Not: Tarayıcıda .../Calisan diye aratırsanız hata alırsınız çünkü controller icerisindeki action ismi ile view ismi farklıdır. Burada action ismini yazmamız gerekmekteri yani .../getCalisanDetay dediğimizde bu methodumuz bizi calısanlar viewine yonlendiricektir.
@{
Projeadi.Modelklasorunadi.Modelsınıfınızınadi cls = (Projeadi.Modelklasorunadi.Modelsınıfınızınadi)
ViewData["Calisan"];
}


Çalışan adı : @cls.Ad

Çalışan soyadı : @cls.Soyad

Çalışan maaş :@cls.Maas.ToString("C")

Çalışan giriş tarihi :@cls.BaslamaTarihi

Çalışan adı-soyadı :@(cls.Ad+” “+cls.Soyad)

ViewBag
C# 4.0 dan sonra geliştirilmistir. MVC3ten sonra viewdata nin yerini almıs ve viewdata nın dinamik hali olarak kullanılmaktadır. Yukarı ki örneğimizde değiştirmemiz gereken alanlar sunlardır:
Controller icerisinde yorumsatirina aldığımız kısım
//viewdatamızı oluşturup çalısanımızı viewimize gonderiyoruz
//ViewData["Calisan"] = c;
//return View("Calisan");
//viewdata yerine viewbag kullanımı
ViewBag.Calisanlar = c;
return View("Calisan");
View içerisinde yorum satırına aldığımız kısım
@*@{
MVCSevenDayStart.Models.Calisanlar cls = (MVCSevenDayStart.Models.Calisanlar)
ViewData["Calisan"];
}*@
@{
MVCSevenDayStart.Models.Calisanlar cls = (MVCSevenDayStart.Models.Calisanlar)
ViewBag.Calisanlar;
}
veya view icerisinde 
@{
@Model;
}

Çalışan adı : @Model.Ad

Çalışan soyadı : @Model.Soyad

Çalışan maaş :@Model.Maas.ToString("C")

Çalışan giriş tarihi :@Model.BaslamaTarihi
gibi bir değişiklik yaparsak çalışan detaylarına ulaşabiliriz. Daha fazla ornek için

View içerisine liste göndermek
1. Bunun için öncelikle yeni bir model oluşturalım ve adina CalisanviewModel diyelim.
public class CalisanViewModel
{
public string Ad { get; set; }
public string Soyad { get; set; }
public string Maas { get; set; }
public DateTime BaslamaTarihi { get; set; }
public string CalisanRenk { get; set; }
}
2. Daha sonra list model oluşturalim ve adına CalisanListViewModel diyelim.
public class CalisanListViewModel
{
public List CalisanlarList { get; set; }
public string KullaniciAdi { get; set; }
}

3. Yeni bir view oluşturalim ve adına CalisanlarListesi diyelim. Ve içerisini aşağıdaki gibi düzenleyelim.
@foreach (CalisanViewModel item in Model.CalisanlarList)
{

@item.Ad

@item.Maas

}
4. Simdi sıra projemizi bir basamak ilerletmeye geldi ve business layer katmanını olusturuyoruz. Bunun için model klasorunun içerisine CalisanlarBusinessLayer adinda bir sinif olusturuyoruz. Ve içerisine GetCalisanlar methodunu ekliyoruz.
public List GetCalisanlar()
{
List calisanList = new List();
for (int i = 0; i < 5;i++ )
{
Calisanlar cls = new Calisanlar();
cls.Ad = "sahin" +i;
cls.Soyad = " yaral"+i;
cls.Maas = 1234 +i*100;
calisanList.Add(cls);
}
return calisanList;
}

5. Sıra verilerimizi view icerisine gostermeye  geldi bunun için yeni bir controller oluşturuyoruz tabi isteyenler testController içerisindede yapabilirdi.Ve olusturdugumuz controller içerigini aşagıdaki gibi düzenliyoruz.
public ActionResult CalisanListesi()
{
CalisanListViewModel calisanListViewModel = new CalisanListViewModel();

CaslisanlarBusinessLayer clsBal = new CaslisanlarBusinessLayer();
List calisanlarList = clsBal.GetCalisanlar();
List clsViewModels = new List();
foreach (Calisanlar item in calisanlarList)
{
CalisanViewModel clsViewModel = new CalisanViewModel();
clsViewModel.Ad = item.Ad + " " + item.Soyad;
clsViewModel.Maas = item.Maas.ToString();
if (item.Maas > 1235)
{
clsViewModel.CalisanRenk = "yellow";
}
else
{
clsViewModel.CalisanRenk = "green";
}
clsViewModels.Add(clsViewModel);
}
calisanListViewModel.CalisanlarList = clsViewModels;
calisanListViewModel.KullaniciAdi = "Admin";
return View("CalisanlarListesi", calisanListViewModel);
}

simdi F5 deyip sonucu kontrol edebiliriz bende .../CalisanList/CalisanListesi altında gorunmektedir.

MVCde başlagıç seviyesinde bir girisimiz oldu.Sanırım birazda uzunca oldu :) Kaynaklar:

Hiç yorum yok:

Yorum Gönder