ASP.NET MVC’yi anlamak için “WebForms”un ne olduğunu bilmek ve anlamış olmak gerekir. Bundan dolayı öncelikle biraz webformsa değinmek istiyorum.

Klasik ASP ile web geliştirenlerin .NET’e geçişi ile birlikte hayatlarına giren ilk şey “WebForms” olmuştur. Asp.Net programlamada başlangıç seviyesinde, mantığı tam olarak anlaşılamasa da, giriş seviyesi bir programcı dahi webformsu aktif olarak kullanır. Basit bir şekilde anlatmak gerekirse; bir aspx sayfasında bulunan asp.net server kontrollerine (textbox, dropdown, vb.) girilen verilerin programatik olarak işlenmesi için koda gönderilmesini sağlayan sayfa yapısına webforms diyebiliriz. Bu işlemi gerçekleştirmek için bize yardımcı olan mekanizmalar vardır. Postback ve Viewstate bunların başında gelir. Postback bu kontrollerdeki veriyi koda gönderme eylemine verilen isimdir. Viewstate ise postback öncesinde bu formlara girilmiş olan verilerin postback sonrasında tekrar kullanılabilir olmasını sağlayan mekanizmadır. Örneğin aşağıdaki gibi basit bir aspx sayfamız olsun.

Bu sayfadaki textbox’a bir yazı girip, checkbox’a tick atıp, butona tıklandığında textboxa girilen yazıyı sayfanın başına yazdırdığımızı düşünelim. Bunun için Visual Studio’da designerdaki butona çift tıklarız ve bizi code behind’a yönlendirir ve bu buton için bir event oluşturur. Bu eventin içine Response.Write(TextBox1.Text) benzeri bir kod yazarız. Daha sonra bu sayfayı çalıştırıp, butona tıkladığımızda sayfa bir kere refresh yapar (kendini tazeler) ve tekrar aynı sayfayı açar.

Textboxa girdiğimiz yazı, olması gerektiği gibi sayfanın başında gözükür. Ayrıca textbox’ın içinde yazı hala duruyordur ve checkbox da ticklenmiş durumdadır. Oysa sayfa kendini refresh etmiştir. Refresh eyleminin aynı sayfayı tekrar açtığını düşünürsek (adres çubuğundaki url değişmez), o sayfaya ilk defa girildiğinde olduğu gibi boş bir şekilde açılması beklenir. Bunu test etmek için sayfa boş iken textboxa bir yazı girin checkbox’a tick atın ve daha sonra browser’ınızın refresh butonuna basın. Bunu yaptığınızda göreceğiniz üzere textbox’taki yazı kaybolur ve checkbox boşalır. Sayfa ilk açıldığı şekline geri döner. Fakat butona tıklayıp sayfayı refresh ettirdiğinizde her şey yerinde duruyordur. İşte buradaki butona tıklama eylemi sonucu sayfanın refresh yapmasına postback denir. Bu refresh sonunda textbox’a girdiğimiz yazının durması ve checkbox’ın tickli kalmasını da viewstate mekanizması sağlar. Postback ile textbox’taki yazı koda gönderilir. Kod bu yazıyı alır, işler, sayfanın başına yazar ve tüm bunlar refresh anında olur. Refresh tamamlandığında her şey istediğimiz gibidir. İşte tüm bu olaylar zincirinin ve mekanizmaların tamamına “WebForms” denir.

Basit anlamda webformsun işleyiş şekli ve yapısı böyledir. Fakat Asp.Net MVC’de yapı bu şekilde değildir. MVC’de postback, viewstate, codebehind, server kontrolleri (textbox, checkbox) ve bu kontollerin eventleri yoktur. “Olamaz! Bunlar olmadan sayfa nasıl çalışır!” dediğinizi duyar gibiyim. Evet alışık olduğumuz bu yapı Asp.Net MVC’de farklı bir şekildedir. Peki neden farklı? Bu yapı gayet güzel çalışıyor. Bunu neden farklı bir yapıda kullanma ihtiyacı duyuyum ki? Benzeri soruların cevabı ise; webformsun bu yapısının bazı dezavantajları olduğu ve bu dezavantajların mvc’de olmamasıdır. Bazı web projelerinde webformsun birazdan bahsedeceğim dezavantajları tahammül edilemeyecek derecelere ulaştığı için Asp.Net MVC, WebForms’a alternatif olarak geliştirilmiştir. Fakat bu MVC’nin daha iyi, webformsun daha kötü olduğu veya mvc’nin webformsun yerine geçeceği gibi bir anlam taşımamaktadır. Projenin türüne göre tercih edilebilecek birer alternatiftirler.

