Önceki yazımda ASP.NET MVC Framework’ü genel hatlarıyla incelemiştik. Bu yazımızda da bir MVC uygulamasını geliştirmeye çalışacağız. Öncelikli olarak Visual Studio 2008'de File > New Project linkini, açılan pencereden kullanacağımız dilin altında yer alan proje türlerinden Web'i seçiyor ve buradan da ASP.NET MVC Web Application proje şablonunu seçerek yeni bir proje oluşturuyoruz.
Resim: ASP.NET MVC projesinin oluşturulması
Proje oluşturulurken Visual Studio, MVC uygulaması ile birlikte bir de test projesi oluşturmak için onay penceresi çıkaracaktır. Bu test projesi, MVC uygulamamızdaki action metotlarını test edebilmemiz, yani unit test'ler yapabilmemiz için kullanılabilir. Eğer test işlemleri de yapacaksanız karşınıza çıkan bu pencereden Yes… ile başlayan seçeneği kullanabilirsiniz. Burada MVC Framework ile gelen standart Visual Studio Unit Test framework'ü kullanılabileceği gibi üçüncü parti test framework'leri de kullanılabilir. Biz şimdilik test projesi kullanmayacağımız için No… ile başlayan seçeneği seçiyor ve OK butonuna tıklıyoruz.
Resim: Unit Test Projesi seçenekleri
ASP.NET MVC Web uygulamamız oluşturuldu. İlk olarak Solution Explorer'a bakıyor ve bize biraz yabancı gelebilecek dizin yapısını inceliyoruz. Aşağıdaki resimde projemizin Solution Explorer'daki görüntüsü bulunmaktadır.
Resim: ASP.NET MVC projemizin dosya ve klasör yapısı
Resim üzerinde klasörlerle ilgili kısa açıklamaları bulabilirsiniz. Bizim için burada önemli olan dizinler Controllers, Models ve Views olacaktır. Herbirinin adından da anlaşılacağı üzere Model View Controller deseninin dosya olarak uygulanışı bu dizinler içerisinde olacaktır. Bunun dışında Content css, resim gibi dosyaları, Scripts ise JavaScript kod kütüphanalerini içermesi için özel ayrılmış dizinlerdir. Scripts klasöründe AJAX, MVC için AJAX ve jQuery kütüphanelerini otomatik olarak geldiği de görülmektedir. Controllers klasöründe AccountController ve HomeController adında iki Controller class'ı bulunmaktadır. Bu iki class URL içerisinde controller değeri Home ve Account olan talepleri karşılayacaktır. View klasöründe ise Account, Home ve Shared klasörleri yer almaktadır. Shared tüm View nesnelerinde ortak kullanılabilecek master sayfa, user control gibi dosyalar içindir. Diğer iki klasöre baktığımızda ise isim olarak Controller sınıflarımızla benzerlik göstermektedir. HomeController'a karşılık gelen Home, AccountController'a karşılık gelen Account adında bir dizin ve bu dizinler altında da kullanıcıların görebileceği aspx dosyaları yer alır. Aslında buradaki isimlendirmeler tesadüf olarak Controller sınıflarına benzemiyor, MVC uygulamasındaki isimlendirme standartına göre HomeController gibi bir controller sınıfına gelen talepler Views altında Home dizini altında yer alan dosyalara iletilecektir. Eğer kendi özel iş mantığımıza göre nesnelerinizi oluşturmak istersek; örneğin veritabanındaki ürünlerimizle ilgili sayfalar oluşturmak için Controllers dizinine UrunController adında bir controller sınıfı ve Views dizini altında da Urun adında bir dizin oluşturmanız gerekecektir.
ASP.NET MVC uygulamalarında URL'deki dizime göre taleplerin işlendiğinden bahsetmiştik. Global.asax dosyası içerisinde uygulamanın başlangıcında(Application_Start metodunda) URL formatlamasının nasıl yapılacağı belirlenmektedir. System.Web.Routing isimalanı altında yer alan RouteTable sınıfının Routes koleksiyonu uygulama genelinde geçerli olacak URL Routing ayarlarını saklamaktadır. Bu koleksiyona eklenecek her URL formatı MVC projesine gelen URL taleplerinde değerlendirilecektir. Aşağıda ASP.NET MVC uygulamalarının varsayılan URL Routing ayarı görülmektedir.
Global.asax
publicue;">class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
Routes koleksiyonunun MapRoute metoduna bakacak olursak; ilk parametrenin route ismini, ikinci parametrenin URL formatını, üçüncü parametrenin ise bu Route ayarının varsayılan değerlerini belirlediğini görürüz. Bu tanımlama sayesinde uygulamaya;
site.com/Products/Edit/3 şeklinde bir URL talebi gelirse
– controller: ProductsController (Controllers klasörü altındaki sınıf)
– action: Edit (ProductsController sınıfı içerisindeki Edit metodu)
– id: 3 (Edit metoduna gönderilecek parametre)
olacaktır. Eğer site.com şeklinde bir talep gelseydi controller HomeControler(URL'de controller değeri belirtilmediği için HomeController'a gidilir), action ise Index olacaktı. Çünkü bu değerlerin boş bırakılması durumunda varsayılan değerlerinin ne olacağı yukarıdaki MapRoute metodunun son parametresinde bu şekilde belirtilmişti. Özel bir not; MapRoute metodundaki son parametre C# 3.0 ile gelen anonim tip(anonymous type) özelliği kullanılarak yazılmıştır.Controller kendisine gelen talebi View'a iletir demiştik. Eğer talep esnasında veriye erişmek gerekiyorsa action metodu içerisinden(yani Controller katmanından) Model bileşenlerine erişilir. Controller Model katmanından çektiği veriyi View'a iletir ve View'da HTML çıktıyı oluşturarak istemciye iletir. Bu arada View içerisinden de doğrudan Model nesnelerine erişilebileceğini, ancak Model içerisinden View'a erişilemeyeceğini de belirtmekte fayda var.
Açtığımız projeyi çalıştırarak MVC'nin temel anlamda işleyişini incelemeye çalışalım. Bu işlemin öncesinde HomeController sınıfındaki About metodunun ilk satırına bir break-point ekleyerek debug modda bu sayfaya yapılan bir talebin bu nasıl işleneceğini izleyelim. F5 tuşuna basarak projenin ana sayfasına gidiyor ve sağ üstteki About linkine tıklıyoruz.
Resim: Home/About şeklindeki URL'e gelen talebin işleyişi
Görüleceği gibi About sayfasında, yani Home/About şeklinde gelen URL talebinde HomeController sınıfının About adındaki action metodu çağrıldı ve bu metottan Views klasörünün altındaki Home/About.aspx adındaki View nesnesi görüntülendi. Anlaşıldığı gibi HomeController nesnesine gelen bir talepte Views dizinindeki Home dizini altında yer alan aspx dosyaları kullanıcıya gönderiliyor. Dosya adının belirlenmesinde de action metodunun isminin etkili olduğu görünmekte. ASP.NET MVC uygulamalarında View nesnelerinin isimlendirme standartı ve Controller nesnesi ile arasındaki ilişki bu şekildedir.
Bu örnekte dikkat çeken bir diğer noktada URL'nin yazılış şeklidir. Bildiğiniz gibi klasik ASP.NET uygulamalarında bu URL aslında bir klasörü simgeler. Klasik ASP.NET uygulamalarında sayfalara yapılan her talebin sonunda sayfanın uzantısı, yani .aspx olmalıdır. Ancak burada adresin sonunda herhangi bir uzantı olmadığı dikkat çekmektedir. Hatta projemizin dizin yapısına baktığımızda root dizinimizde Home adında bir klasör olmadığını da görürüz. MVC uygulamaları URL Routing ile çalıştığı için bu şekilde gelen URL'ler arka planda uygun View nesnesi üzerinden cevaba dönüştürülür. Bu şekilde yazılan URL'ler hem kullanıcılar için daha okunaklı olacak hem de arama motorlarının sayfamızı daha iyi analiz etmesini sağlayacaktır.
Dilerseniz projemize bir de LINQ to SQL sınıfı; yani bir Model nesnesi ekleyerek Controller'ın veriyi nasıl View'a taşıdığını inceleyelim. Models klasörünün üzerine sağ tıklayarak Add > New Item diyoruz ve LINQ to SQL Classes'ı seçerek adı Northwind.dbml olan yeni bir dosya ekliyoruz. Northwind veritabanındaki Products tablosunu entity olarak bu dosya içerisinde ekliyoruz. Artık projemizde Product adında bir Model nesnemiz var. Sıra geldi gerekli Controller ve View nesnelerini oluşturmaya. Controllers klasörüne sağ tıklayarak Add > Controller seçeneğine tıklıyoruz. Karşımızda çıkan pencereden Controller nesnemize UrunController adını veriyoruz. Dikkat edeceğiniz üzere bu penceredeki seçim kutusu ile otomatik olarak belirli metotların otomatik tanımlanmasını sağlayabiliriz.
Resim: UrunController dosyasının projemize eklenmesi
UrunController sınıfı System.Web.Mvc isimalanı altında yer alan Controller adındaki bir sınıftan kalıtılmaktadır. İçerisindeki Index adındaki metodu ben Detay olarak değiştiriyorum ve metoda id adında Int32 tipinden bir de parametre ekliyorum. Gelelim Model nesnesine nasıl erişeceğimize; aslında bildiğimiz klasik kodlama işleminden başka birşey yapmayacağız. Detay metodu içerisinde bir context nesnesi oluşturarak gerekli LINQ sorgusu ile id bilgisi verilen ürünün bilgilerini getireceğiz. Metodumuzun son hali aşağıdaki gibidir.
Controllers/UrunController.cs
…
using AspnetMvcGiris.Models;
namespace AspnetMvcGiris.Controllers
{
public class UrunController : Controller
{
public ActionResult Detay(int id)
{
NorthwindDataContext ctx = new NorthwindDataContext();
Product urun = (from u in ctx.Products
where u.ProductID == id
select u).FirstOrDefault();
return View(urun);
}
}
}
LINQ sorgusu sonucunda getirilen ürün bilgisi return View(urun) ile View sayfasına gönderilmektedir. Buradaki View metodu, şu an içerisinde bulunduğumuz action'ın View dosyasını çağıracaktır. Bu dosyaya da Model adındaki bir nesne içerisinde ürünün bilgilerini taşıyacaktır. MVC uygulamalarındaki sıkıntılarımızdan birisi ASP.NET sunucu kontrollerini kullanamıyor olmamızdı. Bu ilk aşamada View içerisindeki sayfalarımızı tasarlamakta bize zorluk çıkaracak gibi görünse de Visual Studio üzerindeki ASP.NET MVC için gelen özel menüler ve araçlar sayesinde yine daha az kod yazarak arayüzler oluşturabiliyoruz. Yukarıda gördüğümüz Detay adındaki metodun içerisinde herhangi bir yere sağ tıklayarak açılan menüden Add View seçeneğine tıklayalım. Açılan pencere Controller nesnemizden ve action metodumuzdan yola çıkarak bize bir View nesnesi oluşturacaktır. Pencereden eğer Create a strongly-typed view seçeneğini seçersek, aktifleşen kısımlarda oluşan View nesnesinde hangi Model tipine ait bilgilerin görüntüleneceğini(View data class) ve sayfa içeriğinin(View content); yani sayfa detay bilgisi mi gösterecek yoksa güncelleme işlemi mi yapacak, bu bilgileri belirleyebiliyoruz. Add butonuna tıkladığımızda ise Visual Studio'nun ihtiyacımız olan View nesnesini otomatik olarak oluşturacağını göreceğiz. (Views klasörü altına Urun, bu klasörün altına da Detay.aspx adında bir dosya eklenir)
Resim: Hazırladığımız action metodu üzerinden gerekli olan View nesnesini kolay şekilde oluşturabiliriz
Detay.aspx sayfasını incelediğimizde Product nesnesine göre özel bir arayüz hazırlandığını ve ürünün bilgilerinin de Model adındaki nesne üzerinden taşındığını görebiliriz. Uygulamayı çalıştırıp Urun/Detay/3 şeklindeki bir URL'yi talep edersek aşağıdaki gibi bir çıktı alırız.
Resim: Urun/Detay/3 şeklindeki bir URL talebinde karşılaştığımız sayfa
URL'deki id değerine göre ürün bilgilerini sayfamızda görebildik. Eğer sayfanın görünümünü değiştirmek istersek Views/Urun/Detay.aspx sayfası içerisinde gerekli değişiklikleri yapabiliriz.
Böylece genel hatlarıyla bir ASP.NET MVC projesini, bu projeye Controller, Model ve View nesnelerini nasıl ekleyebileceğimizi gördük.
Hocam süper oldu bu yazılar. Devamınıda bekliyoruz dört gözle. Akşamları genelde mesaiye kaldığım için webcastleri izleme şansım olmuyor. MVC anlatcakmışsınız bu ay gördüm programda:) onu kaydedip yayınlarsanız çok sevinirim.
Bu arada MVP’liğiniz hayırlı uğurlu olsun.
Hocam eline sağlık. Asp.Net e gönül vermiş biri olarak Asp.Net MVC ye kayıtsız kalmak benim için imkansızdı. Sayende kolay bir geçiş olacak. Makalelerinin devamını bekliyorum.
Çallşmanız güzel. Genel bir önerim olacak: Eğitimcilerin iki hatası oluyor: 1) Net ve kitaptaki derslerinde de sınıfta öğretir gibi yazmaları. 2) Konuyu analitik ve kısa cümleler ile bilgi yoğun ama sadece şekilde aktarmamaları.
Bunlara dikkat ederek yazılırsa kendi kendine öğrenme yeteneği olan kişiler için daha verimli olacak net ve kitaplar daha etkin kaynaklara dönüşür. Saygılar.
Yorumlar için teşekkür ederim. Bunlara hata demeyelim de yorum farkı diyelim. Sonuçta herkesin kendine göre farklı bir tarzı, yolu olabiliyor ve deneyip başarılı olduğunu gördüğü bu yolları kullanmayı amaç edinebiliyor. 2.5 yıl önce bu tarzın doğru ve faydalı olduğunu düşündüğüm için böyle yazmıştım. Halâ öyle düşünmekle birlikte, bugün olsa biraz daha farklı yazardım diyebiliyorum. Ve yorumları dikkate alarak yazdıklarımı gözden geçiren birisiyimdir. Söylediklerini dikkate alacağım, emin olabilirsin