15 Temmuz 2014 Salı

Model, View, Controller Yapılarına Detaylı Bakış

Önceki yazımızda ASP.NET MVC yapısının ne olduğundan ve avantajlarından bahsetmiştik. Bu yazıda ise daha derinlere inerek MVC'deki Model-View-Controller isimli üç silahşörlerin tüm özelliklerinden bahsedeceğiz.

Bu yazıyı okuduktan sonra, bir MVC uygulamasının farklı bölümlerinin nasıl birlikte çalıştığını öğrenmiş olacağız. Ayrıca bir MVC uygulamasının mimarisinin nasıl Web Forms uygulamasından farklı olduğunu göreceğiz.

Örnek bir ASP.NET MVC Uygulaması

Visual Studio'da bulunan ASP.NET MVC Web Uygulamaları oluşturmak için varsayılan şablon, oldukça basit bir örnek uygulama içerir. Bu örnek uygulamayı, bir MVC uygulamasının çeşitli bölümlerini kolayca kavrayabilmek için kullanabiliriz. Yazımızda da zaten bu örneği kullanacağız.


Visual Studio 2012'yi çalıştırdıktan sonra üst menüdeki File sekmesinden New Project'i seçerek bir ASP.NET MVC uygulaması oluşturabiliriz. New Project kutucuğundan Visual C#'ı seçerek altında kalan proje türlerinden ASP.NET MVC 4 Web Application'ı seçelim. Sonrasında OK'a tıklayalım.


Bir ASP.NET MVC uygulaması oluşturduğumuzda MVC şablonlarından birini kullanın diye öntanımlı olarak sorar. Burada sunucu olarak kendi bilgisayarımızı kullanmamız için hem de kolaylık açısından Intranet (Internet değil) Apllication'ı seçelim ve OK'a tıklayalım.


ASP.NET MVC uygulaması oluşturulduktan sonra bizi bir Readme dosyası karşılıyor. Solution Explorer penceresine baktığımızda ise birçok dosya ve dizin görüyoruz. Özellikle de Models, Views ve Controllers ismindeki 3 dizin gözümüze çarpıyor. Adından da anlaşılacağı gibi bu dizinler Model-View-Controller yapısını implement etmek için var.


Eğer Solution Explorer penceresinden Controllers dizinini genişlettiğimiz zaman HomeController.cs dosyasının bulunduğunu görüyoruz. View dizinini genişletttiğimiz taktirde de ortaya Home ve Shared isimli iki altdizinin çıktığını görüyoruz. Home dizinin altında About.cshtml, Contact.cshtml ve Index.cshtml isminde iki ek dosya görebilmemiz mümkün. Bu dosyalar, varsayılan ASP.NET MVC şablonunda bulunan örnek uygulamayı oluşturuyorlar.

Not: .cshtml uzantılı dosyaların .aspx'lerden aslında çok büyük bir farkı yok. ASP.NET inline kodları gibi Razor kodları da geçici ara koda dönüştürülüyor. Razor View Engine'deki syntax yapısının daha kolay olduğu için böyle bir uygulamaya gidilmiş. Razor kodlarında sadece @ işareti kullanarak kolayca C# kodları gömebilmek mümkün.
Human nesnesinden Name özelliğini okuyacağımızı düşünelim:
Inline syntax:  <div>Name is <%=Human.Name %></div>
Razor syntax: <div>Name is @Model.Name</div>

Gördüğümüz gibi Razor syntax ile daha kolay bir şekilde Name özelliğini okumuş olduk.


Debug menüsünden Start Debugging'i seçererk örnek uygulamayı çalıştırabilmemiz mümkün. Buna alternatif olarak F5'e de basabiliriz.

Visual Studio otomatik olarak uygulamamızı tarayıcımızda çalıştırılıyor. Ve uygulamamızın patladığını görüyoruz :)


Burada Access is denied (erişim engellendi) hatasını almamızın sebebi aslında Microsoft'un MVC uygulamaları korumak için varsayılan olarak getirdiği bir güvenlik önlemi.