Şimdi gelelim webformsun dezavantajlarına. Öncelikle bu dezavantajlardan bahsedeceğim. Daha sonra mvc’nin bunları nasıl çözdüğünü elimden geldiğince anlatmaya çalışacağım. Bu çözümleri incelerken mvc’yi de anlamaya çalışmış olacağız.

1.) Viewstate, sayfadaki server kontrollerinin durumunu hafızasında tutmak için client tarafında gizlenmiş bir hidden input oluşturur. Bu input webforms ile geliştirilmiş her aspx sayfasında vardır. Web browser’ınızda herhangi bir aspx sayfasının kaynağına baktığınızda “__VIEWSTATE” isimli bu inputu görebilirsiniz.

 

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLT
c1MDU0Nzg2MWQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFCUNoZWNrQm94
MX5gT8EYawMsUp79Tkt2Gz2HkU/i"
/>

 

Gerçek hayat uygulamalarında bu inputun value’su o kadar büyür ki boyutu yüzlerce kilobyte’ı bulur. Bu da client tarafında gereksiz bir yavaşlığa neden olur. Server tarafında ise bu viewstate değerini oluşturmak ekstra iş yükü demektir. Hele bir de günde milyonlarca kez ziyaret edilen bir web projesi ise, bu yavaşlık ve iş yükü tahammül edilemez olur. Yukarıda bahsettiğim gibi Asp.Net MVC’de viewstate yoktur. Bundan dolayı mvc’de böyle bir yavaşlık söz konusu değildir. Peki mvc’de viewstate yoksa sayfadaki kontollerinin durumunu nasıl hafızada tutacağız? Merak etmeyin Asp.Net MVC’de bu işi gören bir mekanizma var ve bu mekanizma ne client’a ne de server’a ekstra iş yükü getiriyor. Bu işi http’nin yapısına uygun bir şekilde çok daha doğal yollar ile gerçekleştiriyor.

2.) Webforms’da sayfa yaşam döngüsü (page life cycle) vardır. Yukarıdaki örnekte kısaca bahsettiğim üzere sayfanın çalışma anında bir tür olaylar zinciri gerçekleşir. Butona tıklandığında o butonun click eventi tetiklenir, daha sonra postback başlar, veriler koda gider, kod veriyi işler ve tekrar sayfaya gönderir. Basit bir uygulamada kısa ve hızlı bir döngüdür bu. Fakat kompleks uygulamalarda maalesef bu kadar hızlı olmamaktadır. Hele bir de o sayfada onlarca server kontrolü bir aradaysa çok daha uzun sürer. Eventler havada uçuşur. Önce hangisi tetiklendi? Sonra hangisi tetiklenecek? Şimdi ne olacak? Aynı anda birden fazla eventi nasıl tetiklerim? Bir sürü karmaşa ortaya çıkar. Codebehind event metotlarıyla dolar. Hangi event hangi kontrolündü karıştırırsınız. Designera geri dönüp o kontrole çift tıklayıp codebehind’taki onun eventine gitmek gibi bir zahmete katlanırsınız. İnanın bana büyük web uygulamalarında bu sizi çığırından çıkarır. Asp.Net MVC’de bu eventlerle boğuşmak zorunda değilsinizdir. MVC sizi Page_Load eventindeki “Page.IsPostBack değilse” kontrolünü yapma derdinden de kurtarır.

3.) Webforms’da asp.net server kontolleri otomatik olarak html elementlerine dönüştürülür. Siz o kontrolün html’ine müdahale edemezsiniz. Yaptığımızın işin web sitesi geliştirmek olduğunu düşünürsek web’in temeli olan html’de tam kontrol sahibi olamamamız hoş bir durum değildir. Özellikle standartlara uyumlu sayfa tasarlama gibi bir kaygımız varsa (ki olmalıdır) server kontolleri size bu esnekliği sağlamamaktadır. Server kontrollerinin css’lerinde de tam kontrol sahibi değilizdir. Ayrıca server kontolleri bazen gereksiz html kodları da üretebilmektedir. MVC’de server kontrolleri olmadığı için standart html elementlerini kullanırız. Bu da size sayfanızın html’inde tam kontrol verir.

