![]() | |||||||||
WebMethod'ları Kullanarak AJAX Sayfalarını Daha da Hızlandırın | 11.05.2008 18:38:00 | ||||||||
| Kategori : ASP.NET Özet : Bu makalemizde ASP.NET AJAX uygulamalarında WebMethod'ları kullanarak web sayfalarının nasıl daha hızlı şekilde güncellenebileceğini inceleyeceğiz. WebMethod'ların hem sayfanın code-behind kısmında kullanımını, hem de web servisleri ile kullanımını detaylı şekilde ele alacağız. Yazımızın son kısmında ise sunucuda bir kontrolün HTML içeriğini nasıl oluşturacağımızı ve WebMethod ile sayfa içeriğine nasıl ekleyebileceğimizi inceleyeceğiz. | |||||||||
|
ASP.NET teknolojisi .NET Framework gibi güçlü bir alt yapıyı kullanmaktadır. Yine ASP.NET'in kendine has sayfa yapısı ve uygulama çalışma modeli de eski ASP ve PHP gibi teknolojilere göre oldukça önemli yenilikleri bulundurmaktadır. Tamamen nesne tabanlı (object oriented) ve olay tabanlı (event based) bir ortamda bulunduğumuz için web sayfalarımız da birer nesne olarak ele alınmakta ve çalıştırılan sayfaların sunucu tarafında belirli bir yaşam döngüsü bulunmaktadır. Bu yaşam döngüsü adım adım geçilerek sayfamızın HTML çıktısı üretilir. ASP.NET AJAX'ta bu sayfa yapısında çalışmaktadır. AJAX'ın kullanılmasındaki en büyük amaçlardan birisi sayfanın hızlı şekilde yenilenmesini sağlamaktadır. ASP.NET AJAX ile hazırlanan bir web sayfası normal bir ASP.NET sayfasından daha hızlı olacaktır. Fakat sayfanın sunucuda nesnesi oluşturulacak ve yaşam döngüsü çalışacaktır. Eğer sayfa nesnenin oluşturulmasını ve yaşam döngüsünün çalışmasını engelleyerek sayfamızı asenkron şekilde çalıştırırsak, çok daha hızlı şekilde güncellemeler yapılmasını sağlayabiliriz. İşte bu makalemizde ASP.NET AJAX kod kütüphanesinde hali hazır gelen yapılar sayesinde bu işlemi nasıl gerçekleştireceğimizi göreceğiz.
Bu işleme geçmeden önce "Neden böyle bir şeye ihtiyacımız var?" sorusunun cevabına
bakalım. Visual Studio 2005'te ASP.NET AJAX-Enabled Web Site projesi veya Visual
Studio 2008'de ASP.NET 3.5 projesi açarak UpdatePanel ile klasik bir AJAX örneği
hazırlayalım. Hazırlayacağımız örnek basit olarak butona tıklandıkça sunucuda çalıştırılan
bir kodun sonucunun etiket kontrolüne yazılmasını sağlayacak. Aşağıda hazırlayacağımız
sayfanın kodları yer almaktadır.
Default.aspx.cs
Görüldüğü gibi sayfanın yüklenmesi esnasında Label kontrolüne 16.05.2008 tarihine
ne kadar dakika kaldığını yazdırıyoruz. Butona tıkladığımızda Button1_Click
metodu çalışacak ve Label kontrolü asenkron olarak güncellenecektir. Fakat işin arka
planını incelediğimizde ASP.NET AJAX uygulamasında
asenkron güncelleme esnasında
sadece butonun Click olayına bağlanan metodun değil,
sayfanın tüm yaşam evrelerinin çalışacağını görebiliriz. Sayfanın Page_Load metoduna bir break-point ekleyip buton vasıtasıyla
güncelleme gerçekleştirirsek debug işlemi esnasında bu metoda girildiğini
görebiliriz.
Görüldüğü gibi sayfanın sunucu tarafında yeniden oluşması gerçekleşmektedir. Fakat sunucudan istemciye sadece UpdatePanel içeriğinin HTML kodları gönderilecektir; yani AJAX'ın temel prensibi olan sadece güncellenen bilgilerin sunucudan istemciye gönderilmesi burada gerçekleşecektir. Buna rağmen sayfanın sunucuda baştan oluşturulması performans açısından uygulamayı olumsuz yönde etkileyecektir. İlk bakışta "Neden sayfanın nesne örneği sunucuda tekrar oluşturuluyor?" sorusu akla gelse de mimari gereği ASP.NET sayfası için böyle bir işlemin gerçekleşmesi kaçınılmaz olacaktır. Diğer yandan UpdatePanel'in içeriğinin güncellenmesi sayfanın diğer olayları ile alakalı değilse; örneğin sunucuda basit olarak bir metot çalışacak ve sonucu sayfanın bir kısmını güncelleyecek ise sayfamızı daha da hızlandıracak yollar arayabiliriz. Yani sayfamızın çok daha hızlı güncellenmesini sağlayacak yolları aramak...
ASP.NET AJAX kod kütüphanesinde yer alan ve WebMethod adını verdiğimiz
metotları kullanarak ve istemci tarafında hazırlayacağımız basit JavaScript fonksiyonları
ile sayfayı sunucu tarafından tekrar oluşturmadan hızlıca güncelleyebiliriz. WebMethod
bir niteleyici (attribute) tipidir. Bildiğimiz gibi niteleyici tipleri sınıf (class)
ve yapı (struct) gibi tiplere, metot ve özellik (property) gibi tip üyelerine uygulanabilen
ve uygulandığı birime çalışma zamanı esnasında farklı şekilde davranmasını sağlayabilen
tiplerdir. WebMethod niteleyicisi de metotlara uygulanarak metodun çalışma zamanı
içinde kendisine gelen asenkton isteklere cevap verebilmesini sağlar. WebMethod'ları
ASP.NET AJAX sayfalarına iki farklı şekilde uygulanabilir:
Sayfanın code-behind kısmında yazılacak static metotlar WebMethod'ların en kolay şekilde uygulanacağı yoldur. Web servislerini metodumuzun (veya metotlarımızın) farklı sayfalar ve farklı uygulamalar tarafından çağrılmasını istediğimiz durumlarda kullanmamız daha doğru olacaktır. Eğer amacımız sadece bir sayfadaki belirli bir kısmı güncellemek olacaksa, static metotları kullanmak en iyi seçim olacaktır. Bu makalede her iki yolu kullanarak bu işlemi nasıl gerçekleştireceğimizi göreceğiz.
ASP.NET AJAX ile gelen ScriptManager kontrolü sayfamıza AJAX ile ilgili JavaScript kod kütüphanelerinin eklenmesini ve sayfadaki AJAX kontrollerinin hem diğer sunucu kontrolleriyle, hem de tarayıcılarla uyumlu şekilde çalışmasını sağlıyordu. AJAX destekli sayfamızda static metot kullanacak olursak UpdatePanel kontrolü olmadan da kısmi güncelleme işlemleri gerçekleştirebiliriz. Burada bahsedilen metodu çalıştırmak için sayfanın nesnesine ihtiyacımız olmayacaktır; zira gitmeye çalıştığımız yerde burasıdır. Sayfa çalıştığında sunucu tarafında sayfa nesnesi oluşturulur ve gerek olmasa dahi sayfanın Init, Load gibi olayları çalışır. Bildiğimiz gibi bir sınıf içerisindeki static üyeleri (değişken, property, metot gibi) çağırmak için sınıfın nesne örneğine ihtiyacımız yoktur. Eğer static bir metot tanımlayabilirsek ve bu metodu da istemciden çağırabilirsek sayfanın nesne örneğini oluşturmadan, olaylarını tetiklemeden istenilen işlemi gerçekleştirebiliriz. Bu da yapılacak işlemin daha da hızlı olmasını sağlar. Burada tanımlayacağımız static metodun JavaScript fonksiyonları tarafından çağrılabilmesi için System.Web.Services isim alanı (namespace) altında yer alan WebMethods niteleyicisini (attribute) uygulaması gerekir. Makalemizin başında yaptığımız örneği UpdatePanel kontrolünü kullanmadan tekrar çalıştıralım. Aşağıda sayfamızın HTML ve code-behind kısmını oluşturan kodlarımız aşağıda yer almaktadır.
Default.aspx
Default.aspx.cs
Sayfamızdaki değişikliklere göz atacak olursak belki de en göze çarpıcı nokta sayfamızda
UpdatePanel veya başka bir ASP.NET sunucu kontrolü kullanmamış olmamızdır. WebMethod
çağırımları JavaScript fonksiyonları ile gerçekleşeceği için sayfa içerisindeki
HTML alanlarına yine JavaScript ile erişme şansımız olacaktır. Code-behind sayfasında
oluşturulan metodumuz geriye string tipinden değer dönen static
bir metottur. Makalemizin konusu olan anahtar kelime WebMethod
ise metot tanımlamasının bir üst satırına niteleyici olarak eklenmiştir. System.Web.Services
isim alanı altında yer alan bu sınıfı [ ] (köşeli parantezler)
ile metoda uyguluyoruz. Artık KalanDakika adındaki metoda PageMethods
adındaki JavaScript nesnesiyle erişebilir, asenkron olarak ürettiği değerleri sayfamızda
kullanabiliriz. Gerekli JavaScript fonksiyonlarını HTML kısmında <head> etiketi
içerisinde oluşturuyoruz. AsenkronMetotCagir asenkron çağırımı
başlatacak olan fonksiyondur. PageMethods ise ASP.NET AJAX'ın istemci tarafında
çalışan kütüphanesinde yer alan ve sunucudaki WebMethod'lara erişebilen bir nesnedir.
İstemci tarafından bu nesneye erişebilmek içinse sayfamızdaki ScriptManager
kontrolünün EnablePageMethods niteliğini true
olarak belirlemeli; yani sayfada PageMethods nesnesinin kullanımını etkinleştirmemiz
gerekmektedir. PageMethods.KalanDakika(IslemBitti) ifadesi
ile KalanDakika metodunu çağırıyoruz ve istek sona erdiğinde dönen
değerin IslemBitti adındaki fonksiyona iletileceğini belirtiyoruz.
Asenkron istek sona erdiğinde otomatik olarak IslemBitti fonksiyonu çağrılır ve
sunucuda çalışan metodun sonucu deger adındaki değişken ile metoda
aktarılır. Böylece sayfa içerisindeki herhangi bir HTML alanının içeriğini güncelleyebiliriz.
Görüldüğü gibi istemci tarafında oluşturacağımız çok basit iki JavaScript fonksiyonu ve sunucuda çalıştıracağımız static bir metot ile sayfamızda kısmi güncellemeler gerçekleştirebilmekteyiz. Makalemizin başında yaptığımız test işlemininde olduğu gibi Page_Load metoduna bir break-point ekleyerek butona tıklayacak olursak, Visual Studio'nun debug ekranına düşmediğini görürüz. Bu durum sayfanın nesne olarak sunucuda tekrar oluşturulmadığını ve doğal olarak ta sayfamızın daha da hızlı çalışacağının göstergesidir.
Bildiğimiz gibi web servisleri internet üzerinden belirli hizmetlerin başka web uygulamalarına açılmasını sağlar. Bir web servisinde oluşturacağımız WebMethod'ları kullanarakta yukarıdaki örnekte gördüğümüz şekilde sayfamızda kısmi güncellemeler gerçekleştirebiliriz. Kendi uygulamamızda oluşturacağımız web servisini kullanabileceğimiz gibi farklı bir uygulamadan hizmete açılmış bir web servisinden alınan bilgileri de (hava durumu, döviz bilgileri gibi) benzer şekilde projemizde kullanabiliriz.
Web servisi kullanımını incelemek için öncelikle projemize bir web servisi uygulaması
ekleyelim. Solution Explorer’da iken projemizin üzerine
sağ tıklayıp Add New Item seçeneğini seçelim. Açılan pencereden dosya tipi olarak Web Service’i
seçip dosyamızın adını da AskerService olarak belirleyelim. Projemize
bir tane AskerService.asmx dosyası eklenecektir ki bu bizim başka web sitelerine
de açabileceğimiz bir servis olacaktır. AskerService.asmx
dosyasının arka planda kullanacağı AskerService.cs adındaki bir dosya da
App_Code
klasörü altına yerleştirilecektir. Bu dosyada yer alan sınıf (class) ve metotlar
bizim sayfamızdan çağırım yapacağımız üyelerimiz olacaktır. Resimde Solution Explorer’dan
proje dosyalarının son hali görülmektedir.
Web servisini JavaScript fonksiyonundan asenkron olarak çağırabilmemiz için öncelikli olarak web servisi sınıfımızın System.Web.Script.Services isim alanı altında yer alan ScriptService niteleyicisini (attribute) uygulaması gerekmektedir. Servis içerisinde oluşturacağımız metotlar zaten varsayılan olarak WebMethod niteleyicisini uyguladığı için bu metodun içeriğini değiştirmemiz yeterli olacaktır. Aşağıda web servisimizin son halinin kodları yer almaktadır. App_Code/AskerService.cs
Web servisini sayfamızda kullanabilmek için öncelikli olarak ScriptManager kontrolüne bu servisi kaydetmemiz gerekecektir. ScriptManager'ın Scripts koleksiyonu kullanılacak harici JavaScript dosyalarını saklarken, Services koleksiyonu ise sayfada kullanılacak web servisleri ve WCF servislerini saklamaktadır. Bu senaryoda web servisi çağırımı yapılacağı ve sayfaya dahil olan bir metot çağrılmayacağı için ScriptManager'ın EnablePageMethods niteliğini true olarak belirlememize gerek yoktur. Bu doğrultuda PageMethods kullanılmayacağına göre asenkron çağırımda bulunan JavaScript fonksiyonunda da PageMethods yerine web servisinin adı üzerinden metot çağrılacaktır. Aşağıda Default.aspx sayfasını son halinin kodları yer almaktadır. Default.aspx
Yapılan değişikliklerden sonra sayfamızı çalıştırdığımızda aynı sonucu elde edeceğimizi
görebiliriz. Sayfamız
çalıştığında aşağıdaki gibi bir sonuç alırız.
Görüldüğü gibi örneklerde sayfa içerisinde oluşturduğumuz static metotların ve web servisi içerisindeki metotların kullanımı aynı amaca hizmet etmektedir. Burada yapılacak seçim tamamen verilen hizmetin birden fazla uygulamadan veya sayfadan kullanılıp kullanılmayacağına bağlıdır. Yukarıda incelediğimiz örneklerde sunucuda oluşturulmuş ve geriye string tipinden değerler döndüren basit metotları kullandık. Bu metotlar sayfamızın daha hızlı çalışmasını sağlıyor olsa da, klasik ASP.NET AJAX uygulamalarında kolaylıkla yapabildiğimiz bir çok kompleks işlemi burada yapmamız biraz zor gibi... Özellikle bu tip senaryolarda çağrılan metodun çıktısını GridView, DetailsView, Calendar gibi kontroller üzerinde kullanmamız pek mümkün olmayacaktır. Peki metodun geri dönüş tipini bahsettiğimiz kontrollerin üreteceği HTML çıktı olarak belirlersek bu ihtiyacı giderebilir miyiz? Makalemizin son kısmında da WebMethod'ların geri dönüş değerini sunucuda üretilecek bir kontrolün HTML çıktısı olarak nasıl belirleyebileceğimizi inceliyoruz.
ASP.NET uygulamalarında kullandığımız tüm kontroller HTML çıktılara dönüştürülmekte ve sayfanın HTML kodları içerisine yerleştirilmektedir. Basit olarak bir Label kontrolü sunucuda çalıştırıldığında <span> elementine dönüştürülürken, GridView gibi bir kontrol ise tablo (<table> elementi) ve tablo içerisindeki elementlere dönüştürülür. Web uygulamalarında kullandığımız tüm sunucu kontrolleri WebControl sınıfından, WebControl sınıfı ise Control isimli bir sınıftan türetilmektedir. Control sınıfında yer alan RenderControl metodu sunucuda oluşturulan kontrolün HTML çıktısını elde edebilmemizi sağlar. Control sınıfında yer alan bu metot dolayısıyla tüm sunucu kontrollerinin de sahip olduğu bir üyedir ve programatik olarak oluşturulacak bir sunucu kontrolünün RenderControl metodu ile HTML çıktısına ulaşılabilir. RenderControl metodunu kullanarak WebMethod'lar içerisinde kompleks kontroller üretebilir ve çıktısını metodun geri dönüş tipi olarak belirleyebiliriz. Böylece WebMethod'larla sayfamızı daha hızlı güncelleyebilme şansına sahip olduğumuz gibi, bu tip kontrollerin çıktılarını da sayfamıza asenkron güncellemelerle ekleyebiliriz. RenderControl metodu çalıştığında string bir çıktıyı direkt oluşturmamak, parametre olarak alacağı HtmlTextWriter tipinden bir nesneye HTML çıktıyı sunmaktadır. Dilerseniz karşımıza çıkabilecek bir senaryoyu makalemizde gerçekleyerek RenderControl metodunu nasıl WebMethod'larda kullanabileceğimizi inceleyelim. Veritabanımızda bulunan kategorilere ait ürünlerimiz bulunduğunu düşünelim. Bir DropDownList kontrolünde kategorileri listelemek ve listeden seçilen değere göre de GridView kontrolüne o kategoride bulunan ürünleri doldurmak istiyoruz. Sayfamıza eklediğimiz <select> (ASP.NET kontrollerinden DropDownList'in dönüşeceği element) elementini runat="server" ifadesiyle sunucuda ele alınabilir hale getirip, üzerinde seçim gerçekleştiğinde de istemcideki JavaScript fonksiyonumuzu çağırıyoruz. Çağrılacak WebMethod'da ise GridView kontrolünü oluşturup çıktısını sayfamıza asenkron olarak göndereceğiz. Aşağıda sayfamızın kodları yer almaktadır.
Default.aspx
Default.aspx.cs
Kodların kalabalık olması ilk bakışta işlemin karmaşık olduğunu akla getirebilir,
fakat çoğu işlemin veritabanından verilerin getirilmesi ile ilgili olduğu görülmektedir.
Urunler metodunun son satırlarına baktığımızda RenderControl metodunun oluşacak
çıktıyı HtmlTextWriter nesnesine, HtmlTextWriter nesnesi de kendi
içerisinde (InnerWriter özelliğinde) oluşan HTML çıktıyı StringWriter
nesnesine aktardığı anlaşılmaktadır. sw adındaki StringWriter nesnesinin
çıktısı da stringe dönüştürülerek metottan geriye döndürülmektedir. Sayfayı çalıştırdığımızda
DropDownList'ten yapacağımız seçimler sonrasında sonuc adındaki
div alanına GridView kontrolünün içeriğine asenkron olarak yükleneceği görülecektir.
Aşağıda sayfamızın çıktısı yer almaktadır.
Bu makalemizde ASP.NET AJAX sayfalarımızı WebMethod'lar ile nasıl daha hızlı sunabileceğimizin detaylı şekilde incelemiş olduk. Web uygulamalarının en önemli yönlerinden biri uygulamanın performası ve kullanıcının sayfaları hızlı şekilde gezebilmesidir. AJAX sayfalarını bu şekilde istemciye daha hızlı şekilde sunmak uygulamamız için önemli bir artı olacaktır. Bir başka makalede görüşmek dileğiyle.
Uğur UMUTLUOĞLU | |||||||||
Yazgelistir.com | |||||||||