Visual Studio'ya gelip Stop Debugging yaptıktan sonra Solution Explorer'da Web.config dosyası içerisinde 23.satırdaki <deny users="?" /> etiketini yorum satırı haline getirerek bunu çözebiliriz. Şimdi tekrar uygulamamızı başlatabilriz.


 Örnek uygulamamız Index, About ve Contact olmak üzere üç web sayfası içeriyor. About sayfasına gitmek için üstteki About linkine tıklayabiliriz.

Adres çubuğuna bakarsak /Home/About ve /Home/Contact olarak değiştiğini görebiliriz.

Tarayıcıyı kapatıp Visual Studio'ya döndüğümüzde Home/About gibi bir path göremiyoruz. Peki dosya nereye gitti havalanıp uçmadı ya? Böyle bir şeyin olması mümkün olabilir mi?

MVC Uygulamasında URL İle Sayfa Birbirine Eşit Değildir

Bir ASP.NET Web Forms uygulaması oluşturduğumuzda URL ve sayfanın bire-bir eşleştiğini görürüz. Mesela sunucudan Sayfam.aspx isimli bir web sayfası istersek, diskten de Sayfam.aspx isimli sayfanın gelmesini bekleriz. Eğer böyle bir sayfa mevcut değilse 404 - Sayfa Bulunamadı hatasını alırız.

Web Forms'un aksine MVC uygulamasında, tarayıcıdaki adres çubuğuna yazdığımız URL ile uygulamamızdaki dosyalar arasında böyle bir benzeşme yoktur. MVC uygulamasında bir URL, diskteki sayfa yerine controller'daki action ile eşleşir.

ASP.NET uygulamasında, tarayıcı istekleri sayfalar ile eşleştirilir. MVC uygulamasında ise tarayıcı isteklerine cevap veren controller eylemleri (actions) vardır. Web Forms uygulamaları içerik odaklıdır. MVC uygulamaları ise uygulama mantığı (application logic) üzerine odaklıdır.

ASP.NET Routing

ASP.NET Framework'teki gelen tarayıcı isteklerinin bir controller eylemine eşleştirilmesine ASP.NET Routing denir. MVC Framework, gelen istekleri controller eylemlerine yönlendirmek için ASP Routing kullanır.

ASP.NET Routing, gelen istekleri işleyebilmek için bir yönlendirme tablosu (routing table) kullanır. Bu yönlendirme tablosu, web uygulamamızı ilk kez başlattığımızda oluşturulur. Yönlendirme tablosu, Solution Explorer'da yer alan Global.asax dosyasında oluşturulur.


ASP.NET uygulaması ilk kez başlatıldığında Application_Start() metodu çalıştırılır. Bu metod RegisterRoutes() metodunu çalıştırır ve RegisterRoutes() metodu varsayılan yönlendirme tablosunu oluşturur.

Varsayılan yönlendirme tablosunda tek bir tane yönlendirme bulunur. Bu yönlendirme, gelen istekleri 3 parçaya ayrıştırır:
  1. İlk parça bir controller ismi ile eşleştirilir.
  2. İkinci parça action adı ile eşleştirilir.
  3. Son parça da belirlenen action'ın id parametresi ile eşleştirilir
Örneğin şöyle bir URL'imiz olsun: /Ürün/Detaylar/3
Bu URL aşağıdaki şekilde üç parametreye ayrıştırılır:

  • Controller = Ürün
  • Action = Detaylar
  • Id = 3
Global.asax dosyasında tanımlanan varsayılan yönlendirmede 3 tane ön tanımlı parametre değeri vardır:

  • Controller Home'dur
  • Action Index'tir
  • Id ise boş bir string'dir.

Bu üçünü göze alarak, aşağıdaki URL'in nasıl ayrıştırılacağına daha yakından bakalım:
URL: /Employee

  • Controller = Employee
  • Action = Index
  • Id = ��

Bir de herhangi bir URL girmeden bir MVC Uygulaması açarsanız, URL varsayılan olarak şu şekilde ayrıştırılacaktır:

  • Controller = Home
  • Action = Index
  • Id =��


Controlller'lar Nedir?

MVC Uygulaması ile kullanıcı etkileşimin kontrolünden bir controller sorumludur. Bu controller, MVC Uygulamasındaki akış kontrolü mantığını (flow control logic) içerir. Kullanıcı tarayıcıdan bir istek oluşturduğunda, kullanıcıya neyin geri döneceğini bir controller belirler.