4.) Büyük web projelerinde N-Layer, N-Tier, vb. metodolojileri kullanarak programınızın mantık (logic) kısmı ile tasarım (presentation) kısmını birbirinden ayırırsınız. Böylece projenin yazılımsal olarak yönetimi daha kolay olur. Webformsdaki codebehind yapısı aslında bu metodolojilere ters düşmektedir. Çünkü presentation layer’ınızda yoğun olarak kod yazarsınız. Bir çok mantıksal işlemi aspx sayfasına bağlı codebehind’da gerçekleştirirsiniz. MVC’de tasarım ile mantık çok iyi bir şekilde ayrılmıştır. Tasarımı bir kere bitirdiğinizde tekrar tekrar oraya geri dönmek zorunda kalmazsınız. Artık işiniz daha çok mantıksal işlemlerdir, bu katmana yoğunlaşırsınız.

Temel olarak bu dört dezavantajın yanında diğer bazı dezavantajlar da mevcuttur. Fakat konuyu uzatmamak için onlara bu yazıda değinmeyeceğim. Yukarıdaki dezavantajlar ele alındığında büyük bir web projesi için Asp.Net MVC’nin tercih edilmesi akıllı bir yol olarak gözüküyor değil mi? Peki mvc sadece bu dezavantajları gideren bir yapı mı? Kesinlikle hayır. Asp.Net MVC’nin bize kazandırdığı daha birçok yeni ve kullanışlı özellik de mevcut. Bunlardan en önemlisinin “Routing” mekanizması olduğunu söyleyebilirim. Routing, bir aspx sayfasına URL üzerinden gelen çağrıları anlamlı hale getirdikten sonra işlenmesi için mantıksal yapının olduğun koda (logic) yönlendirme işini gerçekleştiren mekanizmadır. Örneğin “www.abc.com/kategori/altkategori/sayfa” şeklinde bir url olduğunu düşünelim. Bu url’i web browserda adres çubuğuna girip enter’a basıldığı an asp.net mvc’de ilk olarak routing mekanizması çalışır. Routing bu url’deki ana domainden (www.abc.com) sonra gelen “/” ile ayrılmış kısımları (kategori, altkategori, sayfa) parçalar, daha sonra mantıksal kodun (logic) içerisinde bunlara uygun olan metotları bulup oraya yönlendirir. Logic’de gerekli işlemler yapıldıktan (veritabanından verilerin çekilmesi, işlenmesi, vb.) sonra tekrar Routing devreye girer ve işlenmiş bu verilerin gösterileceği uygun aspx sayfasını bulup oraya yönlendirir. Routing'in sağladığı bu yapı sayesinde url’ler çok daha anlamlı hale gelir. Böyle olunca da arama motorları bu url’leri daha iyi indeksler ve siteniz üst sıralarda çıkar. Webforms’da bu yapıyı oluşturabilmek için ekstra zahmete girersiniz. Webforms’da url rewrite denilen teknik ile bu işlem gerçekleştirebilmektedir fakat mvc’de olduğu kadar hızlı ve doğal değildir.

Routing’i anlatırken aslında Asp.Net MVC’yi anlamaya bir giriş yapmış olduk. Genel itibariyle mvc’nin çalışma mantığı routing’deki bu yapı üzerine kuruludur. URL’den bir istek gelir, o isteğe uygun metot (Controller) bulunur, bu metod aldığı bu isteği yerine getirmek için uygun business logic metotlarını (Model) çalıştırır ve son olarak buradan dönen anlamlı veriler uygun aspx sayfalarına (View) yönlendirilir.
Burada parantez içerisinde belirttiğim “Model”, “View”, “Controller”lar da bir araya gelip MVC’yi oluşturur.

Bu yazıda Asp.Net MVC’ye detaylı sayılabilecek bir giriş yapmış olduk. Planım bunu bir yazı dizisine çevirip MVC’nin tamamını detaylı bir şekilde incelemek ve sizlerle birlikte örnek bir uygulama geliştirmek. Umarım bu planımı gerçekleştirebilirim. Bir sonraki yazıda Model-View-Controller yapısının nasıl çalıştığına göz atıp, örnek bir asp.net mvc projesi oluşturarak bunu pekiştiririz. Şimdilik bu kadar. Diğer yazıda görüşmek üzere.