Bir controller, C# veya VB dilinde yazılan bildiğimiz sınıftır. Örnek MVC uygulamamız Controllers dizini altında HomeController.cs isimli controller'ı içerir. Hadi bu controller'a daha yakından bakalım.

Sınıfa baktığımızda Index(), About() ve Contact isimli üç metod görüyoruz. Bu üç metod, controller tarafından sunulan üç tane eyleme cevap vermek üzere hazırlanmıştır. Controller'a /Home/Index isimli bir URL geldiğinde HomeController.Index() metodu, /Home/About URL'i geldiğinde HomeController.About() metodu çalıştırılır.

Bir contolller'daki her bir public metod, bir controller eylemine (action) tekabül eder. Bu konuda dikkatli olmalıyız. Çünkü, tarayıcı üzerinden URL'i doğru şekilde giren herhangi bir kimse controller içerisindeki public metoda erişip çalıştırabilir.

View'lar Nedir?

HomeController sınıfının Index(), About() ve Contact() isminde üç tane metod sunduğundan daha önce bahsetmiştik. Bu metodların üçü de birer view döndürüyor. Bir view'da HTML kodları ve tarayıcıya iletilecek içerik bulunur. MVC uygulamasında bir view, bir web sayfasıyla eş değerdir.

View'ları doğru konumda oluşturmalıyız. Mesela HomeController.Index() eylemi aşağıdaki konumdaki bir view'ı return eder:
\Views\Home\Index.cshtml

HomeController.About() eylemi ise aşağıdaki URL'de bulunan bir view'ı geri döndürür:
\Views\Home\About.cshtml

Bir controller eylemi için bir view döndürmek istiyorsak, Views dizini altında o controller ile aynı isimde bir alt dizin oluşturmamız gerekir. Alt dizin içerisinde de, controller eylemi ile aynı isimde bir .cshtml dosyası oluşturmak zorundayız.


Solution Explorer'daki About.cshtml dosyasına yakından bakalım. @'li satırlar haricinde, view'ın geri kalanı standart bir HTML yapısında görünüyor. Bu sayede view içeriğindeki HTML kodlarını değiştirebilmemiz mümkün.

Bir view, Web Forms'daki bir sayfaya oldukça benzer. Bir view sadece HTML değil aynı zamanda script'leri de içerebilir. C# veya VB ile scriptleri yazarak, veritabanı gibi dinamik içerikleri görüntüleyebilmemiz mümkün.

Model'lar nedir?

Controller'lardan ve view'lardan bahsetmiştik. Son konumuz ise model'lar ile alakalı. Peki bir MVC uygulamasındaki model nedir?

Bir MVC model, controller veya view'da bulunmayan tüm uygulama mantığını (application logic) içerir. Bu sebeple Model; business, validation ve database logic'ini içermelidir. Örneğin veritabanına bağlanmak için Entity Framework kulanıyorsak, Models dizini altında Entity Framework sınıflarını (.edmx dosyasını) oluşturmamız gerekir.

Bir view yalnızca ve sadece kullanıcı arayüzü oluşturma ile alakalı işleri içermelidir. Bir controller da kullanıcıya doğru view'ı return edecek kısmı içermelidir. Geriye kalan herşey model içerisinde yer alır.

Genelde büyük model'lar ve küçük controller sınıfları ile uğraşmalıyız. Controller'ımızda sadece birkaç satır kod bulunmalıdır. Eğer bir controller eylemi kodlarla şişerse, bir kısım kodları Models dizinindeki yeni bir sınıfa taşımayı düşünebiliriz.

Özet Olarak

Bu yazımızda ASP.NET MVC web uygulamasının çeşitli bölümlerini ele aldık. ASP.NET Routing'in, gelen tarayıcı isteklerini nasıl belirli controller eylemlerine eşleştirdiğini öğrendik. Controller'ların da nasıl view'ları yönettiğini gördük. Son olarak da model'ların, uygulamanın business, validation ve database erişim mantığını nasıl içerdiğini öğrendik.

Bir sonraki yazıda görüşmek üzere..

Kaynaklar: ASP.NET, Stackoverflow.com

Hiç yorum yok:

Yorum Gönder