Ana Sayfa | English Blog | Seminer TV | Dil Cookie Sil  Blog'u Mail ile takip et!  
Daron Yöndem - ASP.NET 3.5
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  | 
 Wednesday, April 29, 2009

Bu hafta sonu için sizlere iki ayrı etkinlik duyurum var. Her ikisi de Ankara'da! Cumartesi günü SQL Kampı etkinliğimizin Ankara ayağını yapıyoruz, Pazar günü ise benim de konuşmacı olacağım NedirTV'nin 3. yıldönümü kutlama etkinliği olacak. Her ikisinin de planını aşağıda bulabilirsiniz.

02.05.2009 / SQL Kampı
09.30-10.30 Silverlight 3.0 ve İş Uygulamaları - Daron Yöndem
10.30-12.00 SQL 2008 Platform ve Development Yenilikleri - Tarık Kranda
13.00-15.00 Index Strategies and Performance Tunning - Pamir Erdem
15.30-17.00 IIS 7 üzerinde PHP ve MSSQL - Muammer Benzeş

03.05.2009 / NedirTV Günü
09:45-11.15 ASP.NET MVC - Uğur Umutluoğlu
11:30-13.00 What is SharePoint? - Burak Batur
14:00-15.30 WCF 4.0 & WF 4.0 - Burak Selim Şenyurt
15:30-16.30 WPF ve MultiTouch Programlama – Daron Yöndem

Her iki etkinlik de Bilkent Üniversitesi'nde gerçekleştirilecek. Merkez Kampüs Rektörlük Binası Mithat Çoruh Amfi Salonu'nda olacağız. Hepinizi bekliyoruz!

Not: Etkinlik sonrası "Haberimiz olsa gelirdik" diyen her birey saçımdan bir tel daha kopartıp üzerinde tepinmeme neden oluyor :) O nedenle sizden ricam etrafınızda bu etkinlik ile ilgilenebilecek herkesi haberdar etmeniz. Görüşmek üzere...

Wednesday, April 29, 2009 1:17:35 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   ASP.NET 3.5 | MultiTouch | Silverlight 3.0 | SQL Server 2008 | WPF  | 
 Saturday, March 14, 2009

Bugün tam günlük NedirTv.com etkinliğindeydik. NedirTv'nin üçüncü yılını kutladığımız bu etkinlikte ilk olarak Windows 7 oturumumuz oldu. Ayrıca ben de İstanbul'da ilk olarak MultiPoint programlama anlattım. Sonrasında sevgili Uğur ASP.NET 3.5, Burak Selim C# ve Pamir Erdem ise SQL 2008 yenilikleri ile hızlı bir marator gerçekleştirdik.

MultiPoint Semineri, İstanbul
MultiPoint Semineri, İstanbul

Etkinlik epey heyecanlı geçti, özellikle hediyelerimiz ve Windows 7 Beta'lar ve "Random gerçekten Random mıdır?" tartışması unutulmazlar arasında :) olsa gerek. Buradan sevgili Uğur'a NedirTV'deki emeği ve sosyal topluluk olarak INETA tarafına katkısı için çok teşekkür ediyorum. Diğer yandan tüm diğer NedirTV editörleri ve konuşmacılarımıza da çok teşekkürler ve tabi ki katılımcılarımız :) sizleri de unutamam. Hepinize sonsuz teşekkürler, umarım faydalı olmuştur.

NedirTV 3. Yıl Dönümü, İstanbul
NedirTV 3. Yıl Dönümü, İstanbul

Etkinlikte çekilen tüm fotoğrafları tam çözünürlüklü halleri ile aşağıdaki adresten bilgisayarınıza indirebilirsiniz ;)

http://cid-8eca4439fd9a640f.skydrive.live.com/browse.aspx/NedirTV%203.%20Yıl%20Dönümü%20İstanbul%20Etkinliği

Saturday, March 14, 2009 12:26:48 AM (GTB Standard Time, UTC+02:00)  #    Comments [4]   ASP.NET 3.5 | MultiPoint SDK | SQL Server 2008 | Windows 7  | 
 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  | 
 Sunday, February 22, 2009

Son iki gündür sevgili Uğur Umutluoğlu ile Ankara, Bilkent Üniversitesi'ndeyiz. Toplam iki gün süren ve 6 oturumdan oluşan bir seri ile birçok konuya değindik. WPF, WCF, LINQ, C# 3.0, Silverlight, ASP.NET 3.5 SP1 başlıklarına sahip oturumların hepsinde de muhteşem ilgili bir kitle bulunduğunu itiraf etmeliyiz.

Bilkent Üniversitesi, Ankara, Silverlight Oturumum
Bilkent Üniversitesi, Ankara, Silverlight Oturumum

Oturumlarımızdan birini de LAB çalışması olarak gerçekleştirdik ve Silverlight seminerinde öğrendiklerimizi Silverlight ile bir oyun geliştirerek pekiştirdik. LAB çalışması benim neredeyse etkinlik içerisinde en sevdiğim bölüm oldu. "Üretmenin" zevkini herkesin gözlerinde gördüm.

Silverlight Lab Çalışması
Silverlight Lab Çalışması

Buradan teşekkür etmem gereken o kadar çok kişi var ki :) Sevgili MSP'lerimiz Ali Uğur Çakmak, Alper Özçetin'a çok teşekkürler. Ayrıca BTS ve ACM'deki herkese teşekkürler. Süper bir hafta sonu geçirdim, "dayının yeri"ni hala unutamıyorum :)

Sunday, February 22, 2009 10:29:12 PM (GTB Standard Time, UTC+02:00)  #    Comments [6]   ASP.NET 3.5 | LINQ | Silverlight 2.0 | WCF | 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  | 
 Sunday, January 11, 2009

Bu hafta sonu İzmir'deydik. Daha önce sizlere duyurmuş olduğum INETA EGE HIT etkinliğini Dokuz Eylül Üniversitesi'nde gerçekleştirdik. Katılımcı profili gerçekten muhteşemdi, hem Cumartesi hem de Pazar günü en ufak bir oturumu bile kaçırmayın daimi bir kitlemiz vardı :) Benim için çok eğlenceli ve sevindirici oldu diyebilirim. Her oturumda aldığım tepkiler çok güzeldi.

INETA Ege Hit başlangıcı.
INETA Ege Hit başlangıcı.

Her zamanki gibi iki de anekdot yarattık; birincisi benim gülen surat çizimimi görüp animasyon olarak "yağmur yağsın ve şemsiye açılsın" diyen arkadaşımızdı :) Dikkatinizi çekerim gülen suratın ne yağmur ne de şemsiye ile alakası yok ayrıca İzmir'de yağmur falan da yapmıyordu :) Her neyse... İkinci anekdot ise buradan paylaşamayacağım hatta sanırım ömür boyu hiç paylaşamayacağım bir şey :) Üzgünüm...

INETA Ege Hit sonu...
INETA Ege Hit sonu...

Organizasyondaki katkılarından dolayı sevgili İzmir MSP'lerimize buradan ÇOK teşekkür ediyorum. Sevgili Buğra, Murat, Gülşah ve Okan'a çok teşekkürler. Etkinlik boyunca çekilen resimlerin orijinal boyutlu hallerine buradan ulaşabilirsiniz. Ayrıca tüm oturumlardaki örneklere ait kodları da aşağıdaki linkten bilgisayarınıza indirebilirsiniz.

Oturumlardaki örnek projeler - 11012009.rar (5,11 MB)

Sunday, January 11, 2009 3:39:22 PM (GTB Standard Time, UTC+02:00)  #    Comments [7]   ASP.NET 3.5 | LINQ | Silverlight 2.0 | WPF  | 
 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  | 
 Monday, December 01, 2008

Son üç gündür Isparta, Süleyman Demirel Üniversitesi'ndeydim. Cumartesi günü başladığımız INETA Boot Camp Isparta etkinliğimizde LINQ ve WCF konularını işledik. Pazar günü Microsoft'un Oyun Turu'nun da Isparta ayağını kampımıza ekleyerek dün de bahsettiğim gibi SL 2.0 ile ve XNA ile Oyun Programlama konularını inceledik. Son günümüz olan Pazartesi günü de ASP.NET Dynamic Data Web Site yapılarını göz attık sonra "Silverlight 2.0 ile Data Uygulamaları" ve "WPF" oturumlarımızı tamamladık. Böylece dolu dolu bir üç gün geçirdik.

Isparta, Süleyman Demirel Üniversitesi, INETA Boot Camp
Isparta, Süleyman Demirel Üniversitesi, INETA Boot Camp

Etkinliklere katılan hem konuşmacı arkadaşlarıma hem de sevgili öğrenci kardeşlerime çok teşekkür ediyorum. Geçen öğretim yılında da Süleyman Demirel Üniversitesi'nde gittiğimde blogumda yazmıştım hatta dün de yazmışım :) SDÜ'nün yeri benim için çok ayrı. Yukarıda resimde gördüğünüz tüm öğrencilerin Silverlight ve WPF konulu ödevleri var. Hepsi giriş seviyesini çoktan geçmiş durumda. Bu duruma tabi ki öğretim görevlilerinin katkısı çok büyük.

Özellikle organizasyonun gerçekleşmesindeki katkılarından dolayı sevgili Eğitim Görevlisi dostum Mehmet Albayrak'a çok teşekkür ediyorum.

Son gün yaptığımız bazı örnekleri toparlayıp bir poşete koydum :) aşağıdaki linkten indirebilirsiniz.

Örneklere ait kaynak dosyalar - 01122008_2.rar (2,81 MB)

Monday, December 01, 2008 2:57:22 PM (GTB Standard Time, UTC+02:00)  #    Comments [3]   ASP.NET 3.5 | Expression Blend | LINQ | Silverlight 2.0 | WCF | WPF  | 
 Saturday, November 08, 2008

Bugün Afyon Kocatepe Üniversitesi'ndeydim. Sabahtan başlayarak Silverlight 2.0, WPF, LINQ ve ASP.NET Dynamic Data konularına değinerek zevkli bir gün geçirdik. Günün sonunda tadına vardığım Afyon kaymağı ve ekmek kadayıfı süper ikilisi aslında neredeyse oturumları uzatarak Afyon'a yerleşmeme bile sebep olacaktı :)

Kocatepe Üniversitesi 2. Bilişim Günleri oturumlarımın sonundan bir kare.
Kocatepe Üniversitesi 2. Bilişim Günleri oturumlarımın sonundan bir kare.

Aktivite boyunca yardımlarından dolayı teşekkür etmem gereken o kadar çok kişi var ki kesinlikle atladığım kardeşlerim olacaktır. İster üniversite dahilinde öğretim görevlisi olsun ister öğrenci olsun aktivitede emeği geçen herkese ve tabi ki tüm katılımcılara çok teşekkürler. Muhteşem bir aktiviteydi. Organizasyondaki katkılarından dolayı sevgili Sadık Oral'a özellikle teşekkür ediyorum.

Herkese çok teşekkürler.
Rektör Yardımcısı Prof. Dr. Belkıs Özkara - Daron Yöndem

Saturday, November 08, 2008 1:26:58 PM (GTB Standard Time, UTC+02:00)  #    Comments [5]   ASP.NET 3.5 | LINQ | Silverlight 2.0 | WPF  | 
 Thursday, November 06, 2008

Bugün Microsoft Ankara ofisinde hosting sağlayıcılara yönelik bir eğitimimiz var. IIS 7 ile beraber gelen yeni özelliklerin yanı sıra ASP.NET 3.5 ve programcıların dertlerinden bahsettik. Tabi hosting sağlayıcılarımız da dertleri vardı. Programcıların hatalarından kaynaklanan bazı sorunlar yüzünden hosting sağlayıcıların müşteri ile uğraşmak zorunda kaldığı derdi de aslında bir gerçek :)

Microsoft Ankara hosting sağlayıcılar eğitimi.
Microsoft Ankara hosting sağlayıcılar eğitimi.

Eğitimde kullandığım sunumu aşağıdan indirebilirsiniz.

IIS 7 ve ASP.NET 3.5 sunumu - 09112008_1.pptx (206,66 KB)

Hepinize kolay gelsin.

Thursday, November 06, 2008 4:39:27 PM (GTB Standard Time, UTC+02:00)  #    Comments [3]   ASP.NET 3.5 | Eğitimler | IIS 7.0  | 
 Tuesday, October 21, 2008

.NET 3.5 SP1 ile beraber gelen Dynamic Data Web Site yapısı ile beraber doğrudan sadece veri üzerinde çalışan web uygulamaları yazmanın gerçekten kolaylaştığını itiraf edebiliriz. Fakat her yeni araç gibi Dynamic Data ile beraber de istediklerimizi yapabilmek için kendine özgü özelleştirme kurallarını bilmemiz gerek. Bu yazıda elimizde hazır bir Dynamic Data Web Site olacak ve bu web sitesinde gösterilen veritabanındaki bazı tablolardaki bazı sütunların gösterim esnasındaki özelleştirmelerine değineceğiz. Cevaplayacağımız sorulardan bazıları şunlar olacak;

  • Belirli bir tablonun sadece bir sütununun görünmemesini nasıl sağlarım?
  • İstediğim bir sütunun istediğim değerleri almasını nasıl sağlarım?

Yazımızda kullanacağımız örnek siteyi yaratmak için buradaki yazıyı inceleyebilirsiniz.

MetaData üzerinden ayarlamalar...

Dynamic Data yapısına baktığımızda olabildiğince her şeyin otomatik ilerlediğini görüyoruz. Örneğin bir tablonun içerisindeki tüm sütunlar otomatik olarak söz konusu tablo ile beraber tüm sayfalarda düzenlenebilir şekilde gözükmeye başlıyor. Sütunlarla ilgili tek tek ayar yapmanın tek yolu söz konusu sütunlara ek MetaData bilgileri vermek. Peki bizim sütunlarımızı kodumuzla kim tanımlıyor?

Biz projemizde LINQ2SQL kullanarak ilerlediğimiz için veritabanındaki her bir nesneyi tanımlayan objeler LINQ'e ait DBML'in arkasında tanımlanmış durumda. Bir DBML dosyasının arkasına baktığınızda designer.vb veya designer.cs uzantılı dosyalar görebilirsiniz. Bu dosyalar içerisinde veritabanındaki tüm nesnelerin birer kopyası .NET nesneleri olarak yaratılmıştır.

[VB]

<Table(Name:="dbo.Urunler")>  _

Partial Public Class Urunler

    Implements System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged

[C#]

[Table(Name="dbo.Urunler")]

public partial class Urunler : INotifyPropertyChanging, INotifyPropertyChanged

{

Yukarıda gördüğünüz şekilde başlayan Urunler adındaki Class DBML dosyasının arkasında duruyor ve bizim her bir ürünümüzü tanımlıyor. Maalesef bu designer dosyalarında değişiklik yapamıyoruz. Aslında değişiklik yapabilirsiniz fakat DBML dosyasında Visual Studio arayüzündeki tasarım araçları ile yaptığınız her işlem bu dosyaların sistem tarafından tekrar yaratılmasına neden olacağı için kullanıcı tarafından yapılan tüm kod değişiklikleri kaybolacaktır. Peki bu durumu nasıl çözeceğiz? Dikkat ettiyseniz tüm bu sınıflar Partial olarak tanımlanmıştır yani bir başka bir dosyada tekrar Partial birer sınıf yaratarak işlemlerimize devam edebiliriz. Bu durumda buyurun yeni bir VB/CS dosyası oluşturalım ve Partial olarak aynı sınıftan bir adet daha yaratalım.

[VB]

<ComponentModel.DataAnnotations.MetadataType(GetType(UrunlerMeta))> _

Partial Public Class Urunler

 

End Class

[C#]

[System.ComponentModel.DataAnnotations.MetadataType(typeof(UrunlerMeta))]

public partial class Urunler

{

 

}

Yukarıdaki koda baktığınızda özellikle en üstteki MedadataType işaretleri dikkatinizi çekecektir. Aslında bu da bir MetaData fakat maalesef bu şekilde Partial sınıflara doğrudan MetaData veremiyoruz. O nedenle başka bir sınıf yaratarak MetaData'ları orada tutacağız ve o sınıftan MedaData'ları bu tarafa aktaracağız. Kodumuz içerisinde UrunlerMeta olarak geçen obje aslında başka bir sınıfın adı.

[VB]

Public Class UrunlerMeta

 

    Private _Fiyati As Object

    <ComponentModel.DataAnnotations.Range(10, 20, errormessage:="Hata!")> _

    Public Property Fiyati() As Object

        Get

            Return _Fiyati

        End Get

        Set(ByVal value As Object)

            _Fiyati = value

        End Set

    End Property

 

End Class

[C#]

public class UrunlerMeta

{

    [System.ComponentModel.DataAnnotations.Range(10, 20, ErrorMessage = "Hata!")]

    public object Fiyati { get; set; }

}

UrunlerMeta sınıfı içerisinde sadece Fiyati adında bir Property var. Aslında ana Urunler sınıfındaki tüm Property'leri burada da tanımlayarak kullanabilirdik fakat şimdilik bize Fiyati Property'si yeterli. ComponentModel.DataAnnotations altından Range sınıfını kullanarak Fiyati değerinin 10 ile 20 arasında olmak zorunda olduğunu ve bu durumun sağlanmaması halinde de hata olarak "Hata!" yazısının gösterilmesi gerektiğini belirtiyoruz. Gelin bu kodun bir de web sitesindeki yansımasına göz atalım.

Range sınıfı ile yaptığımız ayarlamalar arayüzde kendini gösteriyor.
Range sınıfı ile yaptığımız ayarlamalar arayüzde kendini gösteriyor.

Başka neler yapabiliriz?

MetaData'lar üzerinden başka neler yapılabileceği ile ilgili çok sayıda farklı senaryo mevcut fakat en basit örnekleri inceleyebilmek için kabaca ComponentModel.DataAnnotations sınıfına göz atmak yeterli olacaktır. Örneğin aşağıdaki gibi bir kod istediğiniz bir kolonun web sitesinde gösterilmemesini sağlayabilir.

[VB]

<ComponentModel.DataAnnotations.ScaffoldColumn(False)> _

[C#]

[System.ComponentModel.DataAnnotations.ScaffoldColumn(false)]

Peki ya diğer seçenekler? Gelin hızlı bir tur atalım.

DisplayColumn

Bu özellik toplam en fazla üç parametre alabilir. Amacı tablolar arası ilişkilendirmelerde kullanıcının gördüğü metinleri değiştirmektir. Örneğin bizim projemizde ürünlere bağlı olan kategorilerin adları otomatik olarak her üründe gösteriliyor. Sistem aslında arka planda Kategoriler tablosunda ID(PK) kolonundan sonra karşılaştığı ilk String kolonu alarak göstermeye göre ayarlı. Oysa bazı durumlar FK'in bağlı olduğu tablodan alınması gereken ve gösterilecek olan metin çok daha ileride farklı bir sütunda olabilir. İşte DisplayColumn bunu ayarlıyor ve bir FK durumunda ana tablodan hangi sütunun bu üründe gösterilmesi gerektiğine karar veriyor. Bunun haricinde aldığı iki diğer parametrenin ilki hangi kolon üzerinden Sorting yapılabileceği ve üçüncü parametre ise Sorting işleminin ilk açılışında hangi yönde yapılacağı verisini taşıyor.

RegularExpression

Kendisine ilk parametre olarak verilen RegEx desenini hedef kolona test eden ve uyuşmaması durumunda da ikinci parametre olarak verilen hata mesajının gösterilmesini sağlayan bir Validation sisteminin entegrasyonuna yönelik olarak kullanılabilir.

Required

Sadece tek bir parametresi vardır; eşleştirildiği sütun için veri girilmez ise gösterilmesi gereken hata mesajını String olarak alır.

ScaffoldTable

Tablo sınıflarına doğrudan verilebilen bu MetaData ile bir tablonun web sitesi görselliğinde gösterilip gösterilmeyeceğini belirler.

StringLength

Bir sütuna girilebilecek maksimum metin uzunluğu ilk parametresi olarak alır. İkinci parametresinde ise söz konusu uzunluk aşıldığında gösterilecek olan hata mesajını saklar.

Sonuç

Yazı boyunda Annotation'lar içerisinde atladığım bazı seçenekler oldu. Bu seçenekleri ileriki yazılarda daha detaylı olarak incelememiz gerektiği için şimdilik yüzeysel olarak geçmek istemedim.

Hepinize kolay gelsin.

Tuesday, October 21, 2008 2:36:26 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET 3.5 | LINQ  | 
 Monday, October 20, 2008

Hafta sonunu Ankara'da geçirdik. Neden mi? INETA Capital Hit zamanıydı! Atladık INETA minibüsümüze :) yollara düştük. Maceralarımızla ilgili videolar ve fotoğraflar çok yakında bu blogda :)

İki kocaman gün boyunca dopdolu bir programla Çankaya Üniversitesi'nde iki yüz elli kişilik bir ekip olarak yattık kalktık diyebilirim. Yine her zamanki gibi benim için muhteşem zevkliydi.

Pazar akşamı saat yedide Capital Hit'i sonlandırdık.
Pazar akşamı saat yedide Capital Hit'i sonlandırdık.

Aktiviteye katılan tüm konuşmacı dostlarıma binlerce teşekkür. Ayrıca Çankaya Üniversitesi Bilişim Kulübü ve sevgili MSP, Çağrı Erdoğan'a da çok teşekkürler. Bir organizasyonda ancak bu kadar başarılı bir misafirperverlik sergilenebilirdi.

Tabi ki her şey bu kadarla bitmiyor! Elimde birçok fotoğraf, minibüs yolculuğumuzdan videolar ve panel kaydımız var. Hepsini büyük bir hızla hazırlamaya çalışıyorum. En kısa zamanda sizlerle buradan paylaşacağım.

Şimdilik aşağıdaki sunumlarla idare edelim :)

AdoNet Data Services / Burak Selim Şenyurt - 20102008_1.pptx (1,01 MB)
LINQ / Uğur Umutluoğlu - 20102008_2.pptx (750,29 KB)
WCF / Burak Selim Şenyurt - 20102008_3.pptx (460,14 KB)

Not: Bu sefer ben hiç sunum kullanmadım, doğrudan demolarla ilerledim. O nedenle sunum paylaşamıyorum.

Monday, October 20, 2008 6:24:54 PM (GTB Standard Time, UTC+02:00)  #    Comments [9]   .NET Framework 3.5 | ASP.NET 3.5 | Expression Blend | Haberler | IIS 7.0 | LINQ | Seminer | Silverlight 2.0 | WCF | WPF  | 
 Sunday, October 12, 2008

Bir önceki yazımda yeni bir Dynamic Data Web Site'ın nasıl oluşturulabileceğine göz atmıştık. Aynı proje üzerinden devam ederek Dynamic Data Web Site'larda otomatik olarak karşımıza çıkan sayfaların yapılarını, nerelerden geldiklerini ve yönlendirme sistemlerini inceleyeceğiz.

Tamamen boş, yeni bir Dynamic Data Web Site yarattığınızda aslında Visual Studio sizin için birçok gerekli dosyayı projenize otomatik olarak ekliyor. Tüm bu otomatik eklenen dosyalar proje içerisinde DynamicData adında bir klasörün altında saklı.

DynamicData klasöründeki SAKLI GÜÇ
DynamicData klasöründeki SAKLI GÜÇ

Dynamic Data klasöründeki farklı yapıların amaçlarını hızlıca açıklayalım. Content klasörü altındaki içerik genelde diğer UserControl ve sayfalarda kullanılan içeriği taşır. Bu klasörde resimler veya harici UserControll'ler bulunabilir. Varsayılan ayarlarla gelen iki UserControl'den biri olan FilterUserControl bizim örneğimizde Kategorilerin filtreleme amaçlı olarak kullanıldığı yerlerde nasıl gözükeceğini ve çalışacağını belirler. FilterUserControl.ascx'in içindeki kod baktığımızda aşağıdaki manzara ile karşılaşıyoruz.

<%@ Control Language="VB" CodeFile="FilterUserControl.ascx.vb" Inherits="FilterUserControl" %>

 

<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" EnableViewState="true" CssClass="droplist">

    <asp:ListItem Text="All" Value="" />

</asp:DropDownList>

Bu kodda gördüğünüz DropDownList'i farklı bir kontrol ile değiştirirseniz doğrudan tüm proje içerisinde Filtreleme işlemlerinde bu kontrol kullanılacaktır. Sanırım yavaş yavaş Dynamic Data Web Site yapısının avantajlarını da hissetmeye başladık. Tabi bu gibi özelleştirme konularının detaylarına ileride daha derinlemesine gireceğiz.

DynamicData klasörümüzün içeriğine geri dönmek gerekirse sırada FieldTemplates klasörü vardı. Hatırlarsanız bir önceki makalemizde veritabanındaki tabloların Field'lerinin veri tipine göre farklı kontrollerin sahneye geldiğini görmüştük. Yerine göre MultiLine bir Textbox veya Chechbox gelebiliyordu. İşte FieldTemplates klasörü altında farklı veri tiplerine için sahneye gelecek olan UserControl'ler bulunuyor. Örneğin Boolean.ascx'i açarak karşımıza bir Checkbox gelecektir.

<%@ Control Language="VB" CodeFile="Boolean.ascx.vb" Inherits="BooleanField" %>

 

<asp:CheckBox runat="server" ID="CheckBox1" Enabled="false" />

Yine bu dosya içerisinde yapılan herhangi bir değişiklik tüm projede Boolean Field'lerin gösteriminde etkili olacaktır.

Son olarak bizi yakından ilgilendiren klasörlerden biri de PageTemplates klasörü. Bu klasör içerisinde veri kaynağımızdaki tüm tablolarla dinamik olarak çalışabilecek şekilde hazırlanmış ve CRUD işlemlerini yapmayı hedefleyen farklı ASPX sayfaları bulunuyor. Bu sayfalar bizim örneğimizde de hem Kategoriler hem de Ürünler tablosunu düzenlerken kullanılıyordu.

Dynamic Data Web Site'ın URL yapısı.
Dynamic Data Web Site'ın URL yapısı.

Yukarıdaki ekran görüntüsünde de görebileceğiniz gibi Kategorilers adındaki LINQ serisini düzenlerken düzenlediğimiz tablonun / nesnelerin adı URL içerisinde belirdikten sonra doğrudan List.aspx adında bir dosya çağrılıyor. Bu dosya hali hazırda PageTemplates içerisinde bulunan dosyanın ta kendisi. Bunun gibi Edit düğmesine tıkladığımızda da Edit.aspx ve tüm diğerleri de uygun işlemlerde tablo isminin ardından geliyorlar. Tabi ki URLRewriting'den bahsediyoruz ama konumuz o olmadığı için detaylara girmeyeceğim.

PageTemplates içerisinde herhangi bir dosyanın görselliğini veya yapısını değiştirdiğiniz anda projenizdeki tüm tablolarla ilgili işlemlerde gözükür hale gelecektir. Unutmayın tüm tablolar için bu dosyalar kullanılıyor. Peki bu durumu nasıl değiştirebiliriz?

Farklı tablolara farklı sayfalar?

Aslında tüm bu yönlendirme işlemlerinin yapıldığı yer projenin Global.asax dosyası. Global.asax içerisinde kodlar tabloların ne şekilde hangi dosyalarla işlem yapacağına karar veriyor.

[VB]

    routes.Add(New DynamicDataRoute("{table}/{action}.aspx") With { _

        .Constraints = New RouteValueDictionary(New With {.Action = "List|Details|Edit|Insert"}), _

        .Model = model})

[C#]

        routes.Add(new DynamicDataRoute("{table}/{action}.aspx") {

            Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert" }),

            Model = model

        });

Yukarıdaki gördüğünüz kod Global.asax içerisinde hazır olarak bulunuyor ve List, Details, Edit, Insert işlemlerinin hepsini tablo adı / aksiyon adı .aspx şeklinde yönlendiriyor. Aslında Dynamic Web Site yapısına gelen bir diğer özellik de tüm bu CRUD işlemlerinin tek bir sayfada yapılacak şekilde düzenlenmesi. Yani verileri ekleme, çıkarma ve düzenleme işlemlerinin hepsini tek bir sayfada halledebilecek şekilde hazırlanmış bir şablon da DynamicData klasöründeki PageTemplates içerisinde duruyor : ListDetails.aspx.

Bu dosya içerisindeki bir GridView Inline Editin sağlarken DetailsView'de detayların gösterilmesi ve yeni kayıt eklenmesini sağlıyor. Peki yönlendirmeyi nasıl değiştirebiliriz? Bu işlemin kodu de Global.asax içerisinde pasif bir şekilde duruyor. Tek yapmanız gereken yukarıdaki kodu pasif hale alıp aşağıdaki aktif hale getirmek.

[VB]

        routes.Add(New DynamicDataRoute("{table}/ListDetails.aspx") With { _

            .Action = PageAction.List, _

            .ViewName = "ListDetails", _

            .Model = model})

 

        routes.Add(New DynamicDataRoute("{table}/ListDetails.aspx") With { _

            .Action = PageAction.Details, _

            .ViewName = "ListDetails", _

            .Model = mod

[C#]

        routes.Add(new DynamicDataRoute("{table}/ListDetails.aspx")

        {

            Action = PageAction.List,

            ViewName = "ListDetails",

            Model = model

        });

 

        routes.Add(new DynamicDataRoute("{table}/ListDetails.aspx")

        {

            Action = PageAction.Details,

            ViewName = "ListDetails",

            Model = model

        });

Kodlarda da yer aldığı üzere toplam iki yönlendirme yapıyoruz. Birincisi "List" işleminin tablo adı / ListDetails.aspx sayfasında yapılacağı ile ilgili diğer ise Details görünümünün de aynı şekilde yapılacağı ile ilgili. Edit ve Insert işlemlerini yönlendirmemize gerek yok çünkü zaten onlar artık ListDetails içerisinde hallediliyor olacak.

ListDetails ile herşey aynı sayfada halloluyor.
ListDetails ile herşey aynı sayfada halloluyor.

Yukarıdaki ekran görüntüsünde ListDetails.aspx'i görüyorsunuz. GridView artık kendi içerisinde InlineEdit destekliyor ve bizim kategori kolonu da gördüğünüz gibi Edit modunda bir DropDownList olarak beliriyor.

Peki bizim esas konumuz neydi? Biz farklı bir tabloyu farklı bir dosya ile göstermek istiyorduk. Gelin örneğimizdeki Urunler tablosunun ListDetails ile gösterilmesini ayarlarken geri kalanların normal bir şekilde ayrı ayrı dosyalarla düzenlenmesini sağlayalım.

[VB]

        routes.Add(New DynamicDataRoute("Urunlers/ListDetails.aspx") With { _

            .Action = PageAction.List, _

            .ViewName = "ListDetails", _

            .Table = "Urunlers", _

            .Model = model})

 

        routes.Add(New DynamicDataRoute("Urunlers/ListDetails.aspx") With { _

            .Action = PageAction.Details, _

            .ViewName = "ListDetails", _

            .Table = "Urunlers", _

            .Model = model})

 

        routes.Add(New DynamicDataRoute("{table}/{action}.aspx") With { _

            .Constraints = New RouteValueDictionary(New With {.Action = "List|Details|Edit|Insert"}), _

            .Model = model})

[C#]

        routes.Add(new DynamicDataRoute("Urunlers/ListDetails.aspx")

        {

            Action = PageAction.List,

            ViewName = "ListDetails",

            Table = "Urunlers",

            Model = model

        });

 

        routes.Add(new DynamicDataRoute("Urunlers/ListDetails.aspx")

        {

            Action = PageAction.Details,

            ViewName = "ListDetails",

            Table = "Urunlers",

            Model = model

        });

 

        routes.Add(new DynamicDataRoute("{table}/{action}.aspx")

        {

            Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert" }),

            Model = model

        });

Yukarıdaki kodlar Urunlers tablosunun ListDetails.aspx ile gösterilmesini ve geri kalan tüm tabloların standart bir şekilde tablo adı / aksiyon adı.aspx ile düzenlenmesini sağlayacaktır. Burada önemli olan noktalardan biri kodumuzun içerisindeki istisnai durumların yani bizim örneğimizde Urunlers tablosunun durumunun kod sırasında daha önde tanımlanmış olmasının şart olması. Aksi halde sistem istediğimiz gibi çalışmayacaktır.

Bu yazıda Dynamic Web Site yapısının nasıl çalıştığını ve proje yapısını incelemekle beraber web sitelerini özelleştirme dünyasına da ufak bir giriş yaptık. Sonraki yazılarımda derin detaylara yolculuğumuz devam edecek.

Hepinize kolay gelsin.

Sunday, October 12, 2008 12:28:25 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET 3.5  | 
 Saturday, October 11, 2008

ASP.NET tarafında programlama yaparken çoğu zaman yaptığımız işlemlerin veya kullanıcılara sağlamaya çalıştığımız ortamında sadece CRUD (Create, Read, Update, Delete) operasyonlarını yapmakla yükümlü olduğunu farkına bile varmayız. Aslında tüm yaptığımız sürekli farklı toplolar için INSERT, UPDATE, DELETE işlemlerini yapan sayfalar, arayüzler ve kodlar yaratmaktır. Bazen bu kodların tabloların niteliğine göre biraz değişir bazen de tablolar arası ilişkiler nedeniyle ek filtrelemeler koymamız gerekir. Fakat özünde baktığımızda işin büyük kısmı ve sürekli tekrar etmekten bir programcı olarak genelde sıkıldığımız kısmı klasik CRUD işlemleridir.

İşte tam da bu noktada bizim sorunumuzu çözecek olarak yapı .NET Framework 3.5 SP1 ile beraber artık Visual Studio'nun içerisinde: ASP.NET Dynamic Data Web Site!

Önce bir hazırlanalım!

Nesne Tabanlı Tasarım mimarisinin mantığına tamamen aykırı olsa da maalesef çoğu projede hala öncelikle veritabanı tasarımını yaparak ilerliyoruz. Bu kötü bir alışkanlık gibi gözükse de ufak projelerde çok sorun yaratmayacağını öngörebiliriz. Dynamic Data Web Site mantığında da önce elinizde hazır bir veritabanı olması şart. Bunun için hemen hızlı bir şekilde SQL 2008'de örnek bir veri tabanı yaratacağız.

Örneğimizdeki veritabanının tasarımı.
Örneğimizdeki veritabanının tasarımı.

Veritabanımızı yukarıdaki şemaya göre yarattıktan sonra artık hemen bu veritabanını kontrol edecek olan web sitesini yaratmak üzere Visual Studio tarafına geçebiliriz.

Yeni bir Dynamic Web Site!

Visual Studio içerisinde "File / New Web Site" menüsüne ufak bir yolculuk yaparsak karşımıza seçenekler arasında bir de "Dynamic Data Web Site"ın geldiğini göreceğiz. Hemen bu seçeneği işaretleyerek yeni web sitemizi yaratalım.

Projenizi yarattıktan sonra "Solution Explorer" içerisinde gördüğünüz farklı klasör ve dosyalar aklınızı karıştırmasın. Bu konulara ileriki makalelerde detaylı olarak değineceğiz. Şu an için önemli olan hemen web sitemizi veritabanı ile ilişkilendirerek ayağa kaldırıp sonuca ulaşmak.

Dynamic Data Web Site'ın veritabanına ulaşması için Entity Framework kullanabileceğiniz gibi rahatlıkla LINQ2SQL sınıflarından da faydalanabilirsiniz. Biz örneğimizde LINQ2SQL kullanacağız. Bu nedenle hemen yeni bir DBML dosyasını projemize ekliyoruz ve veritabanımızdan "Kategoriler" ve "Ürünler" tablolarını DBML dosyasına taşıyoruz.

LINQ2SQL'in detayların bu yazıda girmeyeceğim, merak edenler bu konudaki detayları "LINQ2SQL'e Giriş" yazımdan edinebilirler.

Artık LINQ2SQL sınıflarımız da hazır olduğuna göre geriye sadece tek bir nokta kalıyor; Dynamic Data Web Site'ı LINQ2SQL sınıflarımız ile haberleştirmek. Bu işlemi yapabilmemiz için gerekli kod aslında hazır bir şekilde projenin Global.asax dosyasında duruyor.

    '                    IMPORTANT: DATA MODEL REGISTRATION

    ' Uncomment this line to register LINQ to SQL classes or an ADO.NET Entity Data

    ' model for ASP.NET Dynamic Data. Set ScaffoldAllTables = true only if you are sure

    ' that you want all tables in the data model to support a scaffold (i.e. templates)

    ' view. To control scaffolding for individual tables, create a partial class for

    ' the table and apply the [Scaffold(true)] attribute to the partial class.

    ' Note: Make sure that you change "YourDataContextType" to the name of the data context

    ' class in your application.

    ' model.RegisterContext(GetType(YourDataContextType), New ContextConfiguration() With {.ScaffoldAllTables = False})

Yukarıdaki gibi tamamen pasif hale getirilmiş bir paragraf yazı ve bir satır kod Global.asax'ın en başında yer alıyor. Bizim için önemli olan en alttaki kod satırı tabi ki. Bu satırı aktif hale getirerek YouDataContextType'ın yerine kendi DBML dosyamızın DataContext'ini atamamız gerek. Sonrasında da ScaffoldAllTables özelliğini False değerinden True'ye çevirmeliyiz.

[VB]

model.RegisterContext(GetType(DataClassesDataContext), New ContextConfiguration() With {.ScaffoldAllTables = True})

[C#]

model.RegisterContext(typeof(DataClassesDataContext), new ContextConfiguration() { ScaffoldAllTables = true });

Son olarak yukarıdaki kod işimizi görecektir. Burada özellikle açıklanması gereken nokta sanırım ScaffoldAllTables özelliği. Bu özellik sayesinde Dynamic Data Web Site hedef veritabanındaki (Şu anda sadece LINQ2SQL'in sağladığı tablolar) tüm tablolara ulaşarak gerekli CRUD işlemlerinin yapılabilmesini sağlayacaktır. Bu işlemin yapılıp yapılmayacağına isterseniz tablo bazında da karar verebilirsiniz, fakat bunun detaylarına daha ileride gireceğiz.

Şimdi son değişikliklerle beraber Global.asax dosyamızı da kaydedelim ve projemizi çalıştıralım :)

Dynamic Data Web Site'ın ilk görünümü.
Dynamic Data Web Site'ın ilk görünümü.

Gördüğünüz gibi site çalıştığında anda kendisine bağlı tüm tabloları hemen listeledi. Şimdi hızlıca bir Kategorilers sayfasına yönelelim. Unutmadan, buradaki isimlerin LINQ2SQL'deki nesne isimleri olduklarını hatırlamakta fayda var, isterseniz bu isimleri LINQ2SQL tarafından rahatlıkla değiştirebilirsiniz, başka seçenekler de var ama onları da ileride inceleyeceğiz.

Kategoriler tablosu listeleniyor.
Kategoriler tablosu listeleniyor.

Benim daha önce veritabanına girişini yaptığın birkaç veriyi yukarıdaki ekranda görebilirsiniz. Gördüğünüz gibi otomatik olarak tüm bu kategoriler için Edit / Delete ve Details bölümleri açılmış. Kategoriler'in Aciklama özellikleri burada gösterilmemiş ve Details bölümü ile gidilen sayfaya saklanmış. Daha da güzeli her kategorinin yanına bir "View Urunlers" linki konarak bu kategorideki ürünlerin görülebileceği sayfaya birer de link konmuş. Eh gönül daha ne ister?

Ürünler'in gösterildiği Dynamic Data Sayfası
Ürünler'in gösterildiği Dynamic Data Sayfası

Ürünlerin gösterildiği sayfaya gittiğimizde ise otomatik olarak Kategoriler'in bir DropDownList'e dönüştüğünü ve filtreleme amaçlı olarak kullanılabildiğini görüyoruz. Ayrıca burada da hem yeni ürün ekleme amaçlı hem de düzenleme için gerekli tüm detaylar hazırlanmış.

Ürünler'imizin detaylarını düzenleyebileceğimiz sayfalar da hazır.
Ürünler'imizin detaylarını düzenleyebileceğimiz sayfalar da hazır.

Herhangi bir ürüne ait Edit linkine tıkladığımızda gittiğimiz sayfada Urunler tablosundaki her bir Field'e uygun şekilde gerekli görsel öğelerin yaratıldığını görebiliyoruz. Veritabanına NText olarak düzenlediğimiz yerler MultiLine TextBox'lar haline gelirken kategorilerimiz de bir DropDownList haline gelmiş.

Tabi ki bu web sitesi bu şekilde kullanılabileceği gibi özelleştirmelerin gerekeceği de kesin. Sonraki Dynamic Data ile ilgili yazılarımda özelleştirmelerle ilgili detayların yanı sıra arka plandaki mekanizmaları da inceleyeceğiz.

Hepinize kolay gelsin.

Saturday, October 11, 2008 11:22:06 AM (GTB Standard Time, UTC+02:00)  #    Comments [5]   ASP.NET 3.5  | 
 Tuesday, October 07, 2008

Bugün CEBIT fuarında TBDGenc organizasyonundaki Geek Zone dahilinde "Facebook Uygulama Geliştirme" oturumunu sundum. Geek Zone'un konsepti gereği 20 dakikalık oturumlar gerçekleşiyor. Benim oturumu çaktırmadan 30 dakikaya kadar uzattım :)

Geek Zone'daki "Facebook Uygulama Geliştirme" oturumum.
Geek Zone'daki "Facebook Uygulama Geliştirme" oturumum.

Gerçek anlamda "hap" niteliğinde bir oturum oldu, eğer anlattığım her kelimeyi katılımcılara doğru şekilde aktarabildiysem ASP.NET ile FaceBook için uygulama geliştirme yolunda neredeyse karşılaşabilecekleri tüm soruları çözdük diyebilirim.

Aktivite de söz verdiğim üzere kullandığım sunumu aşağıdan indirebilirsiniz ;)

Facebook Uygulama Geliştirme Sunumu - 07102008_2.pptx (807 KB)

Cuma günü "WPF ile 3D animasyonları" anlatıyor olacağım. Sonrasında da CEBIT fuarını gezeceğim :) Bugün gezemedim. Hepinizi beklerim.

Tuesday, October 07, 2008 9:32:53 PM (GTB Standard Time, UTC+02:00)  #    Comments [9]   ASP.NET 3.5  | 
 Saturday, October 04, 2008

Önümüzdeki hafta CEBIT fuarının haftası. CEBIT fuarı çerçevesinde TBDGENC'nin düzenlediği GeekZone aktivitesinde ben de iki oturumda konuşmacı olacağım. İşleyeceğimiz konulardan ilki "FaceBook'da Uygulama Geliştirme" ikincisi ise "WPF ile 3D Animasyonlar". GeekZone'da her bir oturum hap niteliğinde sadece 20 dakika sürüyor. Bana MCT eğitimlerindeki 5 dakikalık sunumlarımızı hatırlattı :)

GeekZone programını aşağıda inceleyebilirsiniz.

GeekZone Programı
GeekZone Programı

Saturday, October 04, 2008 3:44:19 PM (GTB Standard Time, UTC+02:00)  #    Comments [3]   ASP.NET 3.5 | Seminer | WPF  | 
 Friday, September 26, 2008

INETA Summer Hit üzerinden uzun bir zaman geçti gibi hissettiğimiz bu günlerde yeni bir aktivite serisi ile tekrar karşınızdayız. Bu sefer İstanbul değil Anadolu'nun merkezi, Başkentimiz Ankara'da olacağız.

INETA Capital Hit Afişi

Dikkat ederseniz İstanbul'daki Summer Hit sonrası içeriğimizi de epeyce değiştirdik. Tabi bunda sizlerin doldurmuş olduğu değerlendirme formlarının etkisi çok büyük. Bu sefer çok daha sıkışık ve yoğun bir tempomuz olacak. Hediyelerimiz daha fazla (hatta çok ilginç beklenmedik şeyler var :)) ve içecek sorununu da hallettik (:))

İlk gün sabah yine SL 2.0 ile başlayıp sonra benim çok önem verdiğim IIS 7'ye geçeceğiz. IIS 7.0 üzerinde ASP.NET ve PHP tarafında çok güzel yenilikler var. Sonrasında her zamanki gibi bir sohbet panelimiz olacak. Son olarak LINQ ile ilk günümüzü kapatacağız. İkinci gün WPF ile başlayarak ADO.NET Data Services konusunu inceleyeceğiz. Heyecanlandığınızın farkındayım :) Sonrasında IE 8.0 ile gelen yazılımcı ve tasarımcıları ilgilendiren yenilikler ve yeni uygulama platformlarını inceleyerek WCF dünyasına da atılarak iki günü sonlandıracağız.

Aktiviteye üniversite girişinde güvenlik sorunları yaşamamak adına kayıt olmanız şart.

Kayıt adresi: http://daron.yondem.com/kayit/

Emeklerinden dolayı buradan sevgili MSP, Çağrı Erdoğan'a çok teşekkür ediyorum.

Aktiviteyi duyururken geçen sefer güzel bir başarı elde etmiştik. Bu sefer de yine aşağıdaki bannerı kullanabilirsiniz. Banner'a tıklandığında link olarak da kayıt adresini verebilirsiniz.

INETA Capital Hit Banner

Hepinizi bekliyorum ;)

Friday, September 26, 2008 8:59:59 AM (GTB Standard Time, UTC+02:00)  #    Comments [23]   .NET Framework 3.5 | ASP.NET 3.5 | Expression Blend | IIS 7.0 | LINQ | Seminer | Silverlight 2.0 | Visual Basic 2008 | Visual Studio 2008 | WCF | WPF  | 
 Tuesday, September 23, 2008

Başlık olarak “Reflection” yazdıktan sonra ardına sayfalarca açıklama ve örnek konulabilir. Hatta bu konuda ayrı bir kitap bile yazılabilir. Reflection’ın çok farklı kullanımlar var. Özetleyerek hızlı bir şekilde tanımlamak istersek aslında Reflection bize hakkında bilgi sahibi olmadığınız programatik nesnelerle ilgili çalışma zamanında (run-time) bilgi alabilmemize olanak tanıyan bir metottur. Peki böyle bir şeye neden ihtiyacımız olsun? En basit örnek gerçek zamanlı olarak uygulamalara farklı DLL dosyalarının bağlandığı durumları gösterebiliriz. Böyle bir durumda kaynak konumdaki sınıflar veya metotlar ile ilgili herhangi bir bilgi bulunmaz. Söz konusu bu bilgilerin program çalışırken elde edilerek kullanılması gerekir. Gelin ilk olarak Reflection’ın yapısını ve sistemini tanımak adına tek bir uygulama içerisinde nasıl kullanılabileceğimize göz atalım. Örnek uygulamamızda aşağıdaki şekli ile tanımlanmış bir Urun sınıfı kullanacağız.

[VB]

Public Class Urun

 

    Private PAdi As String

    Public Property Adi() As String

        Get

            Return PAdi

        End Get

        Set(ByVal value As String)

            PAdi = value

        End Set

    End Property

 

    Sub New()

 

    End Sub

 

    Sub New(ByVal adi As String)

        Me.Adi = adi

    End Sub

 

    Function Uyari() As String

        Return "Ürünün adı: " & Me.Adi

    End Function

End Class

[C#]

public class Urun

{

 

    private string PAdi;

    public string Adi

    {

        get { return PAdi; }

        set { PAdi = value; }

    }

 

    public Urun()

    {

 

    }

 

    public Urun(string adi)

    {

        this.Adi = adi;

    }

 

    public string Uyari()

    {

        return "Ürünün adı: " + this.Adi;

    }

}

Uygulamamız içerisinde iki adet düğme yer alacak ve kullanacağımız Windows penceresinde global olarak tanımlanmış bir de Object tipinde değişkenimiz bulunacak.

[VB]

Dim BirUrun As Object   

[C#]

object BirUrun;

Uygulama içerisindeki düğmelerden birine basıldığında global BirUrun değişkenimiz yeni bir Urun değişkenine dönüştürülecek.

[VB]

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    BirUrun = New Urun

End Sub

[C#]

    private void button1_Click_1(object sender, EventArgs e)

    {

        BirUrun = new Urun();

    }

Programımız içerisinde diğer düğmeye basıldığında BirUrun adındaki değişkenimizin Adi özelliğini değiştirerek Uyari adındaki metodunu kullanmak istiyoruz. Fakat Visual Studio içerisinde maalesef ki BirUrun adındaki değişkenle beraber Urun tipine ait Intellisense desteği gelmeyecektir. Aslında bu durumun haklı bir nedeni var. İkinci düğmeye basıldığında BirUrun adındaki değişkenin tipininin Object mi yoksa Urun mü olacağı belli değil. İşte tam da istediğimiz ortamı yaratmış olduk. Kullanacağımız nesnenin tipi belirsiz ve biz ona ait bazı özellikleri kullanmak istiyoruz. Bu durumda ilk olarak ikinci düğmeye basıldığında gerçekten BirUrun değişkeninin tipi Urun mü yoksa değil mi sorusunu kontrol etmemiz lazım.

[VB]

       If TypeOf (BirUrun) Is Urun Then

 

        End If

[C#]

        if ((BirUrun) is Urun)

        {

 

        }

Buraya kadar her şey çok kolay. Bundan sonra eğer IF kontrollerimize olumlu sonuç dönüyorsa ilk olarak gidip nesnenin Adi özelliğini bulmamız ve ona bir değer aktarmamız gerekiyor.

[VB]

BirUrun.GetType.GetProperty("Adi").SetValue(BirUrun, "Daron", Nothing)

[C#]

BirUrun.GetType().GetProperty("Adi").SetValue(BirUrun, "Daron", null);   

Yukarıdaki kod ile elimizdeki nesnenin tipini bilmeden onun Adi adındaki özelliğini (property) yakalayarak değerini Daron olarak değiştiriyoruz. Kodumuzu detaylı olarak adım adım bakacak olursak ilk aşamada nesnenin tipini GetType ile alıyoruz. Sonrasında ise tipini yakaladığımız nesnenin GetProperty ile Adi adındaki özelliğini alarak SetValue ile söz konusu özelliğin değerini değiştiriyoruz. SetValue metodu toplam üç parametre alıyor; bunlardan ilki değer değişikliği yapılacak nesnenin kendisi, ikincisi yeni atanacak olan değer, üçüncüsü ise eğer değiştirilecek olan özellik (property) indeksli ise söz konusu indeks değeri. Bizim örneğimizde indeksli bir özellik olmadığı için bu parametreyi boş geçiyoruz.

Değer atamamızı tamamladığımıza göre bu sefer de sıra geldi BirUrun değişkenimize ait Uyari metodunu çalıştırmaya. Metodumuz bize bir String döndürecek biz de onu doğrudan bir mesaj kutusu ile kullanıcıya göstereceğiz.

[VB]

BirUrun.GetType.InvokeMember("Uyari", Reflection.BindingFlags.InvokeMethod, Nothing, BirUrun, Nothing)

[C#]

BirUrun.GetType().InvokeMember("Uyari", System.Reflection.BindingFlags.InvokeMethod, null, BirUrun, null).ToString();

Reflection kullanarak türü bilinmeyen bir nesnenin bir metodunu çalıştırmak için InvokeMember metodundan faydalanmamız gerekiyor. InvokeMember aslında çok geniş kullanımı olan bir metod, biz şimdilik sadece bir çeşit kullanımına değineceğiz. Örneğimizde InvokeMember bir metod çalıştıracağı için ilk parametresinde çalıştırılacak olan metodun adını ikincisinde BindingFlags.InvokeMethod ile bir Metod çalıştırılacağını belirtiyoruz. Üçüncü parametre bizim şimdilik kullanım alanımız dışında kalan Binding’lerle ilgili, aynı şekilde beşinci parametre de boş bırakılarak geçilecek. Dördüncü parametrede ise hedef nesnemiz olan BirUrun değişkenimizi atayacağız. Böylece metodumuzu da çalıştırmış olduk.

Dinamik DLL Kullanımı

Kabaca Reflection’ın nasıl kullanılabildiğine dair bir örnek yaptıktan sonra artık sıra geldi harici bir DLL dosyasının çalışma anında programımıza ekleyerek içerisindeki yapıları kullanmaya. Bu çeşit bir işlevselliği özellikle gerçek zamanlı DLL derlemesi ile birleştirdiğinizde çok farklı bir dünyaya kapı açmış olacaksınız. Hedef olarak kullanacağımız DLL dosyasını aşağıdaki kodlardan yaratacağız.

[VB]

Public Class Deneme

    Function Metin() As String

        Return "Çalışıyor"

    End Function

End Class

[C#]

    public class Deneme

    {

        string Metin()

        {

            return "Çalışıyor";

        }

Yarattığımız DLL dosyasını uygulamamız ile aynı konuma yerleştirdikten sonra aşağıdaki kod ile DLL’imizi kullanmaya başlayabiliyoruz.

[VB]

Dim BirAssembly As Reflection.Assembly = Reflection.Assembly.LoadFrom("ornek2.dll")

[C#]

System.Reflection.Assembly BirAssembly = System.Reflection.Assembly.LoadFrom("ornek2.dll");

Artık yukarıda tanımladığımız Assembly üzerinden Reflection kullanarak ilerleyebiliriz. İlk olarak Deneme adında sınıfımızdan bir instance almamız gerekecek. Bunun için Deneme tipini bulmamız lazım.

[VB / C#]

BirAssembly.GetModule("Ornek2.dll").GetType("Deneme")

Assembly üzerinden modülümüzü yakalıyor sonra da Deneme adındaki tipinizi buluyoruz. Tabi tipi bulmak yeterli değil, söz konusu tipte bir değişken yaratmamız gerekiyor. Activator sınıfını kullanarak bu tip üzerinden bir instance yaratarak Sinif adında bir değişkene aktaracağız.

[VB]

Dim Sinif = Activator.CreateInstance(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme"))   

[C#]

object Sinif = Activator.CreateInstance(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme"));

Yarattığımız sınıfın maalesef özellikleri otomatik olarak gelmeyecek. O nedenle Metin adındaki metodumuzu da elle bularak çalıştırmak zorundayız.

[VB]

BirAssembly.GetModule("Ornek2.dll").GetType("Deneme").GetMethod("Metin").Invoke(Sinif, Nothing)

[C#]

BirAssembly.GetModule("Ornek2.dll").GetType("Deneme").GetMethod("Metin").Invoke(Sinif, null)

Yine Assembly üzerinden yola çıkarak bu sefer daha da ileri gidiyoruz. Deneme sınıfımızı bulduktan sonra içerisinde Metin adındaki metodumuzu buluyor ve doğrudan Invoke ile söz konusu metodu çalıştırıyoruz. Invoke metodu bizden iki parametre istiyor; bunlardan ilki ana sınıfın kendisi. Bir önceki adımda yakaladığımız sınıfı buraya parametre olarak aktarıyoruz. Diğeri ise bizim kullanmayacağımız Binding parametresi.

Metin metodumuz çalıştırıldığında geriye bir String değişkeni döndürüyor. Bu değişkeni de bir mesaj kutusu ile kullanıcıya göstermek istersek uygulamamızın tam kodunun aşağıdaki şekilde sonlanması gerekiyor.

[VB]

Public Class Form2

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim BirAssembly As Reflection.Assembly = Reflection.Assembly.LoadFrom("ornek2.dll")

 

        Dim Sinif = Activator.CreateInstance(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme"))

        MsgBox(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme").GetMethod("Metin").Invoke(Sinif, Nothing))

    End Sub

End Class

[C#]

namespace CSReflection

{

    public partial class Form2 : Form

    {

        public Form2()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            System.Reflection.Assembly BirAssembly = System.Reflection.Assembly.LoadFrom("ornek2.dll");

 

            object Sinif = Activator.CreateInstance(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme"));

            MessageBox.Show(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme").GetMethod("Metin").Invoke(Sinif, null).ToString());

        }

    }

}

Böylece harici bir DLL dosyasını yükleyerek istediğimiz metodu dinamik olarak kullanabildik. Farklı durumlarda isterseniz bir DLL içerisinde tüm metod, sınıf ve özelliklerin listelerini alabilir hatta bunları LINQ sorguları ile tarayabilirsiniz.

[VB]

Dim Metodlar = From Gelenler In BirAssembly.GetModule("Ornek2.dll").GetTypes Where Gelenler.GetMethod("Metin") IsNot Nothing

[C#]

var Metodlar = from Gelenler in BirAssembly.GetModule("Ornek2.dll").GetTypes() where Gelenler.GetMethod("Metin") != null select Gelenler;

Örneğin yukarıdaki LINQ sorgumuz ile harici DLL dosyası içerisinde Metin adında metodu olan tüm sınıfların bir listesini alıyoruz.

Hepinize kolay gelsin.

Tuesday, September 23, 2008 6:51:06 PM (GTB Standard Time, UTC+02:00)  #    Comments [8]   .NET Framework 3.0 | .NET Framework 3.5 | ASP.NET | ASP.NET 3.5 | LINQ | Silverlight 2.0 | Visual Basic 2005 | Visual Basic 2008 | Visual Studio 2005 | Visual Studio 2008 | WCF | WF | WPF  | 
 Sunday, September 21, 2008

Bir uygulama düşünün kendini programlayabilen. Konumuz “Star Trek” veya “Geleceğe Dönüş” değil. Emin olun gerçek dünyadan ve yapılabileceklerden bahsediyorum. Uygulamalarınızın dış sistemlerle ciddi bir bağlantı içerisinde olduğu durumlarda bazen kendi içlerinde dış sistemlere uygun kodlar üreterek kullanmaları gerekebilir. Bunu bazen uygulamaların kendi içlerindeki yapay zeka ile yapabilecekleri gibi bazen ise başka bir dış kaynaktan aldıkları yeni parametrelerden yola çıkarak kendi kodlarında değişiklik yapabilirler. Eğer bunların hiçbiri size gerçekçi gelmiyorsa başka bir seçenek olarak da harici uygulamaların kullanabileceği DLL dosyaları yaratacak bir uygulama yazmak istediğinizde yapmanız gerekenlerden bahsedebiliriz. Aslında her ikisi de aynı kapıya çıkıyor.

Bize dinamik olarak uygulamalar tarafından kullanılabilecek DLL dosyaları yaratacak bir kod lazım. Kullanacağımız nesnelerin çoğunun bulunduğu esas namespace System.CodeDom.Compiler olacak. Bunun haricinde C# veya VB için ayrı ayrı uygun namespace’leri kullanmamız gerek. Eğer VB kodu derleyecekseniz VB sınıflarını C# kodu derleyecekseniz tabi ki C# sınıflarını kullanmalısınız. Çapraz işlem yaparak C# kodunuz ile VB kodundan DLL üretme şansınız da var. Biz örneklerimizde C# ile C#’dan derleme, VB kodu ile de VB’den derleme yapacağız.

[VB]

Dim KodUretici As New Microsoft.VisualBasic.VBCodeProvider

Dim Derleyici As System.CodeDom.Compiler.CodeCompiler = KodUretici.CreateCompiler()

 

Dim Referanslarim As String() = {"System.dll"}

Dim AssemblyAdi As String = "Ornek.dll"

[C#]

Microsoft.CSharp.CSharpCodeProvider KodUretici = new Microsoft.CSharp.CSharpCodeProvider();

System.CodeDom.Compiler.ICodeCompiler Derleyici = KodUretici.CreateCompiler();

 

String[] Referanslarim =  {"System.dll"};

String AssemblyAdi= "Ornek.dll";

Kodumuzun başlangıcında ilk olarak birer CodeProvider nesnesi yaratıyoruz. Elimizdeki hazır kodu derleyecek olan nesneler olarak bu sınıflar VB ve C# için farklılaşıyor. CodeProvider’lar üzerinden birer de derleyici nesnesi aldıktan sonra sıra geliyor derleyeceğimiz kodun referanslarına karar vermeye. Referansları DLL isimleri ile bir String dizisine aktarmanız şart. Windows uygulamalarında en azından System.dll’in web uygulamalarında da System.Web.dll’in referans alınmış olması gerekiyor. Son olarak üreteceğimiz DLL dosyasının adını da başka bir değişkene aktararak yolumuza devam edelim.

[VB]

Dim DerlemeParametreleri As New System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi)

DerlemeParametreleri.GenerateExecutable = True

DerlemeParametreleri.GenerateInMemory = False

[C#]

System.CodeDom.Compiler.CompilerParameters DerlemeParametreleri = new System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi);

DerlemeParametreleri.GenerateExecutable = false;

 DerlemeParametreleri.GenerateInMemory = false;

Derleme işlemini yaparken yapmamız gereken ayarlar var. Bu ayarları derleyicimize bir CompilerParameters nesnesi olarak aktaracağız. DerlemeParametreleri değişkenimizi yaratırken referanslarımızı ve DLL adını aktardıktan sonra özel olarak GenerateExecutable özelliğini false olarak ayarlıyoruz. Böylece derleyicimiz bize tek başına çalışabilir bir dosya yaratmaktansa bir DLL dosyası yaratacak. Bir sonraki adımda da GenerateInMemory özelliğini false yaparak yaratılacak dosyanın uygulamamız ile aynı konuma, diske yazdırılmasını sağlıyoruz. Aksi halde yaratılan Assembly sadece hafızada tutulacak ve diske yazılmayacaktır. Sıra geldi dinamik olarak derlemeyeceğimiz kodu bir değişkene aktarmaya.

[VB]

Dim Kodum As String = <Kod>Public Class Deneme

    Function Metin() As String

        Return "Çalışıyor"

    End Function

End Class</Kod>.Value

[C#]

System.IO.StreamReader Okuyucu = new System.IO.StreamReader("Class1.cs");

string Kodum = Okuyucu.ReadToEnd();

Okuyucu.Close();

Bu noktada VB ile C# arasında farklı işlemler yaptım. VB’de doğrudan yaratacağım kodu uygulamanın içerisine gömerken C#’da derleyeceğim C# kodunu harici bir Class1.cs dosyasından çektim. Siz kendi uygulamalarınızda ister bu kodları farklı dosyalardan çekin ister metin işlemleri ile dinamik kod yaratın. İhtiyaçlarınıza göre uygun çözümü üretmek tamamen size kalmış. Önemli olan tek nokta aslında bu kodlarda hiçbir hatanın olmaması gerektiği, aksi halde derleme işlemi yapılamayacaktır.

[VB]

Dim Sonuc As System.CodeDom.Compiler.CompilerResults = KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum)

[C#]

System.CodeDom.Compiler.CompilerResults Sonuc = KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum);

Tüm ayarlarımız tamamlandığında göre doğrudan CodeProvider nesnemizin CompileAssemblyFromSource metodunu kullanarak derleme işlemini başlatabiliriz. Tabi bu esnada daha önce hazırlamış olduğumuz DerlemeParametrelerini de metoda parametre olarak aktarıyoruz. Derleme işlemimizi baştan sona tamamlayan kodumuzu bir bütün olarak inceleyelim.

[VB]

Dim KodUretici As New Microsoft.VisualBasic.VBCodeProvider

Dim Derleyici As System.CodeDom.Compiler.CodeCompiler = KodUretici.CreateCompiler()

 

Dim Referanslarim As String() = {"System.dll"}

Dim AssemblyAdi As String = "Ornek.dll"

 

Dim DerlemeParametreleri As New System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi)

        DerlemeParametreleri.GenerateExecutable = True

        DerlemeParametreleri.GenerateInMemory = False

 

Dim Kodum As String = <Kod>Public Class Deneme

    Function Metin() As String

        Return "Çalışıyor"

    End Function

End Class</Kod>.Value

 

Dim Sonuc As System.CodeDom.Compiler.CompilerResults = KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum)

[C#]

Microsoft.CSharp.CSharpCodeProvider KodUretici = new Microsoft.CSharp.CSharpCodeProvider();

System.CodeDom.Compiler.ICodeCompiler Derleyici = KodUretici.CreateCompiler();

 

String[] Referanslarim =  {"System.dll"};

String AssemblyAdi= "Ornek.dll";

 

System.CodeDom.Compiler.CompilerParameters DerlemeParametreleri = new System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi);

DerlemeParametreleri.GenerateExecutable = false;

DerlemeParametreleri.GenerateInMemory = false;

 

System.IO.StreamReader Okuyucu = new System.IO.StreamReader("Class1.cs");

string Kodum = Okuyucu.ReadToEnd();

Okuyucu.Close();

 

System.CodeDom.Compiler.CompilerResults Sonuc = KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum);

Dinamik olarak DLL dosyası derlemek işte bu kadar kolay. Dinamik kod yaratma araçları son dönemde çok popüler. Veritabanına bağlanarak veritabanındaki nesneleri algılayıp uygun “Veri Katmanı” kodunu dinamik olarak oluşturan hazır uygulamalar olduğu gibi bazı durumlarda özel kodlar yazmak da gerekebiliyor. Böyle bir durumda artık siz de uygulamalarınıza farklı kaynaklardaki şartlara uygun kodu dinamik olarak üretebilir ve bir DLL olarak farklı uygulamalara aktarabileceğiniz gibi kendi uygulamalarınızda da kullanabilirsiniz. Yarattığınız DLL dosyasını hemen uygulamanızda kullanmak isterseniz bu sefer dinamik olarak Assembly kullanımını ve Reflection konusuna eğilmenizde fayda var.

Hepinize kolay gelsin.

Sunday, September 21, 2008 7:04:21 PM (GTB Standard Time, UTC+02:00)  #    Comments [3]   .NET Framework 3.0 | .NET Framework 3.5 | ASP.NET | ASP.NET 3.5 | Silverlight 2.0 | Visual Basic 2005 | Visual Basic 2008 | Visual Studio 2005 | Visual Studio 2008 | WCF | WPF  | 
 Friday, September 19, 2008

İster VB olsun ister C#, ister web ister Windows uygulaması olsun yazdığımız tüm kodların derlenerek (Compile) bir EXE veya DLL haline dönüştürüldüğünü biliyoruz. Aslında .NET içerisinde yapılan işlem sizin yazdığınız herhangi bir .NET dilindeki kodun MSIL (Microsoft Intermediate Language)’a çevrilmesidir. İşte tam bu noktada akla gelen ilk soru; acaba bu çeviri işleminin tersini yapmak mümkün mü? Yani elimizdeki DLL veya EXE dosyasından yola çıkarak VB veya C# kodumuzu geri alabilir miyiz? Cevap: Evet.

Şu andan itibaren yapacaklarımız hedef olarak kullanacağınız uygulamanın lisans sözleşmesine göre yeri geldiğinde suç teşkil edebilir. O nedenle sizi özellikle uyarmak istiyorum. Çoğu zaman De-Compile işlemleri yaparkenki amacımız yazdığımız kodun nasıl derleyici tarafında MSIL’e çevrildiğini incelemek veya kaynak kodunu kaybettiğimiz ve bize ait olan bir uygulamanın kodlarına ulaşmak olacaktır. Diğer yandan lisans sözleşmesi ile aykırı düşmediği sürece farklı uygulamaları da De-Compile ederek arka planda farklı işlemlerin nasıl yapıldığını inceleme şansınız da olabilir.

.NET tarafına geçtiğimizde herhangi bir DLL veya EXE’nin aslında MSIL kodları içerdiğinden bahsetmiştik. Tabi ki bu MSIL kodları doğrudan bilgisayarlar tarafından çalıştırılabilir kodlar değiller. O nedenle içerisinde MSIL bulunan bir .NET yapısının çalışabilmesi için hedef makinede .NET Framework’ün yüklü olması gerekiyor. .NET Framework içerisindeki CLR (Common Language Runtime) bizim MSIL kodumuzu makine diline çevirerek çalışmasını sağlayacaktır. Kabaca baktığımızda De-Compile yolunda bizim ilk olarak elimizdeki DLL veya EXE içerisinden MSIL kodunu alarak çıkarmamız gerekecek. Bunun için doğrudan .NET Framework SDK paketi ile beraber gelen MSIL DisAssembler (ILDASM) uygulamasını kullanabiliriz.

IL DASM Kullanımı

Bilgisayarınıza .NET Framework SDK paketini kurduktan sonra doğrudan “Başlat” menüsünden ulaşabileceğiniz ILDASM programını Visual Studio yükleme konumu içerisinde SDK klasörü altında da bulabilirsiniz. Programı açtıktan sonra “File / Open” menüsünden istediğiniz bir .NET DLL veya EXE dosyasını açma şansınız olacaktır.Deneme amaçlı olarak gelin mini bir Windows uygulaması yazalım ve ILDASM ile açarak alacağımız sonucu görelim. Uygulamamız içerisinde birer TextBox, Button ve Label bulunacak. Basit bir şekilde düğmeye basıldığında TextBox içerisindeki değeri Label içerisine aktaracağız.

[VB]

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Label1.Text = TextBox1.Text

    End Sub

End Class

[C#]

namespace WindowsFormsApplication1

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            label1.Text = textBox1.Text;

        }

    }

}

Yukarıda yazdığımız kodlar ile oluşturduğumuz uygulamayı ILDASM ile açarak sonucu inceleyelim. Uygulamanın ilk açılan penceresinde bizim EXE’ye ait tüm sınıflar ve namespace’ler gözüküyor olacaktır. Eğer herhangi bir nesnenin tanımı veya metodu ile ilgili MSIL kodunu görmek isterseniz doğrudan çift tıklayarak yeni bir pencerede kodların açılmasını sağlayabilirsiniz.

ILDASM içerisinde EXE’mizin MSIL kodları açıkça gözüküyor
ILDASM içerisinde EXE’mizin MSIL kodları açıkça gözüküyor

Hazırladığımız örnek uygulamanın Button_Click durumundaki MSIL kodunu bulduğumuzda aşağıdaki sonuç ile karşılaşıyoruz.

[MSIL]

.method private instance void  Button1_Click(object sender,

                                            class [mscorlib]System.EventArgs e) cil managed

{

  // Code size       23 (0x17)

  .maxstack  8

  IL_0000:  ldarg.0

  IL_0001:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.Label WindowsApplication1.Form1::get_Label1()

  IL_0006:  ldarg.0

  IL_0007:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication1.Form1::get_TextBox1()

  IL_000c:  callvirt   instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()

  IL_0011:  callvirt   instance void [System.Windows.Forms]System.Windows.Forms.Label::set_Text(string)

  IL_0016:  ret

} // end of method Form1::Button1_Click

Yukarıdaki MSIL kodu normal şartlarda CLR tarafından makine koduna çevrilerek hedef ortamda çalıştırılıyor. Artık MSIL kodumuzu aldığımıza göre bu kodu VB veya C# koduna çevirmemiz lazım. Tabi bu iş o kadar kolay değil ve tek tek elle yapılabilecek bir iş de değil. O nedenle bu sefer de farklı bir araç kullanacağız.

Reflector iş başında

Lutz Roeder tarafından yazılmış bir program olarak Reflector’ı http://www.red-gate.com/products/reflector/ adresinden bilgisayarınıza indirebilirsiniz. Program aslında bir önceki adımda anlattığım MSIL çözme işlemini de kendi içinde yapabiliyor. Bununla kalmayıp çözdüğü MSIL kodunu istediğiniz .NET diline de çevirebiliyor.

Programı çalıştırdıktan sonra “File / Open” menüsünden istediğiniz bir EXE veya DLL dosyasını seçebilirsiniz. Uygulamanın ana penceresindeki sınıf listesine hemen seçtiğiniz program da gelecektir.

Reflector ile kaynak kodunu görebiliyoruz.
Reflector ile kaynak kodunu görebiliyoruz.

Ufak bir gezinti ile istediğiniz sınıfın veya metodun koduna doğrudan ulaşabilirsiniz. Reflector arayüzündeki “Programlama Dili” seçeneğinde VB, C#, Delphi ve IL seçenekleri bulunuyor. Bir önceki bölümde hazırladığımız uygulamamızı açarak Button.Click durumundaki kodu farklı dillerde Reflector ile alıp inceleyelim.

[VB]

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)

    Me.Label1.Text = Me.TextBox1.Text

End Sub

[C#]

private void Button1_Click(object sender, EventArgs e)

{

    this.Label1.Text = this.TextBox1.Text;

}

Yazdığımız kodlar ile Reflector’ın bize verdiği kodlar tam olarak aynı değil. Bu durum zaten çok normal. Çünkü MSIL koduna çeviri esnasında aslında çoğu şey değişiyor. Örneğin tanımladığımız değişkenlerin bize özel olan isimlendirmeleri yok oluyor veya bizim kullandığımız bazı kısa metotlar uzun şekilleri ile yazılabiliyor. Hatta özellikle VB içerisindeki casting kolaylıkları Compile esnasında farklı değişikliklere neden olabiliyor. Bu durumda De-Compile ile aldığımız kod da yazdığımız koddan biraz farklı oluyor. Yine de elimizde çalışır durumda bir kod olduğuna kesin gözü ile bakabiliriz.

Nasıl engelleriz? Obfuscation!

Herhalde çoğunuz “tüm kodlarımız gözler önünde” endişesi içerisindesiniz. Aslında durum gerçekten de öyle. Tabi bu durumun birçok faydası var. Kişisel olarak itiraf etmek gerekirse farklı yazılımları De-Compile ederek çok şey öğrendiğimi söyleyebilirim. Bir defasında da kendi ürettiğimiz bir yazılımı De-Compile etmemiz gerekmişti, gerçekten hayat kurtarmıştı. Peki bunu nasıl engelleyebiliriz? İlk olarak şunu açıkça belirtiyim, herhangi bir .NET uygulamasından MSIL kodunun alınmasını engellemenin hiçbir yolu yok. Yapabileceğimiz tek şey MSIL kodunun okunabilirliliğini azaltmak için işlevsel olarak aynı işi gören fakat daha karışık bir MSIL kodu yaratmak. Bu işlem obfuscation olarak adlandırılıyor.

Obfuscation ile ilgili sektörde çok sayıda ücretli yazılım bulabilirsiniz. Biz bunlardan Xenocode'aait Postbuild 2008 adındaki ticari yazılımı kullanarak obfuscation ile neler yapabildiğimize bakacağız. XenoCode’u ilk açtığımızda karşımıza hemen bir uygulama listesi geliyor. Bu listeye bir önceki adımda kendi hazırladığımız EXE dosyasını ekleyerek uygulamanın üst menüsünden “Protect” tabına geçiyoruz. Burada sadece Windows’da çalışacak EXE dosyalarına uygulanabilecek özel bir koruma yöntemi olan “Surpress ILDASM” seçeneğinin işaretini kaldırmamız gerek. Bu seçenek DLL’lere zaten uygulanamayacaktır. Ekranın sağ tarafında korumak istediğimiz sınıfların ve metodların bir listesini işaretleyebiliyoruz. Tüm ayarları tamamladıktan sonra uygulamanın sağ altındaki “XenoCode Application” düğmesine basıyoruz.

Obfuscation işlemi için yollardayız
Obfuscation işlemi için yollardayız

Obfuscation işlemini tamamladıktan sonra sıra geldi testlerimizi yapmaya. İlk olarak uygulamamızı ILDASM ile açarak bakalım MSIL kodumuz ne hale gelmiş.

[MSIL]

.method private instance void  x44d0c0526a414989(object xe0292b9ed559da7d,

                                                class [mscorlib]System.EventArgs xfbf34718e704c6bc) cil managed

{

  // Code size       23 (0x17)

  .maxstack  8

  IL_0000:  ldarg.0

  IL_0001:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.Label WindowsApplication1.xaa4f033827d75b4d::get_x029e304eb4c44750()

  IL_0006:  ldarg.0

  IL_0007:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication1.xaa4f033827d75b4d::get_x77691a2cfb8f8048()

  IL_000c:  callvirt   instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()

  IL_0011:  callvirt   instance void [System.Windows.Forms]System.Windows.Forms.Label::set_Text(string)

  IL_0016:  ret

} // end of method xaa4f033827d75b4d::x44d0c0526a414989

Gördüğünüz gibi aslında çok büyük bir değişiklik yok. Sadece sınıfların ve metodların isimleri değiştirilerek karışık isimler verilmiş. Aynı uygulamayı Reflector ile açtığımızda ise aşağıdaki kodları elde ediyoruz.

[VB]

Private Sub x44d0c0526a414989(ByVal xe0292b9ed559da7d As Object, ByVal xfbf34718e704c6bc As EventArgs)

    Me.x029e304eb4c44750.Text = Me.x77691a2cfb8f8048.Text

End Sub

[C#]

private void x44d0c0526a414989(object xe0292b9ed559da7d, EventArgs xfbf34718e704c6bc)

{

    this.x029e304eb4c44750.Text = this.x77691a2cfb8f8048.Text;

}

Kodlar epey okunurluluğunu kaybetmiş durumda. Bizim örneğimizde sadece tek bir satır kod bulunduğu için neyin ne olduğunu anlamak çok zor olmuyor. Fakat binlerde satırdan oluşan uygulamaların kodlarından anlaşılabilir bir sonuç çıkarmak neredeyse imkânsız olacaktır.

Hepinize kolay gelsin.

Friday, September 19, 2008 6:27:11 PM (GTB Standard Time, UTC+02:00)  #    Comments [11]   .NET Framework 3.0 | .NET Framework 3.5 | ASP.NET | ASP.NET 3.5 | Silverlight 2.0 | Visual Basic 2005 | Visual Basic 2008 | Visual Studio 2005 | Visual Studio 2008  | 
 Thursday, September 18, 2008

WPF ile beraber özellikle video uygulamalarının programlanmasındaki kolaylık sonucunda artık Multimedya alanında da sıkça .NET ile programlanmış uygulamalar görebiliyoruz. Bu yolda WPF içerisindeki MediaElement'in katkısı tabi ki yadsınamaz. Bu yazımızda WPF içerisinde açtığımız bir video dosyasından bir kare (thumbnail) almayı deneyeceğiz.

Bu işlemi yapmak için normal şartlarda C++ ile DirectShow üzerine çalışmak gerekiyor. Diğer .NET dilleri için Managed Provider'lar bağımsız yazılımcılarca yazılmış olsa da kolay bir çözüm maalesef ki yok. Bu nedenle biz kendi kodumuzda MediaPlayer ile bir video dosyasını açacak ve istediğimiz saniyesine giderek o anki kareyi yakalayacağız. Kodumuz MediaPlayer'in yani uygulamanın çalıştığı bilgisayarda Media Player'ın oynatabildiği her video ile çalışacaktır, herhangi bir kodek sınırımız olmayacak.

Dikkat: MediaPlayer / Media Player ve MediaElement farklı şeylerdir. MediaPlayer doğrudan System.Windows.Media.MediaPlayer sınıfını tanımlarken, Media Player ise yazı boyunca bir bilgisayarda yüklü olan uygulama olarak Media Player'ı anlatacaktır. Diğer yandan MediaElement ise System.Windows.Controls.MediaElement sınıfını tanımlar. MediaElement ile MediaPlayer sınıfları arasındaki en büyük fark MediaPlayer'ın görsel olarak bir WPF formunda doğrudan video gösterememesidir. Videonun ne şekilde nerede gösterileceğine MediaPlayer için kod ile karar vermek gerekir.

Önce videomuzu bir oynatalım.

Uygulamamızda ilk olarak bir MediaPlayer yaratmamız ve sonrasında da istediğimiz video dosyasını söz konusu MediaPlayer içerisinde oynatmamız gerekiyor. Tüm bunları kodlarla yapacağız.

[VB]

        Dim birMediaPlayer As New MediaPlayer

        birMediaPlayer.Open(New Uri("C:\Users\Public\Videos\Sample Videos\Bear.wmv", UriKind.Absolute))

        birMediaPlayer.Play()

        birMediaPlayer.IsMuted = True

        birMediaPlayer.Position = New TimeSpan(0, 0, 5)

[C#]

            MediaPlayer birMediaPlayer = new MediaPlayer();

            birMediaPlayer.Open(new Uri(@"C:\Users\Public\Videos\Sample Videos\Butterfly.wmv"));

            birMediaPlayer.Play();

            birMediaPlayer.IsMuted = true;

            birMediaPlayer.Position = new TimeSpan(0, 0, 5);

Yukarıdaki kodumuzda birMediaPlayer adını verdiğimiz MediaPlayer değişkenimize bilgisayardaki bir video dosyasını açtırıyoruz. Sonrasında hemen videoyu oynatmaya başlıyoruz aksi halde herhangi bir görsel elde etme şansımız kalmaz. Bu esnada videodan ses gelmemesi için sesini de kısıp doğrudan videonun beşinci saniyesine zıplıyoruz.

[VB]

        System.Threading.Thread.Sleep(5000)

        Dim RenderTarBitmap As New RenderTargetBitmap(1600, 1200, 1 / 96, 1 / 96, PixelFormats.Pbgra32)

        Dim DVisual As New DrawingVisual

        Dim DContext As DrawingContext = DVisual.RenderOpen

        DContext.DrawVideo(birMediaPlayer, New Rect(0, 0, 1600, 1200))

        DContext.Close()

        RenderTarBitmap.Render(DVisual)

        birMediaPlayer.Stop()

        Dim BMPFrame As BitmapFrame = BitmapFrame.Create(RenderTarBitmap)

[C#]

            System.Threading.Thread.Sleep(5000);

            RenderTargetBitmap RenderTarBitmap = new RenderTargetBitmap(1600, 1200, 1 / 96, 1 / 96, PixelFormats.Pbgra32);

            DrawingVisual DVisual = new DrawingVisual();

            DrawingContext DContext = DVisual.RenderOpen();

            DContext.DrawVideo(birMediaPlayer, new Rect(0, 0, 1600, 1200));

            DContext.Close();

            RenderTarBitmap.Render(DVisual);

            birMediaPlayer.Stop();

            BitmapFrame BMPFrame = BitmapFrame.Create(RenderTarBitmap);

İşte bu adımda gördüğünüz kod aslında uygulamamızın kalbi. Hemen ilk satırdaki 5 saniyelik uyku modu dikkatinizi çekmiştir. Maalesef MediaPlayer'ın içerisinde bir video yükleyip oynatmaya başlamış olsak da bu işlemin tam olarak gerçekleşip gerçekleşmediğini anlama şansımız yok. Video dosyasının büyüklüğüne bağlı olarak dosyanın açılması uzun sürebilir. MediaPlayer'In MediaOpened event'ı ise tam olarak tahmin ettiğiniz şekilde çalışmıyor. Sonuç olarak en iyi seçecek 5 saniyelik bir bekleme süresi ile disk işlemlerinin tamamlanmasını beklemek. Tabi unutmamak gerek ki tüm bu yukarıdaki kodları harici bir Threat içerisinde yapmazsanız bu beş saniyelik sürede programınız kilitlenecektir.

Sonraki aşamalarda biraz daha karışık bir yapı kullanarak MediaPlayer'ın içerisinde görselliği almaya çalışıyoruz. RenderTargetBitmap sınıfı hem oluşturulacak olan görüntünün boyutlarını piksel olarak alıyor, hem de görüntünün dikey ve yatay olarak DPI (çözünürlük) değerini istiyor. RenderTargetBitmap'in son parametresi ise oluşturulacak olan görseldeki renk kanalları ile ilgili, bizim örneğimizde RGB ve Alpha kanallarını tek tek 8bit toplam 32 bit olarak alıyoruz.

Bir DrawingVisual nesnesi yaratıp Render işlemini de RenderOpen ile başlatarak o anki DrawingContext'i ele alıyoruz. DrawingContext'in DrawVideo metodu doğrudan bir MediaPlayer alarak o anki görüntüsüyü belirtilen bir alana çizebiliyor. Son olarak RenderTargetBitmap'in Render metodu ile eldeki Visual'dan bir bitmap yaratıyoruz. En sonda elde ettiğimiz BitmapFrame artık videodan almış olduğumuz son görüntüyü temsil ediyor. Sıra geldi bu görüntüyü JPEG olarak uygun bir dosyaya yazmaya.

[VB]

        Dim BMPEncoder As BitmapEncoder = New JpegBitmapEncoder

        Dim FStream As New IO.FileStream("C:\Users\Public\Videos\Sample Videos\Butterfly.jpg", IO.FileMode.Create)

        BMPEncoder.Frames.Add(BMPFrame)

        BMPEncoder.Save(FStream)

        FStream.Flush()

        FStream.Close()

[C#]

            BitmapEncoder BMPEncoder = new JpegBitmapEncoder();

            System.IO.FileStream FStream = new System.IO.FileStream(@"C:\Users\Public\Videos\Sample Videos\Butterfly.jpg", System.IO.FileMode.Create);

 

            BMPEncoder.Frames.Add(BMPFrame);

            BMPEncoder.Save(FStream);

            FStream.Flush();

            FStream.Close();

JpegBitmapEncoder sınıfı bizim için JPEG sıkıştırma işlemlerini halledecektir. Tek yapmamız gereken bir de FileStream yaratarak Encoder'a elimizdeki BitmapFrame'i ekleyerek FileStream'e eldeki veriyi Save metodu ile kaydetmek. Böylece dosyamız artık hazır, videodan karemizi istediğimiz çözünürlükte alabildik.

ASP.NET ile video dosyasından kare almak?

Konumuzla herhangi bir alakası yok gibi gözükebilir fakat aslında ASP.NET ile bir video dosyasından kare (thumbnail) alabilmek de bir başka işkencedir. İşin güzel tarafı .NET Framework içerisindeki tüm sınıflar aslında siz onları referans olarak almanız şartı ile sizin kullanımınıza açıktır. Özetle, yukarıdaki kod aynı şekilde ASP.NET'te de çalışır :) Nasıl mı?

Yukarıdaki kodumuz içerisinde kullandığımız sınıflardan MediaPlayer sınıfı .NET Framework içerisinde PresentationCore.DLL dosyasında bulunur. Kullandığımız diğer sınıflar ve PresentationCore.DLL'in Dependecy assembly'si olan bir diğer DLL'te WindowsBase.DLL dosyasıdır. Tüm bu dosyalar bilgisayarınızda C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0 adresinde bulunur. Yarattığınız herhangi bir ASP.NET sitesine bu DLL'leri referans olarak ekledikten sonra kodunuz aynı şekilde çalışacaktır.

Hepinize kolay gelsin.

Thursday, September 18, 2008 5:55:50 PM (GTB Standard Time, UTC+02:00)  #    Comments [2]   ASP.NET 3.5 | WPF  | 
 Thursday, August 21, 2008

Bugün İzmir'de hosting sağlayıcılar ile bir bir eğitimimiz oldu. Benim için çok güzel bir fırsattı :) çünkü zaten hali hazırda Türkiye'deki hosting sağlayıcılar ile ilgili dertliyim. Şirket tarafında müşterilerimize sunduğumuz içerik yönetim sistemlerini müşterilerimiz hosting sağlayıcılardan aldıkları alanlara koyduklarına bir çok sorun ile karşılaşıyoruz. Bu sorunların detaylarına inerek eğitim boyunca ASP.NET hosting yaparken nelere dikkat edilmesi gerektiğine değindim.

Microsoft Hosting Çözümleri Eğitimi, İzmir
Microsoft Hosting Çözümleri Eğitimi, İzmir

Seminerlerde özellikle bana "ASP.NET 3.5 destekli hosting nasıl buluruz?" gibi sorular geliyor. Bu soruları ve arayışı doğrudan hosting firmalarındaki yetkililere iletme şansım oldu. İlginç bir şekilde sunucularında .NET Framework 3.5 kurulu olduğunu fakat sitelerinde hala 2.0 yazdığını söylediler :) Tabi en kısa zamanda bu hatayı düzeltecekler. Hatta birkaç gün içerisinde SP1 yüklü hostinglerimiz bile olacak Türkiye'de.

Bir diğer konu da tabi ki Silverlight'dı :) Silverlight'ın IIS tarafındaki Mime Type ayarlarından ve detaylarından bahsettik.

Eğitimde kullandığım sunumu aşağıdan indirebilirsiniz.

Hosting Çözümleri Eğitimi Sunumu - 21082008_1.pptx (206,66 KB)

Thursday, August 21, 2008 8:15:42 AM (GTB Standard Time, UTC+02:00)  #    Comments [12]   ASP.NET 3.5 | IIS 7.0 | Silverlight | Silverlight 2.0  | 
 Wednesday, August 20, 2008

Server 2008 ile beraber IIS 7.0'ın gelmesi özellikle ASP.NET geliştiricileri için büyük kolaylıklar sunuyor. Bu yazımda sizlere bu kolaylıklardan ufak bir demet sunarken özellikle HttpModule yazma ve IIS 7.0 tarafında kullanma konusuna değineceğim.

Web.Config içindeki hazine

Web.Config dosyası normalde biz yazılım geliştiricilerin sadece kendi uygulamaları ile ilgili ayarları sakladıkları bir yerdi. Oysa artık IIS içerisinde web uygulamanızın çalıştığı sitenin ayarları ile uygulamanızın ayarlarına aynı gözle bakabiliriz. Bunun bir sonucu olarak aynı site ile ilgili hem programatik ayarlar hem de IIS üzerindeki ayarlar artık Web.Config içerisinde saklanıyor. Gelin Visual Studio 2008 ile yarattığımız yeni bir ASP.NET sitesinin Web.Config dosyasının ufak bir bölümüne göz atalım.

    <!--

        The system.webServer section is required for running ASP.NET AJAX under Internet

        Information Services 7.0.  It is not necessary for previous version of IIS.

    -->

    <system.webServer>

      <validation validateIntegratedModeConfiguration="false"/>

      <modules>

        <remove name="ScriptModule" />

        <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

      </modules>

      <handlers>

        <remove name="WebServiceHandlerFactory-Integrated"/>

        <remove name="ScriptHandlerFactory" />

        <remove name="ScriptHandlerFactoryAppServices" />

        <remove name="ScriptResource" />

        <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"

            type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

        <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"

            type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

        <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

      </handlers>

    </system.webServer>

Gördüğünüz gibi normalden farklı olarak Web.Config içerisinde system.webServer adında bir tagımız var. Zaten tag ile ilgili gerekli açıklama İngilizce olarak hemen üstündeki yorum satırlarında yapılmış. system.webServer tagları arasındaki ayarlar sadece IIS 7.0 içerisinde geçerli olacak ve burada yapılan ayarlar ile bu uygulamanın çalışacağı IIS içerisinde sitedeki modüller ve HttpHandler'lar düzenlenmiş olacak. Böylece artık IIS 7.0'a bir site yükledikten sonra ayarlarını yapabilmeniz için harici bir web paneli kullanmanız veya sunucuda admin haklarına sahip olmanız gerekmiyor. Doğrudan neredeyse tüm ayarları Web.Config içerisinde düzenleyebiliyoruz.

Bu sistemin bir diğer avantajı ise kendi bilgisayarınızda çalıştığınız IIS üzerinde yaptığınız tüm ayarların otomatik olarak sunucuya Web.Config dosyasının atılması ile karşı tarafa da yansıması. Böylece "Benim bilgisayarımda çalışıyor ve sunucuya atınca çalışmıyor" şikayetlerine son geliyor diyebiliriz. Artık web sitenizi sunucuya yüklediğinizde tüm ayarlarını da karşı tarafa aktarmış oluyorsunuz.

Ufak bir örnek...

IIS içerisinde her web sitesinin otomatik olarak açılmaya ayarlı sayfaları vardır. Genelde bunlar default.htm, default.aspx gibi sayfalardır ve varsayılan ayarlar ile karşımıza çıkarlar. Böylece sunucuya bir site yüklediğinizde ilk olarak hangi sayfanın açılması gerektiği belirtilmiş olur. Eğer bu ayarı IIS 6.0'da değiştirmek isterseniz ya hosting sağlayıcınızın size bir yönetim paneli sunması lazım ya da yine size özel script hakları ayarlaması gerekir. Oysa IIS 7.0 içerisinde bu ayar Web.Config içerisinde saklanıyor. Nasıl mı?

Bilgisayarınızda IIS 7.0 Manager'ı açarak ASP.NET web sitenizi seçin ve IIS Manager içerisinde "Default Document" kısmına giderek yeni bir doküman ismi ekleyin.

IIS 7.0 içerisinde "Default Document" ayarı.
IIS 7.0 içerisinde "Default Document" ayarı.

Bu yaptığınız ayarı kendi bilgisayarınıza yaptınız ve sitenizi sunucuya yüklediğinizde tekrar yapmanız gerekecek! dersem de inanmayın. Çünkü IIS 7.0 içerisindeki bu ayar aslında söz konusu web sitesindeki Web.Config dosyasına yazıldı, aynen aşağıdaki gibi;

  <system.webServer>

        <defaultDocument>

            <files>

                <add value="ornek.aspx" />

            </files>

        </defaultDocument>

  </system.webServer>

Gördüğünüz gibi IIS içerisinde yeni bir "Default Document" eklemek için aslında tek yapmanız gereken Web.Config'de gerekli tanımlamaları yapmak. Bunun gibi daha birçok ayar tamamen Web.Config içerisine hapsedilmiş durumda. Böylece çoğu sorundan kolayca kurtulmak mümkün.

HttpModule yazalım...

IIS 7.0'ın çalışma yapısı ile IIS 6.0'ın yapısı arasında büyük fark var. IIS 6.0'da ISAPI önünde HttpModule yazabilirken IIS 7.0'da aslında çok daha düşük seviyelere inebiliyoruz. Örneğin ASP.NET ile yazdığınız bir HttpModule otomatik olarak sitenizdeki tüm HTML dosyalarını ve PHP sayfaları bile etkileyebiliyor. Bunun nedeni HttpModule'ün doğrudan IIS'in ana motoru üzerinde çalışıyor olması, yani tam bir entegrasyon söz konusu.

Bir HttpModule yazmak için basit bir şekilde yeni bir sınıf oluşturarak iHttpModule interface'ini implemente etmek yeterli olacaktır. Bu işlemi yaptıktan sonra HttpApplication üzerinden bir Request işleminin tüm event'larına ulaşabilirsiniz. Örneğin aşağıdaki gibi bir HttpModule web sayfası içerisinde açılan her sayfanın başına bir metin ekleyecektir.

[VB]

Imports Microsoft.VisualBasic

 

Public Class Class2

    Implements IHttpModule

 

    Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

 

    End Sub

 

    Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init

        Dim myapp = CType(context, HttpApplication)

        AddHandler myapp.BeginRequest, AddressOf myapp_BeginRequest

    End Sub

 

    Private Sub myapp_BeginRequest(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim myapp = CType(sender, HttpApplication)

        myapp.Context.Response.Write("Deneme")

    End Sub

End Class

[C#]

public class Class1 : IHttpModule

{

    public Class1()

    {

 

    }

 

    public void Dispose()

    {

        throw new NotImplementedException();

    }

 

    public void Init(HttpApplication context)

    {

        HttpApplication myapp = (HttpApplication)context;

        myapp.BeginRequest += new EventHandler(myapp_BeginRequest);

    }

 

    void myapp_BeginRequest(object sender, EventArgs e)

    {

        HttpApplication myapp = (HttpApplication)sender;

        myapp.Context.Response.Write("Deneme");

    }

}

Tabi bu gibi bir HttpModule'ü kullanabilmeniz için Web.Config içerisinde gerekli ayarlamayı da yapmanız gerekir.

  <system.webServer>

    <validation validateIntegratedModeConfiguration="false" />

    <modules>

            <remove name="WindowsAuthentication" />

            <remove name="UrlMappingsModule" />

            <remove name="UrlAuthorization" />

            <remove name="StaticFileModule" />

            <remove name="StaticCompressionModule" />

            <remove name="Session" />

            <remove name="ServiceModel" />

            <remove name="RoleManager" />

            <remove name="RequestMonitorModule" />

            <remove name="RequestFilteringModule" />

            <remove name="ProtocolSupportModule" />

            <remove name="Profile" />

            <remove name="OutputCache" />

            <remove name="IsapiModule" />

            <remove name="IsapiFilterModule" />

            <remove name="HttpLoggingModule" />

            <remove name="HttpCacheModule" />

            <remove name="FormsAuthentication" />

            <remove name="FileAuthorization" />

            <remove name="DirectoryListingModule" />

            <remove name="DefaultDocumentModule" />

            <remove name="DefaultAuthentication" />

            <remove name="CustomErrorModule" />

            <remove name="ConfigurationValidationModule" />

            <remove name="AnonymousIdentification" />

            <remove name="AnonymousAuthenticationModule" />

      <remove name="ScriptModule" />

            <add name="DefaultDocumentModule" />

            <add name="AnonymousAuthenticationModule" />

            <add name="YeniModul" type="Class12 />

    </modules>

  </system.webServer>

Yukarıdaki kod içerisinde IIS 7.0'ın mödüllerini düzenliyoruz. İlk olarak tüm modülleri pasif hale getirerek kullanmayacağımız işlemleri iptal ediyoruz. Sonrasında da sadece üç modül istiyoruz. Bunlardan DefaultDocumentModule otomatik olarak varsayılan dokümanın açılmasını sağlıyor. AnonymousAuthenticationModule ise anonim ulaşımı sağlıyor. Sonrasında da bizim yazdığımız HttpModule'ün sınıf ismini taşıyan yeni modülümüzü ekliyoruz. Böylece artık bu web sitesi içerisindeki tüm isteklerde bu modül de çalışacak.

İsterseniz tüm bu modül ayarlarını otomatik olarak IIS Manager içerisinde de yapabilirsiniz. Ayarlamaları yapacağınız web sitesini seçtikten sonra "Modules" kısmına geçerek tüm modülleri silebilir, sağ menüden "Add Managed Module" diyerek site içerisinde yazılmış modülleri bularak ekleyebilirsiniz.

Başka neler var?

IIS 7.0 içerisinde FastCGI ile PHP desteği geliyor. Hatta PHP tarafında da yukarıdaki HttpModule'lerin çalıştığını düşünürseniz PHP ile tüm bu modülleri kullanabileceğiniz sonucuna varabilirsiniz. Örneğin ASP.NET Forms Authentication modülünü PHP ile kullanabilirsiniz hatta böylece yarısı PHP yarısı ASP.NET ile yazılmış bir sitede global Authentication sistemi bile kurmuş olursunuz. Daha bu gibi bir çok esnekliğe sahip olan IIS 7.0 ile yazılım geliştirme ortamı arıyorsanız Vista ile beraber IIS 7.0'ın geldiğini de hatırlatmak isterim.

Hepinize kolay gelsin.

Wednesday, August 20, 2008 7:57:03 AM (GTB Standard Time, UTC+02:00)  #    Comments [9]   ASP.NET 3.5 | IIS 7.0  | 
 Thursday, June 19, 2008

Çok önceleri İngilizce bloguma yazdığım fakat ilginç bir şekilde Türkçe'ye yazmadığım bir araçtan bahsetmek istiyorum. Özellikle sunumlarda çok işime yarıyor ve sıkça kullanıyorum. En son Soru Merkezi'nde de bir arkadaşımız sorduğu için buraya hemen yazmaya karar verdim.

Gördüğünüz gibi aslında araç çok basit bir iş yapıyor. Sisteminizde herhangi bir klasöre sağ tuş ile tıkladığınızda karşınıza gelen menüden doğrudan ASP.NET Development Server çalıştırabiliyorsunuz. Bu da ortalama 3 saniye içerisinde o klasörün içeriğini gösteren bir IIS anlamına geliyor. Özellikle hızlı bir şekilde örnekleri veya uygulamaları incelemek için çok başarılı bir araç. Visual Studio ile projeyi açıp F5'e basmaktan veya klasör için IIS üzerinde ayar yapmaktan pratik olduğu kesin.

ASP.NET Development Server Kısayol Aracı - 19062007_1.msi (355 KB)

Uygulamayı yazan Infragistics'ten J. Ambrose Little'a buradan teşekkürlerimizi de yolluyoruz ;)

Thursday, June 19, 2008 8:53:36 PM (GTB Standard Time, UTC+02:00)  #    Comments [10]   ASP.NET | ASP.NET 3.5  | 
 Monday, June 09, 2008
 Wednesday, June 04, 2008

WPF teknolojisi Windows uygulamalarında bize iki ve üç boyutlu animasyonlarla zengin kullanıcı arayüzleri hazırlama şansı tanırken WPF Browser Application (XBAP) yapısı ile beraber bu uygulamaları istersek İnternet Tarayıcısı içerisine de taşıyabiliyoruz. Tabi bu noktada istemci tarafında ufak ve sıkıcı bir ihtiyacımız var; .NET Framework. WPF Browser Application projenizi geliştirirken kullanmış olduğunuz .NET Framework sürümünün istemcilerde de yüklü olması şart. Browser Application şablonu Expression Blend ile beraber gelmese de Visual Studio içerisinde böyle bir proje yaratılarak aynı proje rahatlıkla Expression Blend ile beraber açılabiliyor.

Örneğimizde basit bir uygulama yaparak iki metin kutusu, bir düğme ve bir de etiket (TextBlock) kullanacağız. TextBox'lar içerisine yazılan değerler bir web servisine gönderilecek ve web servisi söz konusu değerlerin toplamını alarak uygulamamıza geri verecek. Normalde tabi ki çok basit bir şekilde bu işlem istemci tarafında WPF ile halledilebilir fakat bizim amacımız bir web servisi kullanarak WPF Browser Application içerisinden sunucuya veri göndererek veri alabiliyor olmak. Böylece rahatlıkla sunucu tarafındaki uygulama da kendisine gelen verilere göre herhangi bir veritabanı sistemini sorgulayarak uygun bilgileri geri döndürebilecektir.

WPF Browser Application'ı tasarlayalım...

İlk olarak uygulamamızı Visual Studio içerisinde "File / New Project" menüsünden "WPF Browser Application" proje şablonunu seçerek yarattıktan sonra görsel tasarımını tamamlayalım. Uygulama içerisine otomatik olarak yerleştirilecek olan ana sayfamız "Page1.XAML" dosyasını doğal olarak Expression Blend ile düzenlememiz gerekiyor. Bunun için Visual Studio içerisinde yarattığımız bu projeyi Expression Blend ile de açarak XAML dosyasını düzenlememiz gerek.

<Page x:Class="Page1"

  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  Title="Page1">

    <Grid Width="250" Height="400">

      <Grid.RowDefinitions>

        <RowDefinition Height="0.168*"/>

        <RowDefinition Height="0.155*"/>

        <RowDefinition Height="0.132*"/>

        <RowDefinition Height="0.545*"/>

      </Grid.RowDefinitions>

      <TextBox Text="TextBox" TextWrapping="Wrap" x:Name="Kutu1"/>

      <TextBox Grid.Row="1" Text="TextBox" TextWrapping="Wrap" x:Name="Kutu2"/>

      <Button Grid.Row="2" Content="Button" HorizontalAlignment="Center" Width="100" Height="40" x:Name="Dugme"/>

      <Label Margin="8,8,8,0" VerticalAlignment="Top" Height="27" Grid.Row="3" Content="Label" x:Name="Etiket"/>

    </Grid>

</Page>

Hazırlamış olduğumuz uygulamanın yukarıdaki XAML kodunu incelediğinizde ekranda iki adet metin kutusu, bir düğme ve bir de TextBlock olduğunu göreceksiniz. Tüm bu kontrolleri bir Grid içerisine yerleştirerek ekranda sabit bir şekilde görünmelerini sağlıyoruz.

Web servisimizi hazırlayalım

Sıra geldi web servisimizi hazırlamaya. Bunun için Visual Studio içerisinde üzerinde çalıştığımız Solution yapısına yeni bir ASP.NET 3.5 web projesine ekleyeceğiz. "File / Add / New Project" menüsünden "ASP.NET Web Application" seçeneğinden ilerleyebilirsiniz. Yarattığımız web sitesine "WebService1.asmx" adında yeni bir web servisi ekleyerek aşağıdaki şekilde kodumuzu yerleştirelim.

[VB]

Imports System.Web.Services

Imports System.Web.Services.Protocols

Imports System.ComponentModel

 

<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _

<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _

<ToolboxItem(False)> _

Public Class WebService1

    Inherits System.Web.Services.WebService

 

    <WebMethod()> _

    Public Function Topla(ByVal x As Integer, ByVal y As Integer) As Integer

        Return x + y

    End Function

 

End Class

[C#]

using System;

using System.Collections;

using System.Linq;

using System.Web;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.Xml.Linq;

 

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class WebService : System.Web.Services.WebService

{

 

    public WebService()

    {

    }

 

    [WebMethod]

    public int Topla(int x, int y)

    {

        return x + y;

    }

}

Sıra geldi bu web servisini WPF Browser Application içerisinde kullanmaya.

Reference ekleyelim

Web servisinizi hazırladıktan sonra rahatlıkla WPF Browser Application projenize sağ tıklayarak ve "Add Service Reference" diyerek web servisinizi bulup referans olarak ekleyebilirsiniz. Sonrasında normal bir Winforms uygulamasında olduğu gibi uzaktaki servisi kullanabilirsiniz.

[VB]

Class Page1

    Private Sub Dugme_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Dugme.Click

        Dim Servis = New ServiceReference1.WebService1SoapClient

        Etiket.Content = Servis.Topla(Kutu1.Text, Kutu2.Text)

    End Sub

End Class

[C#]

    public partial class Page1 : Page

    {

        private void Dugme_Click(object sender, RoutedEventArgs e)

        {

            ServiceReference1.WebServiceSoapClient Servis = new WpfBrowserApplication1.ServiceReference1.WebServiceSoapClient();

            Etiket.Content = Servis.Topla(int.Parse(Kutu1.Text), int.Parse(Kutu2.Text)).ToString();

        }

    }

Yukarıdaki kodumuzda basit bir şekilde ServiceReference1 üzerinde servisimizi tanımlayarak içerisindeki Topla metodunu kullanıyoruz. Sonucu da WPF uygulamasında Etiket adındaki TextBlock içerisine yazdırıyoruz.

Sorunlar baş gösteriyor...

Fakat ufak bir sorun var. WPF Browser Application'ı Visual Studio içerisinden çalıştırdığınızda doğrudan dosya sistemi üzerinden çalıştırılacaktır, yani IIS veya ASP.NET Development Server devreye girmeyecektir. Oysa bizim web servisi ASP.NET Development Server üzerinde çalışmak zorunda. Visual Studio'nun web servisini ASP.NET Development Server üzerinden çalıştırırken WPF Browser Application'ı dosya sisteminden çalıştırması bizi büyük bir sorunla baş başa bırakacak; "Güvenlik".

Artık hem AJAX hem de Silverlight nedeniyle çoğumuzun bildiği üzere istemci tarafında bir alan adından yola çıkarak başka bir alan adına bağlanıp veri alımı veya gönderimi yapamazsınız. WPF Browser Application dosya sisteminden başlatıldığında maalesef web servisini "başka bir alan adında" olarak algılayacağı için veri trafiği gerçekleşmeyecektir. Bu durumda yapılacak şey belli; WPF Browser Application'ı bizim web servisi ile aynı projeye "output" ettirmemiz, aslında Publish etmemiz gerek.

WPF Browser Application projenize sağ tuş ile tıklayın ve "Publish" komutu verin. Yayınlanacak konum olarak web servisinize ait dosyaların bulunduğu ASP.NET sitenizin ana klasörünü gösterin. Böylece WPF Browser Application hazırlanarak web sitenize yerleştirilmiş olacak. Şimdi ASP.NET Development Server üzerinden XBAP dosyasını açabilir ve uygulamanızı gönül rahatlığı ile kullanabilirsiniz.

Hepinize kolay gelsin.

Wednesday, June 04, 2008 6:07:02 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET 3.5 | WPF  | 
 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  | 
 Saturday, May 31, 2008

Varsayalım ki web sitenizde belirli aktiviteleri paylaşıyorsunuz veya belki de toplantıları. İnsanların buluşma tarihlerini bir kenara not almalarını ve sonra da günü geldiğinde hatırlamalarını istiyorsunuz. Artık çoğu kullanıcının bir şekilde dijital ortamda takvim tuttuğunu varsayarsak neden onlara söz konusu aktivitelerini hızlı bir şekilde takvimlerine ekleme olanağı tanımlayalım? Şükür ki bu konuda genel geçer bir standart var; VCalendar!

VCalendar standardı çoğu dijital takvim uygulaması ile uyumlu bir standart. Yapacağımız örnekte bir Generic Handler (ashx) kullanacağız. Söz konusu handler bize VCalendar davetiye dosyaları oluşturarak verecek. Siz uygulamalarınızda ashx dosyasına QueryString üzerinden parametreler göndererek farklı VCalendar dosyaları oluşturabilirsiniz.

        context.Response.ContentType = "application/download"

İlk olarak yukarıdaki şekilde istemciye göndereceğimiz verinin download edilmesi gereken bir uygulama dosyası olduğunu belirtelim. Böylece istemcideki tarayıcı bir download penceresi açacaktır. VCalendar dosyaları vcs uzantılıdır, istemciye doğrudan gönderdiğimiz istemcide kullanıcı bunu ister Outlook ile açar ister farklı bir uygulama ile kullanır, karar tamamen kullanıcıya kalmış.

[VB]

        Dim BasTarih As Date = Date.Now

        Dim SonTarih As Date = Date.Now.AddDays(1)

        Dim Konum As String = "İstanbul - MS Binası"

        Dim Konu As String = "VCalendar Toplantısı"

        Dim Detay As String = "Toplantı VCalendar standartları görüşülecek. "

[C#]

        System.DateTime BasTarih = System.DateTime.Now;

        System.DateTime SonTarih = System.DateTime.Now.AddDays(1);

        string Konum = "İstanbul - MS Binası";

        string Konu = "VCalendar Toplantısı";

        string Detay = "Toplantı VCalendar standartları görüşülecek. ";

Bir sonraki adımda yukarıdaki şekilde parametrelerimizi tanımlayalım. Bu parametreleri siz uygulamalarınızda veritabanına bağlayabilirsiniz. Yaratacağımız VCalendar dosyası buradaki bilgileri içerecek.

[VB]

        Dim BirStream As New IO.MemoryStream()

        Dim Yazici As New IO.StreamWriter(BirStream)

        Yazici.AutoFlush = True

[C#]

        System.IO.MemoryStream BirStream = new System.IO.MemoryStream();

        System.IO.StreamWriter Yazici = new System.IO.StreamWriter(BirStream);

        Yazici.AutoFlush = true;

VCalendar dosyaları özünde text (metin) bazlı dosyalardır. O nedenle aslında sunucu tarafında bir metin yaratarak Binary olarak istemciye göndereceğiz. Bu nedenle istemciye göndereceğimiz tüm içeriği oluştururken elimizde bir Stream ve StreamWriter olması gerekiyor. Söz konusu Stream herhangi bir konuma yazdırılmayacağı için havada bir MemoryStream yaratarak ilerliyoruz. Söz konusu StreamWriter'ın AutoFlush özelliğini True olarak aktardığımızda artık tüm içerik otomatik olarak Stream'e aktarılıyor olacak.

        Yazici.WriteLine("BEGIN:VCALENDAR")

        Yazici.WriteLine("PRODID:-//daron.yondem.com")

        Yazici.WriteLine("BEGIN:VEVENT")

Yukarıdaki VCalendar standartlarına uygun dosyamızı yaratmaya başladık. PRODID özelliğine aktardığınız değer çok önemli değil. Aslında bu VCalendar dosyasını yaratan programın adını içermesi yeterli.

[VB]

        Yazici.WriteLine("DTSTART:" & BasTarih.ToUniversalTime.ToString("yyyyMMdd\THHmmss\Z"))

        Yazici.WriteLine("DTEND:" & SonTarih.ToUniversalTime.ToString("yyyyMMdd\THHmmss\Z"))

        Yazici.WriteLine("LOCATION:" & Konum)

        Yazici.WriteLine("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" & Detay)

        Yazici.WriteLine("SUMMARY:" & Konu)

[C#]

        Yazici.WriteLine("DTSTART:" + BasTarih.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));

        Yazici.WriteLine("DTEND:" + SonTarih.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));

        Yazici.WriteLine("LOCATION:" + Konum);

        Yazici.WriteLine("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" + Detay);

        Yazici.WriteLine("SUMMARY:" + Konu);

Gördüğünüz gibi neredeyse tüm parametrelerimizi burada dosyamıza ekledik. Önemli olan noktalardan biri tüm tarih bilgilerinin ilk olarak UniversalTime'a yani global olarak geçerli zaman dilimine uyarlanması gerektiği. İkincisi ise tarih dosyaya yazdırılırken uyulması gereken format. Sonraki satırlarda diğer parametrelerimizi de aktardıktan sonra devam edebiliriz.

[VB]

        Yazici.WriteLine("PRIORITY:3")

 

        Yazici.WriteLine("BEGIN:VALARM")

        Yazici.WriteLine("TRIGGER:-PT30M")

        Yazici.WriteLine("ACTION:DISPLAY")

        Yazici.WriteLine("DESCRIPTION:" & Konu)

        Yazici.WriteLine("END:VALARM")

 

        Yazici.WriteLine("END:VEVENT")

        Yazici.WriteLine("END:VCALENDAR")

[C#]

        Yazici.WriteLine("PRIORITY:3")

 

        Yazici.WriteLine("BEGIN:VALARM")

        Yazici.WriteLine("TRIGGER:-PT30M")

        Yazici.WriteLine("ACTION:DISPLAY")

        Yazici.WriteLine("DESCRIPTION:" + Konu)

        Yazici.WriteLine("END:VALARM")

 

        Yazici.WriteLine("END:VEVENT")

        Yazici.WriteLine("END:VCALENDAR")

Kodumuzun ilk satırında bu aktivitenin ne kadar önemli olduğuna dair bir değer aktardıktan sonra aktivite ile ilgili bir alarm ayarlıyoruz. PT30M ayarı ile aktiviteden yarım saat önce kullanıcının uyarılması gerektiğini belirtmiş olduk. Siz bu ayarları istediğiniz gibi değiştirebilirsiniz. Son olarak hem VEVENT gem de VCALENDAR'ı kapatarak dosyamızı sonlandırıyoruz.

[VB]

        context.Response.AppendHeader("Content-Disposition", "attachment; filename=aktivite.vcs")

        context.Response.AppendHeader("Content-Length", BirStream.Length.ToString())

        context.Response.BinaryWrite(BirStream.ToArray())

[C#]

        context.Response.AppendHeader("Content-Disposition", "attachment; filename=aktivite.vcs");

        context.Response.AppendHeader("Content-Length", BirStream.Length.ToString());

        context.Response.BinaryWrite(BirStream.ToArray());

Sıra geldi oluşturduğumuz dosyayı istemciye göndermeye. İlk olarak istemciye gönderdiğimiz HTTPResponse'a bazı header bilgileri eklememiz gerekiyor. Bunlardan ilki istemcinin aldığı dosyayı hangi isimle açacağı. Bizim örneğimizde dosya adı aktivite.vcs şeklinde yer alıyor. İkincisi ise oluşturduğumuz dosyanın boyutu. Son olarak Response.BinaryWrite ile elimizdeki Stream'i istemciye gönderiyoruz.

Eğer istemci bu adresi doğrudan açarsa karşısına bir VCalendar download penceresi gelecektir. Yarattığımız ashx dosyasını farklı aspx dosyaları içerisinde linkleyerek kullanıcıların linklere bastıklarında VCalendar dosyalarını indirebilmelerini sağlayabilirsiniz.

Generic Handler'ımızın son hali ile aşağıdaki şekilde;

[VB]

<%@ WebHandler Language="VB" Class="vcalendar" %>

 

Imports System

Imports System.Web

 

Public Class vcalendar : Implements IHttpHandler

 

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

        context.Response.ContentType = "application/download"

 

        Dim BasTarih As Date = Date.Now

        Dim SonTarih As Date = Date.Now.AddDays(1)

        Dim Konum As String = "İstanbul - MS Binası"

        Dim Konu As String = "VCalendar Toplantısı"

        Dim Detay As String = "Toplantı VCalendar standartları görüşülecek. "

 

        Dim BirStream As New IO.MemoryStream()

        Dim Yazici As New IO.StreamWriter(BirStream)

        Yazici.AutoFlush = True

 

        Yazici.WriteLine("BEGIN:VCALENDAR")

        Yazici.WriteLine("PRODID:-//daron.yondem.com")

        Yazici.WriteLine("BEGIN:VEVENT")

 

        Yazici.WriteLine("DTSTART:" & BasTarih.ToUniversalTime.ToString("yyyyMMdd\THHmmss\Z"))

        Yazici.WriteLine("DTEND:" & SonTarih.ToUniversalTime.ToString("yyyyMMdd\THHmmss\Z"))

        Yazici.WriteLine("LOCATION:" & Konum)

        Yazici.WriteLine("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" & Detay)

        Yazici.WriteLine("SUMMARY:" & Konu)

 

        Yazici.WriteLine("PRIORITY:3")

 

        Yazici.WriteLine("BEGIN:VALARM")

        Yazici.WriteLine("TRIGGER:-PT30M")

        Yazici.WriteLine("ACTION:DISPLAY")

        Yazici.WriteLine("DESCRIPTION:" & Konu)

        Yazici.WriteLine("END:VALARM")

 

        Yazici.WriteLine("END:VEVENT")

        Yazici.WriteLine("END:VCALENDAR")

 

        context.Response.AppendHeader("Content-Disposition", "attachment; filename=aktivite.vcs")

        context.Response.AppendHeader("Content-Length", BirStream.Length.ToString())

        context.Response.ContentType = "application/download"

        context.Response.BinaryWrite(BirStream.ToArray())

    End Sub

 

    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable

        Get

            Return False

        End Get

    End Property

 

End Class

[C#]

<%@ WebHandler Language="C#" Class="Handler" %>

 

using System;

using System.Web;

 

public class Handler : IHttpHandler {

 

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "application/download";

 

        System.DateTime BasTarih = System.DateTime.Now;

        System.DateTime SonTarih = System.DateTime.Now.AddDays(1);

        string Konum = "İstanbul - MS Binası";

        string Konu = "VCalendar Toplantısı";

        string Detay = "Toplantı VCalendar standartları görüşülecek. ";

 

        System.IO.MemoryStream BirStream = new System.IO.MemoryStream();

        System.IO.StreamWriter Yazici = new System.IO.StreamWriter(BirStream);

        Yazici.AutoFlush = true;

 

        Yazici.WriteLine("BEGIN:VCALENDAR");

        Yazici.WriteLine("PRODID:-//daron.yondem.com");

        Yazici.WriteLine("BEGIN:VEVENT");

 

        Yazici.WriteLine("DTSTART:" + BasTarih.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));

        Yazici.WriteLine("DTEND:" + SonTarih.ToUniversalTime().ToString("yyyyMMdd\\THHmmss\\Z"));

        Yazici.WriteLine("LOCATION:" + Konum);

        Yazici.WriteLine("DESCRIPTION;ENCODING=QUOTED-PRINTABLE:" + Detay);

        Yazici.WriteLine("SUMMARY:" + Konu);

 

        Yazici.WriteLine("PRIORITY:3");

 

        Yazici.WriteLine("BEGIN:VALARM");

        Yazici.WriteLine("TRIGGER:-PT30M");

        Yazici.WriteLine("ACTION:DISPLAY");

        Yazici.WriteLine("DESCRIPTION:" + Konu);

        Yazici.WriteLine("END:VALARM");

 

        Yazici.WriteLine("END:VEVENT");

        Yazici.WriteLine("END:VCALENDAR");

 

        context.Response.AppendHeader("Content-Disposition", "attachment; filename=aktivite.vcs");

        context.Response.AppendHeader("Content-Length", BirStream.Length.ToString());

        context.Response.BinaryWrite(BirStream.ToArray());

    }

 

    public bool IsReusable {

        get {

            return false;

        }

    }

 

}

Hepinize kolay gelsin.

Saturday, May 31, 2008 12:53:37 PM (GTB Standard Time, UTC+02:00)  #    Comments [7]   ASP.NET | ASP.NET 3.5  | 
 Friday, May 30, 2008

ASP.NET uygulamalarında Date.Now() gibi çoğu sınıf o anki CurrentCulture üzerinden gerekli bilgileri alarak çalışır. Yani uygulamanın çalıştığı makinen Regional Settings'i Türkiye'ye göre ayarlanmış ise tarih bilgisi ona göre gelecektir. Bu durum genelde sıkıntı yaratmasa da özellikle yurt dışından hosting (barındırma) hizmeti aldığınızda sıkıntılar baş göstermeye başlar. Eğer uygulamanız farklı ülkelere ve dillere hizmet edecek şekilde bir altyapıya sahip değilse veya buna gerek yoksa aslında uygulamanın her şart altında belirli bir CurrentCulture ile çalışmasını isteyebilirsiniz.

Varsayalım satın aldığınız hosting firması yurt dışında olduğu için sunucularını yüklerken "Regional Settings"de sunucu ayarı olarak İngilizceyi seçtiler. Bu durumda Date.Now() dahil kullandığınız çoğu sınıf geriye farklı formatlarda değerler döndürecektir. Örneğin bizde sıfırdan küçük sayılar virgül ile ayrılırken İngilizce ayarlanmış bir sunucuda nokta ile ayrılacaktır. Bu gibi sıkıntıları toptan çözmek için Web.Config içerisinde yapabileceğiniz bir ayar var.

<system.web>

  <globalization culture="tr-TR" uiCulture="tr-TR" />

</system.web>

Yukarıdaki şekilde Web.Config içerisindeki System.Web tagları arasına uygun satırı yerleştirmeniz yeterli. Artık tüm uygulama herşeyden bağımsız olarak Türkiye'ye ve Türkçe'ye göre çalışacaktır.

<%@ Page UICulture="tr-TR" Culture="tr-TR" %>

Ayrıca isterseniz bu ayarı her aspx (web form) için ayrı ayrı da yapabilirsiniz. Yukarıdaki şekilde herhangi bir web forumun mark-up kısmına Page için UICulture ve Culture ayarlarını tanımlayabilirsiniz.

Hepinize kolay gelsin...

Friday, May 30, 2008 12:10:17 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET | ASP.NET 3.5  | 
 Thursday, May 22, 2008

Herhangi bir web sitesine bir ASP.NET uygulaması yerleştirdiğinizde otomatik olarak uygulama ile beraber Web.Config dosyasını da sunucuya yerleştirmiş olursunuz. Bazı durumlarda (benim blogda olduğu üzere) birden çok ASP.NET uygulamasını tek bir alan adı altında çalıştırmanız gerekebilir. Bu uygulamaları iç içe klasörlerle ayırmak vs pek işe yaramaz çünkü kök klasörde bulunan Web.Config içerisinde tüm ayarlar alt klasörleri de otomatik olarak etkiler. Yani bir "inheritance" durumu söz konusudur.

Kök dizindeki Web.Config içerisindeki tüm ayarları tek tek iç dizinlerdeki Web.Config'ler içerisinde "remove" etmek mümkün fakat çok zahmetli bir iş. Diğer yandan bazı durumlarda farklı ASP.NET sürümlerini de aynı site içerisinde kullanmak isteyebilirsiniz, örneğin benim blog ASP.NET 2.0 kullanırken aktivite kayıt uygulamam ASP.NET 3.5 ile hazırlandı.

İşin kolayı!

Herhangi bir Web.Config dosyası içerisindeki ayarları "inheritance" ile alt klasörlerini geçmesini istemiyorsanız aslında yapacağınız çok ufak bir ayar var.

<location path="." inheritInChildApplications="false">

<system.web>

<!--Tüm ayarlar burada-->

</system.web>

</location>

Web.Config dosyanız içerisinde tüm ayarların bulunduğu System.Web taglarını ayrıca bir location tagı içerisine alarak söz konusu location tagının da inheritInChildApplications özelliğini False olarak ayarlarsanız artık kök dizindeki ayarlarınız diğer dizinler tarafından kullanılmayacaktır. Böylece rahatlıkla yeni uygulamalarınızı aynı alan adına yükleyebilirsiniz.

Hepinize kolay gelsin...

Thursday, May 22, 2008 11:04:24 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET | ASP.NET 3.5  | 
 Saturday, April 19, 2008

.NET Framework 3.0 ile beraber gelen WPF, WCF ve WF sonrasında VS 2008 ve .NET Framework 3.5 derken aslında epey bir yenilik ile karşı karşıya kaldık. Bu konularda Microsoft'un sertifikasyonlarında şu ana kadar yeni bir sistem oluşturulmamıştı, zaten bu konularda sertifikasyon sınavları da yoktu. Oysa artık sizlere güzel haberlerim var; Visual Studio 2008 ile beraber yeni sertifikasyonlar ve sınavlar tam olarak belli oldu.

Visual Studio 2008 MCTS Sertifikasyon Sınavları
Visual Studio 2008 MCTS Sertifikasyon Sınavları

Yukarıdaki görselde de görebileceğiniz üzere toplam altı adet yeni MCTS sertifikasyonu söz konusu. Her biri özellikle .NET Framework 3.5 olarak isimlendirimiş durumda. WPF, WCF ve WF'i görmek gerçekten hoş. Diğer yandan ADO.NET'in ayrı bir sertifikasyon yolu olarak seçilmesi ise gerçekten ilginç. Yukarıdaki sınavlardan 70-502,503 ve 504 şu an açık durumda. Diğerleri önümüzdeki aylarda açılacak.

Visual Studio 2008 MCPD Sertifikasyon Sınavları
Visual Studio 2008 MCPD Sertifikasyon Sınavları

MCPD yolunda da ilginç gelişmeler var. Windows Developer ve EA Developer'ın sonuna .NET Framework'ün sürüm numarası eklenmiş. Böylece hangi sürümün yazılım geliştiricisi olduğunuz doğrudan belli olacak. Web Developer sertifikasyonu ise artık yok, onun yerine ASP.NET Developer 3.5 şeklinde yeni bir sertifikasyon var. Aslında bu çok doğru bir adım olmuş. Çünkü Web Developer adı çok daha geniş kapsamlı, oysa sınavlarda doğal olarak sadece Microsoft ürünleri soruluyor. O nedenle ASP.NET Developer adı bence çok daha uygun olmuş.

Visual Studio 2008'e Upgrade Sertifikasyon Sınavları
Visual Studio 2008'e Upgrade Sertifikasyon Sınavları

Her zamanki gibi eski sertifikalı uzmanlar için "upgrade" sınavları da olacak. Yükseltme sınavları ile ilgili detayları yukarıdan inceleyebilirsiniz. Bu sınavların da daha hiçbiri yayında değil.

Yeni sertifikasyonlar ve sınavlar gerçekten güzel organize edilmiş. Ben heyecanla Expression ürün ailesi ve Silverlight sınavlarını bekliyorum. Umarım WPF, WCF ve WF için beklediğimiz kadar beklemek zorunda kalmayız.

Hepinize kolay gelsin.

Saturday, April 19, 2008 8:19:21 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   .NET Framework 3.0 | .NET Framework 3.5 | ASP.NET 3.5 | Visual Basic 2008 | Visual Studio 2008 | WCF | WPF | WF  | 
 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  | 
 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  | 
 Friday, February 29, 2008

Dün verdiğim sözü tutmanın zamanı geldi. Sizlerle kodlarını paylaştığım mini projenin içerisindeki önemli birkaç noktayı öne çekerek mini bir XLINQ ve VB şovu yapmak istiyorum :) Üzgünüm C# cılar .Element veya .Elements gibi metodlarla uğraşmak zorunda kalacaklar ve benim güzel VB'mi bırakarak ek metotlar kullanmaya niyetim yok :) Ayrıca paylaştığım proje de VB ile yazılmış durumda o nedenle bu yazı da full VB olacak. (Sektörde benim kadar agresif C#'a saldıran yok :) Allah sonumu hayır etsin:) Bu arada C#'ı severim yani ama herkes yerinde sağ olsun ;))

Kodlara geçmeden önce gelin projenin kullandığı XML dosyalarının yapısına bir göz atalım.

<?xml version="1.0" encoding="utf-8"?>

<Olay>

  <Tag>223257</Tag>

  <Icerik>1112567</Icerik>

  <Katilimci>0</Katilimci>

  <Katilan Adi="Ercan Altuğ Yılmaz" Mail="hebele@gubele.com" Tel="0900900900:)" />

  <Katilan Adi="İbrahim Demir" Mail="hebele@gubele.com" Tel="0900900900" />

</Olay>

Projedeki her bir aktivite için aktivitenin TAG ozelliği ile aynı isme sahip bir XML dosyası oluşturuluyor. Ayrıca TAG bilgisi neden dosyanın içerisine de kaydetmişim bilmiyorum :) Şimdi kodumu okurken saçma olduğunu gördüm. Neyse gece yarısı aceleyle herhangi bir planlama olmadan kod yazılırsa böyle olur :) Yukarıdaki gibi yaratacağımız XML dosyalarında Olay kök elementinin içerisinde Icerik kısmına söz konusu aktivite ile ilgili açıklamaları içerecek olan HTML kodları yerleştirilecek. Maksimum katılımcı sayısı Katilimci tagları arasına yazılacak. Sonrasında aktiviteye kayıt olan herkesin bilgisi Katilan taglarındaki gibi bu dosyaya eklenecek.

kayit.aspx

Bu dosyayı herhangi bir kaydı göstermek veya düzenlemek için kullanacağız. Eğer bu dosyaya herhangi bir aktivitenin tag bilgisi adres üzerinden ?tag=aktivite şeklinde aktarılmış ise söz konusu aktivitenin bilgileri gelecek ve sonrasında değiştirilebilecek. Aksi halde yeni bir aktivite yaratılacak. Önemli olan birinci nokta yeni bir aktivite için yeni bir XML dosyası yaratarak içerisine gerekli bilgileri ekleyebilmek.

Dim Belge As New XDocument

Dim root As New XElement("Olay")

root.Add(New XElement("Tag", TextBox2.Text))

root.Add(New XElement("Icerik", TextBox1.Text))

root.Add(New XElement("Katilimci", TextBox3.Text))

Belge.Add(root)

Belge.Save(Server.MapPath("App_Data") & "\" & TextBox2.Text & ".xml")

Yukarıdaki kodda bir XDocument yaratarak içerisine XElement'ler ekliyoruz. Elementleri eklerken isterseniz değerlerini de ikinci parametre olarak verebiliyorsunuz. Son olarak da XDocument'ın Save metodu ile dosyayı kaydediyoruz. Olay aslında bu kadar basit. Kullanıcının kutulara girdiği metinleri herhangi bir kontrolden geçirmiyoruz, çünkü birincisi yönetim panelindeyiz. Yani güvenli bir yerdeyiz, ikincisi bu projede buna zamanımız yok :D Ama aklınızda olsun halka açık sitelerde böyle girişleri script injection için kontrol etmek gerek.

Peki var olan bir dosyayı okuyup ekranda nasıl gösteririz?

Dim Belge = XDocument.Load(Server.MapPath("App_Data") & "\" & Request.QueryString("tag") & ".xml")

TextBox2.Text = Belge.<Olay>.<Tag>.Value

TextBox3.Text = Belge.<Olay>.<Katilimci>.Value

TextBox1.Text = Belge.<Olay>.<Icerik>.Value

 

GridView1.DataSource = From Gelenler In Belge.<Olay>.<Katilan> Select Gelenler.@Adi, Gelenler.@Mail, Gelenler.@Tel

GridView1.DataBind()

İlk satırda gördüğünüz üzere XDocument sınıfının Load metodu ile dosyamızı okuyarak Belge değişkenine aktarıyoruz. Bu noktada özellikle VB ile ilgili late-binding olayından bahsetmek istiyorum. Dikkatinizi çektiyse Belge değişkenini tanımlarken herhangi bir değişken tipi belirtmedim. Bu durum kod çalışırken run-time esnasında değişkenin tipi belli olacak şeklinde çalışmıyor. Eğer böyle çalışsaydı yıllar önceki VB'deki performans kaybını yaşamış olurduk. Tam tersine biz bu kodumuzda Belge değişkeninin tipini belirtmesek de compiler bunu algılayarak gerekli tanımlamaları yapacaktır. Zaten yukarıdaki manzarada bile Visual Studio içerisinde Belge değişkeninin üzerine fare ile geldiğimizde değişkenin tipinin algılandığını görebiliyoruz. Buradan yola çıkıp "hiçbir değişkenin tipini tanımlamayın" diye bir şey söylemiyorum, bu büyük bir hata olur fakat tipi belli bir şey için de uğraşmaya gerek yok :) (VB'cilerdeki bu tembellik nedir ya :D)

GridView ile ilgili kısma geçerken bu Grid'in ne işe yarayacağını baştan söyliyeyim. Tüm kolonları otomatik yaratılmak üzere ayarlanmış bir Grid olarak bu arkadaşımızın görevi aktiviteye kayıt olanların bilgilerini göstermek. Bunun için doğrudan Belge değişkenimize bir LINQ sorgusu göndererek istediğimiz bilgileri kolonlar şeklinde alıyoruz. Ne kadar kolay değil mi?

default.aspx

Proje içerisinde değinmek istediğim bir diğer dosya da ana kayıt sayfası. Bu sayfada ilk olarak söz konusu aktiviteye kayıt olan kişi sayısını bularak maksimum sayının altında olup olmadığını kontrol etmemiz gerekiyor. Yani XML dosyası içerisinde Katilan taglarını saymamız gerek.

If Belge.<Olay>.<Katilimci>.Value <= Belge.<Olay>.<Katilan>.Count And Belge.<Olay>.<Katilimci>.Value <> 0 Then

Label1.Text = "Aktivite için maksimum kayıt sayısına ulaşıldı. Üzgünüz, bir dahakine."

kayittablo.Visible = False

Else

Belge değişkenimize XML dosyasını yükledikten sonra doğrudan Olay'ın Katilimci değerinden maksimum katılımcı sayısını alabiliyoruz. O ana kadar toplam kaç kişinin kayıt olduğunu, yani Katilan taglarının sayısını da doğrudan Count metodu ile alabiliyoruz. XLINQ cidden süper bir şey, eskiden ömür tüketirdi bu işler.

Dim Belge = XDocument.Load(Server.MapPath("App_Data") & "\" & Request.QueryString("event") & ".xml")

Belge.<Olay>.SingleOrDefault.Add(New XElement("Katilan", New XAttribute("Adi", TextBox1.Text), New XAttribute("Mail", TextBox2.Text), New XAttribute("Tel", TextBox3.Text)))

Belge.Save(Server.MapPath("App_Data") & "\" & Request.QueryString("event") & ".xml")

Son olarak gelelim kayıt olan ziyaretçinin bilgilerini XML dosyasına eklemeye. XML dosyasını okuyarak içerisinde Olay kök elementini buluyoruz. Normalde elementler liste olarak döndürüldüğü için bizim bu listeyi tek bir elemente çevirmemiz lazım. Olay elementinin zaten XML dosyasında bir adet olabileceğini biz biliyoruz, çünkü kök element. O nedenle Olay'ı yakaladıktan sonra .SingleOrDefault diyerek bunu tek bir element olarak alıyoruz ve içerisine Katilan elementi ekliyoruz. Katilan elementini XElement olarak yaratırken birinci parametrede elementin adını verdikten sonra istediğiniz kadar başka XElement'ler veya XAttribute'ler ekleyebilirsiniz. Bizde katılımcının adı, telefonu ve maili yeterli olacak. Son olarak dosyayı diske kaydediyoruz.

XLINQ ile XML uygulamaları "bebelere balon" kıvamında!

Eski günlerde olsak yukarıdaki işlemleri yapabilmek için XSLT, XPATH bilmenin yanı sıra bolca da XML okuma ve yazma için kod yazmanız gerekirdi. Oysa bugün iş gerçekten çocuk oyuncağı da olmanın ötesinde "bebelere balon" kıvamına gelmiş durumda. Umarım bu projeyi sizlerle paylaşmam XLINQ'nun kullanımı ile ilgili ufak da olsa bir fikir verip bu dünyaya giriş yapmanıza yardımcı olur.

Hepinize kolay gelsin.

Friday, February 29, 2008 2:14:40 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET 3.5 | LINQ  | 
 Thursday, February 28, 2008

Ücretsiz 24 saatlik Silverlight eğitimi ile ilgili duyuru içerisindeki kayıt formunu görmüşsünüzdür. Maalesef bu form sistemini yapmamı bekleyerek duyuruyu üç gün kadar geç yapabildik :) Bu aralarda ciddi çok yoğun.

Peki böyle bir formu yapmak ne kadar sürebilir ki? Ortalama 15 dakikamı aldı, ama sadece bir mailform değil :) Hazır yapmışken ileriki aktiviteler için de kullanabileceğim bir sistem yapmak istedim. Hedefim mini-iğrenç :) bir yönetim panelinden en azından aktivite yaratıp kapatabilmekti, tabi kayıt olan kişilerin listesini de alabilmem gerekiyordu. Neden iğrenç dediğimi de açıklıyım. Sadece ben kullanacağım için yönetim panelinin güzelliği ile vs hiç mi hiç uğraşmadım :) iş görsün yeter.

Konuyu uzatmadan, bütün bunları neden size anlattığımı da söylemekte fayda var. Hazırlamış olduğum sistemi tüm kodları ile sizlerle paylaşmaya karar verdim. Evet, birazdan indirebileceksiniz :)

Sistem aslında çok basit bir mantıkla çalışıyor. Yönetim panelinden bir aktivite yaratıyorsunuz aktiviteye verdiğiniz TAG özelliği o aktivitenin kodu oluyor. Bu kod üzerinden default.aspx?event=kod gibi adreslerle insanlar bu aktivitelere kayıt olabiliyorlar. Her bir aktivitenin kodu, aciklamasi ve maksimum katılımcı sınırı var. Aciklama kısmı aktivite ile ilgili sayfadaki kayıt formunun üzerindeki HTML kısmı içeriyor. Makimum katılımcıyı isterseniz 0 vererek sınırsız hale getirebiliyorsunuz. Her bir aktivite ile ilgili tüm bilgiler ayrı ayrı XML dosyalarında App_data klasöründe saklanıyor.

Uyarılar

Arkadaşlar birazdan projenin kodlarını indirip incelerken bu projeyi bir gece yarısı saat 01.00 ile 01.15 arasında yaptığımı aklınızın bir köşesinde bulundurun :) Hatta bu projeyi paylaşıyorum diye içerisinde herhangi bir değişiklik vs de yapmadım. Yalan olmasın login.aspx deki şifreyi değiştirdim. O nedenle aşağıda bahsettiğim noktalarla ilgili bu projeyi örnek almayın!

Bunları örnek almayın!

-Authentication yapısı rezalet. Zaten login.aspx de kullanıcı adı bile yok, sadece şifre soruyor :) Şifreyi sorduğu metin kutusunun tipi bile Password değil :) Bir ara düzeltmek lazım. Forms Authentication kurmaya üşendim.

-XML dosyalarının okunması ve yazılması arasında aslında application.lock kullanmak lazım. Aynı salisede 2 kişi formu göndermeye kalkarsa biri karambole gidecektir. Allahtan bizde pek böyle bir ihtimal yok gibi :) (Umarım)

İncelenmesi gereken kısımlar (Projenin kodunu paylaşmaktaki amacım)

XLINQ ile yazılmış kısımlara özellikle dikkat etmenizde fayda var. XML dosyalarının yaratılmasındaki kolaylık, okunmasındaki rahatlık özellikle dikkat çekici. Bu kodu sizlerle paylaşmanın birinci nedeni XLINQ örneği olarak incelemeniz ikincisi ise böyle bir mini sisteme ihtiyacı olan varsa alsın rahat rahat kullansın :)

LINQ'den bahsettiğimize göre unutmamak gerek ki bu site ASP.NET 3.5 ile hazırlanmıştır. Projedeki bazı kodlarla ilgili yarın bazı açıklamalar da yayınlayacağım.

Hepinize kolay gelsin.

Aktivite Kayıt Sistemi Kaynak Kodları - 28022008_1.zip (7.5 KB)

Thursday, February 28, 2008 1:29:56 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET 3.5 | LINQ  | 
 Monday, February 11, 2008

Bu aralar karşılaştığım ilginç sorulardan biri de URL Mapping hakkında. İnternette gezerken dikkatinizi çekmiştir, bazı sitelerde www.adres.com/bu+bir+makale/default.aspx gibi adresler kullanılıyor. İşte buna URL Mapping deniyor. Bu işlemi, aslında var olmayan bir adresi varmış gibi kullanarak esasen var olan başka bir adrese arka planda yönlendirmek şeklinde tanımlayabiliriz.

Örneğin:

www.ornek.com/urunler.aspx?ID=5

gibi bir adres yerine

www.ornek.com/5/default.aspx

şeklinde adresler kullanabiliyorsunuz.

Biz de bu konuda bir örnek yaparak yukarıdaki gibi bir adresi dönüştürmeyi deneyelim. Örneğimizde kullanmak üzere bir default.aspx yaratıyoruz ve basit bir şekilde sayfaya bir adet yerleştirerek QueryString üzerinden gelecek ID bilgisini Label içerisine yazdıracağız.

[default.aspx]

<%@ 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>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>

    </div>

    </form>

</body>

</html>

[default.aspx.vb]

Partial Class _Default

    Inherits System.Web.UI.Page

 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Label1.Text = Request.QueryString("ID")

    End Sub

End Class

Sayfamızı hazırladığımıza göre sıra geldi mapping işlemini yapmaya. Projemize bir adet Global.asax (Global Application Class) eklememiz gerekiyor. Projeye "Solution Explorer" içerisinde sağ tuş tıklayarak "Add new item" diyerek söz konusu dosyayı ekleyebilirsiniz. Sonrasında Global.asax içerisinde Application'a ait BeginRequest durumunu yakalayarak mapping kodumuzu yazacağız.

<%@ Application Language="VB" %>

 

<script runat="server">

    Protected Sub Application_BeginRequest(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim GelenAdres As String = Context.Request.Url.AbsolutePath

        Dim GelenID As String = GelenAdres.Substring(GelenAdres.IndexOf("/", GelenAdres.IndexOf("WebSite15")) + 1, GelenAdres.IndexOf("default.aspx") - GelenAdres.IndexOf("/", GelenAdres.IndexOf("WebSite15")) - 2)

        Context.RewritePath("../default.aspx?ID=" & GelenID)

    End Sub

</script>

Gelelim yukarıda neler yaptığımıza. İlk satırda GelenAdres adında bir değişken yaratarak buraya kullanıcının talepte bulunduğu adresin yolunu kopyalıyorum. Bu adres metni içerisinde /5/ gibi duran ID bilgisini almam gerekiyor. Ben bu işlemi standart String işlemleri ile yaptım, oysa güzel bir RegularExpression çok daha hoş durabilir. İhtiyaçlarınıza göre istediğiniz metodu kullanabilirsiniz. ASP.NET Development Server kullandığım için benim sitem bir WebSite15 denen bir klasör içerisinde açıldı. O nedenle string işlemlerimi şimdilik ona göre yazdım. Son olarak da Context nesnesine ait RewritePath metodu ile esas açılacak olan adresi belirtiyorum. Yakalamış olduğum ID bilgisini adresin sonuna ekliyorum.

Artık www.ornek.com/5/default.aspx adresine giden kullanıcılar için aslında www.ornek.com/default.aspx?ID=5 adresi açılıyor ama bunu hiçbir kullanıcı görmüyor. Örneği bir adım ileri taşıyarak www.ornek.com/Bu+bir+metin/default.aspx şeklindeki adreslerin de www.ornek.com/default.aspx?ID=5 şekline dönüşmesini sağlayabilirsiniz. Tek yapmanız gereken gelen başlik bilgisini alip ona uygun ID'yi veritabanından çekerek yeni adrese aktarıyor olmak.

Mapping yaptığımız tüm adreslerin sonunda .aspx uzantılı bir dosya adresi kullandık. Bunun nedeni sadece .aspx uzantılı dosyaların IIS 6.0 üzerinde asp.net motoruna bağlı olması. Bu durum IIS'e admin erişiminiz varsa özel ayarlarla tabi ki değiştirilebilir. Yakın zamanda Server 2008 lansmanı ile IIS7.0 da kullanıyor olacağız. IIS7.0'ın mimari yapısındaki değişiklikler sonucu yukarıdaki kodu IIS 7.0 üzerinde çalıştırdığınızda tüm istekler dosya uzantısına bakılmadan map edilebilecektir.

Yukarıdaki taktiğin yanı sıra HttpModule yazarak URL Mapping işlemini daha performanslı bir hale getirmek de mümkün. Umarım o konuda da yakında uzun bir makale yazma şansım olur :)

Hepinize kolay gelsin.

Monday, February 11, 2008 3:09:52 PM (GTB Standard Time, UTC+02:00)  #    Comments [12]   ASP.NET 3.5  | 
 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  | 
 Thursday, January 24, 2008

Budan bir süre önce Windows Server 2008 sertifikasyonlarından bahsetmiştim. Bugünlerde Visual Studio 2008 için planlanan sertifikasyonların da bir kısmı duyurulmaya başlandı.

Visual Studio 2005'de olduğu gibi 2008 ile beraber de MCTS ve MCPD ünvanlarına "competency" ler ekleniyor olacak. Şu an için MCTS tarafı belirlenmiş durumda ve öngörülen MCTS'lerin listesi şöyle;

  • Windows Forms Applications
  • ASP.NET Applications
  • Windows Communication Foundation Applications
  • ADO.NET Applications
  • Windows Workflow Foundation Applications
  • Windows Presentation Foundation Applications

Visual Studio 2005 serisi ile beraber girdiğimiz 70-536 sınavı hala geçerli olan ve yeni başlayanların Visual Studio 2008 için de girmek zorunda olacağı bir sınav olacak. Yani bugün yola çıkacak olanların hemen girebileceği bir sınavdan bahsediyoruz :) Yukarıdaki konulardaki sınavlar Mart ayından başlayarak Mayıs sonuna kadar farklı tarihlerde yayınlanmaya başlayacak.

Yeni haberler duyuruldukça sizlere de ulaştırıyor olacağım.

Thursday, January 24, 2008 9:34:37 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   .NET Framework 3.5 | ASP.NET 3.5 | Visual Basic 2008 | Visual Studio 2008 | WCF | WPF  | 
 Friday, January 18, 2008

Bundan bir süre önce .NET Framework 3.5'in açık kaynak kodlarının Microsoft tarafından dağıtılacağını sizlere duyurmuştum. Bu gibi bir dağıtımın özellikle Framework içerisinde hataların hızlıca giderilebilmesine ve biz programcıların arka planda nelerin çalıştığını görerek yerine göre daha performanslı uygulamalar hazırlayabilmemize yardımcı olacağı kesin. İşte o gün bugün :)

Framework içerisindeki aşağıdaki kütüphanalerin açık kaynak kodları yayınlandı.

  • .NET Base Class Kütüphanaleri (System, System.CodeDom, System.Collections, System.ComponentModel, System.Diagnostics, System.Drawing, System.Globalization, System.IO, System.Net, System.Reflection, System.Runtime, System.Security, System.Text, System.Threading, vs).
  • ASP.NET (System.Web, System.Web.Extensions)
  • Windows Forms (System.Windows.Forms)
  • Windows Presentation Foundation (System.Windows)
  • ADO.NET ve XML (System.Data ve System.Xml)

Çok yakında diğer sınıfların da zaman içerisinde paylaşıma açılacağı ayrıca duyuruldu.

Yükleme başlıyor...

Visual Studio'nun .NET Framework açık kaynak koduna online olarak ulaşabilmesi için aşağıdaki adresten gerekli paketi bilgisayarınıza yüklemeniz şart. Maalesef söz konusu paket Express sürümlerle çalışmayacaktır.

https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=10443&wa=wsignin1.0

Yükleme işlemi tamamlandıktan sonra Visual Studio 2008 içerisinde Tools > Options > Debugging > General tabına giderek "Enable Just My Code"" seçeneğini OFF ve "Enable Source Server Support" seçeneğini ON olarak değiştirmeniz gerekiyor.

Açık kaynak koduna yolculuk : Adım 1
Açık kaynak koduna yolculuk : Adım 1

Bir sonraki adımda yine "Options" içerisinde "Symbols" bölümüne "http://referencesource.microsoft.com/symbols " adresini ekledikten sonra internetten indirilen kaynakların önbelleklenmesi için de bir klasör belirtmeliyiz. Klasör olarak kullanıcınızın yazma hakkına sahip olduğu bir yol göstermenizde fayda var. Özellikle Vista kullanıcılarına tavsiyem kendi kullanıcı klasörleri içerisinde bir adres vermeleri. "Search the above locations only when symbols are loaded manually" işaretini de işaretleyerek işlemimizi tamamlıyoruz.

Açık kaynak koduna yolculuk : Adım 2
Açık kaynak koduna yolculuk : Adım 2

İşlemleri tamamlamak için "OK" düğmesine bastığınızda Visual Studio size harici bir kaynaktan kaynak kodu yüklemenin tehlikeli olabileceğine dair bir uyarı gösterecektir. Söz konusu uyarıya "Yes" diyerek kaynağa güvendiğinizi belirtebilirsiniz.

Peki NASIL kullanacağız?

Şimdi hemen bir Winforms projesi başlatarak bir uyarı mesajı gösterelim. Uyarı mesajımı gösterecek koda "breakpoint" ekledikten sonra projeyi çalıştırarak "breakpoint" noktasına geldiğinde "Call Stack" penceresinden istediğimiz sınıfı seçerek sağ tuş ile gelen menüden "Load Symbols" komutu veriyoruz.

Açık kaynak koduna yolculuk : Adım 3
Açık kaynak koduna yolculuk : Adım 3

Yükleme işlemi internet üzerinden yapılacağı için tabi ki "Load Symbols"e tıklamadan önce internete bağlı olduğunuzdan emin olmanız gerekiyor. İşlem bittiğinde "Call Stack" içerisinde gri satırlar artık siyah olacak ve her satırın sonunda kaynak koddaki satır numaralı da gözükecektir.

Açık kaynak kodu bilgisayarımızda.
Açık kaynak kodu bilgisayarımızda.

İncelemek istediğiniz koda karar verdikten sonra çift tıklayarak kaynak dosyasının açılmasını sağlayabilirsiniz. Kaynak açılmadan önce size lisans sözleşmesi de gösterilecektir, sözleşmeyi okuyup kabul ettikten sonra kaynak kodu bilgisayarınıza indirilecektir. Daha sonraki denemelerinizde sözleşme bir daha gösterilmeyecektir.

.NET Framework açık kaynak kodu VB :)
.NET Framework açık kaynak kodu VB :)

İşte açık kaynak kodu karşımızda. Unutmayalım bu kod bizler için hazırlanmış bir kod. Yani içerisinde bize özel yorumlar var. Karşılaşacağımız bazı sınıflar VB bazıları ise C# ile yazılmış durumda. Maalesef şimdilik istediğimiz dilde inceleme gibi bir şansımız yok.

Hepimize hayırlı, uğurlu olsun :)

Friday, January 18, 2008 1:36:48 AM (GTB Standard Time, UTC+02:00)  #    Comments [6]   .NET Framework 3.5 | ASP.NET 3.5 | Visual Studio 2008  | 
 Saturday, January 12, 2008

14 Ocak, Pazartesi günü saat 15.15-16.00 arasında IIS 7.0 ve ASP.NET ile Gelen Yenilikler webineri ile karşınızda olacağım. Webiner boyunca Vista ile karşımıza çıkan ve Windows Server 2008 ile sunucu tarafında da kısa zamanda kullanabileceğimiz IIS 7.0'ın ASP.NET yazılım geliştiricileri için getirdiği yeniliklerden bahsedeceğiz.

Meeting ID: T9FQCG
Webiner Bağlantısı :https://www112.livemeeting.com/cc/microsoft/join?id=T9FQCG&role=attend&pw=wJp%2F%3FB%3D7s
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, January 12, 2008 8:22:12 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET 3.5 | Webiner | IIS 7.0  | 
 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  | 
 Wednesday, January 02, 2008

2008'in ilk aktivitesini CETURK.com organizasyonunda Microsoft, İstanbul / Dikilitaş binasında gerçekleştiriyoruz. "2008 Microsoft Vizyonu ve Yeni Teknolojileri Semineri" olarak adlandırdığımız güne hepiniz davetlisiniz :) 12 Ocak, Cumartesi günü sabah 10'dan başlayarak 17.30'a kadar sürecek olan seminerlerin konuları arasında Expression Web, Design, Blend, Silverlight, Visual Studio 2008, LINQ bulunuyor. Expression Blend ile WPF Animasyonları ve Silverlight 1.0, 2.0 Uygulamaları bölümünü 12.30-14.30 arasında ben sunuyor olacağım.

Programın detayları ve seminere kayıt için aşağıdaki linki kullanabilirsiniz.

http://www.ceturk.com/etkinlikkayit.asp?id=35

Wednesday, January 02, 2008 11:46:06 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   .NET Framework 3.5 | ASP.NET 3.5 | Expression Blend | Expression Design | Expression Encoder | Expression Web | LINQ | Seminer | Silverlight | Visual Studio 2008 | WPF  | 
 Friday, December 28, 2007

.NET Framework 3.5 ile beraber ASP.NET 3.5'i de kullanmaya başladığımız bugünlerde artık projelerimizi yavaş yavaş sunuculara aktarmaya doğru da yaklaşıyoruz. Peki sunucuda neler yapmamız gerekiyor? Aslında durum daha önceki .NET Framework sürümlerinden pek farklı değil. .NET Framework 3.5'i direk sunucunuza kurmanız gerekiyor fakat öncesinde kesinlikle .NET Framework 2.0'ın kurulmuş olması şart. Malum 3.5 sürümü 2.0 üzerine gelen eklentilerden oluşuyor ve hala 2.0 sürümündeki sınıflar 3.5 içerisinde de kullanılıyor.

Kurulumu tamamladıktan sonra akla gelecek ikinci bir soru ise IIS içerisinde nasıl bir ayar yapmamız gerektiği. Hatırlarsanız .NET Framework 2.0 ile beraber IIS içerisinde artık her bir web sitesi için 1.0 ve 2.0 arasında bir seçim yapabildiğimiz ayarlar gelmişti. Bu ayarlara baktığınızda 3.5 seçeneğini göremezseniz şaşırmayın çünkü ASP.NET 3.5 siteleri IIS'de 2.0 siteleri gibi çalışıyor. Yani söz konusu siteyi IIS içerisinde .NET Framework 2.0 ile çalışacak şekilde ayarladıysanız hiçbir sorunla karşılaşmazsınız.

O zaman ne farkı kaldı? Fark aslında projenizin Web.Config dosyası içerisinde yer alıyor.

    <system.codedom>

      <compilers>

        <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"

                  type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

          <providerOption name="CompilerVersion" value="v3.5"/>

          <providerOption name="WarnAsError" value="false"/>

        </compiler>

        <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4"

                  type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

          <providerOption name="CompilerVersion" value="v3.5"/>

          <providerOption name="OptionInfer" value="true"/>

          <providerOption name="WarnAsError" value="false"/>

        </compiler>

      </compilers>

    </system.codedom>

İşte Web.Config içerisinde yer alan yukarıdaki bölüm projenizin ASP.NET 3.5 projesi olduğunu ve .NET Framework 3.5 özelliklerini kullanabileceğini belirtiyor. Böylece gerekli referanslar ile artık web siteniz LINQ ve entegre AJAX gibi özelliklerden faydalanabilecek. Visual Studio 2008 ile yarattığınız ASP.NET 3.5 sitelerinde Web.Config dosyalarına bu kod otomatik olarak ekleniyor.

Hepinize kolay gelsin.

Friday, December 28, 2007 12:43:13 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET 3.5 | IIS 6.0  | 
 Thursday, December 27, 2007

Bugün sizlere biraz Refactoring'den bahsetmek isriyorum. Refactoring'i kaba bir şekilde tanımlamak gerekirse herhangi bir kodun işlevini değiştirmeden yazılışı değiştirmek ve hedef olarak da kodun okunuşu kolaylaştırmaktır diyebiliriz. Refactoring konusunda sektörde bir çok araç, üçüncü parti uygulamalar satılıyor. Visual Studio içerisinde de C# için hazır bazı ufak tefek Refactoring araçları bulunuyor. Tabi ben bir VB programcısı olarak olayın VB kısmından bahsedeceğim ve sizlere ücretsiz bir Visual Studio eklentisi olan Refactor'u tavsiye edeceğim.

http://msdn2.microsoft.com/en-us/vbasic/bb693327.aspx

Yukarıdaki adresten indirebileceğiniz yazılımın normal sürümü ücretsiz ve hem Visual Studio 2005 hem de 2008 ile uyumlu. Yazılımın daha çok özelliklere sahip bir sürümü de "Refactor Pro" adı altında satılıyor. Biz şimdilik ücretsiz sürümle yetinelim :)

Hemen bir iki örnek ile neler yapabileceğimize bakalım.

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim ds As New Data.DataSet

 

        Using cnn As New SqlConnection(ConfigurationManager.ConnectionStrings("CNN").ConnectionString)

            Using cmd As New SqlCommand("SELECT * from TABLO", cnn)

                Dim da As New SqlDataAdapter(cmd)

                da.Fill(ds)

            End Using

        End Using

 

        GridView1.DataSource = ds

        GridView1.DataBind()

    End Sub

Yukarıdaki kod herhangi bir asp.net web sayfasının Page.Load durumunda çalışıyor olsun. Gördüğünüz gibi veritabanına bir Select göndererek gelen veriyi GridView'e bağlıyoruz. Eğer Select ile aldığımız veriyi sayfada başka yerlerde de almamız gerekecekse aslında bunu harici bir function olarak yazmamız daha faydalı olacaktır. Hemen aşağıdaki şekilde function içerisine almak istediğim bölümü seçiyorum.

Kodumuzu harici bir function içerisinde alıyoruz.
Kodumuzu harici bir function içerisinde alıyoruz.

"Extract Method" komutu verdiğimizde Refactor bize kodu class yapısı içerisinde nereye yazdırmak istediğimizi soruyor sonrasında da Function'ımızı aşağıdaki gibi otomatik olarak yaratıyor.

Partial Class _Default

    Inherits System.Web.UI.Page

 

    Private Shared Sub Page_LoadExtracted(ByVal ds As Data.DataSet)

        Using cnn As New SqlConnection(ConfigurationManager.ConnectionStrings("CNN").ConnectionString)

            Using cmd As New SqlCommand("SELECT * from TABLO", cnn)

                Dim da As New SqlDataAdapter(cmd)

                da.Fill(ds)

            End Using

        End Using

    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim ds As New Data.DataSet

 

        Page_LoadExtracted(ds)

 

        GridView1.DataSource = ds

        GridView1.DataBind()

    End Sub

End Class

Gördüğünüz gibi artık aynı Function'ı kullanarak sürekli aynı datayı istediğimizde bir DataSet içerisine doldurtabiliyoruz. Fakat burada sizi rahatsız edeceğinden emin olduğum bir şey var; Refactor'un yarattığı function'ın adı çok anlamsız :) Visual Studio içerisinde yaratılan fonksiyonun adını değiştirirseniz Refactor sizin için söz konusu fonksiyonun kullanıldığı yerlerdeki referansları da otomatik olarak değiştirecektir.

Gelelim bir diğer örneğe. Varsayalım ki yeni bir sınıf yapısı oluşturmaya başladınız. Oluşturduğunuz ilk sınıfın bir sürü Private değişkeni var ve bunlara da uygun Property'lerin tanımlanması gerekiyor. Set ve Get leri tek tek her biri için ayarlıyor olmak gerçekten işkenceye dönüşebilir. Gelin aşağıdaki koda bir bakalım.

    Public Class Deneme

        Private Ozellik As Integer

        Private Ozellik2 As Integer

 

        Sub New()

 

        End Sub

 

        Sub New(ByVal Ozellik As Integer, ByVal Ozellik2 As Integer)

            Me.Ozellik = Ozellik

            Me.Ozellik2 = Ozellik2

        End Sub

    End Class

Yukarıdaki sınıfımızda sadece iki adet özellik bulunuyor bunların Property'lerini oluşturmamız gerekiyor. Private değişkenlerin üzerine sağ tuşu ile tıkladıktan sonra "Refactor / Encapsulate Field" komutu veriyorum ve kodun yerleştirileceği yeri de seçtikten sonra Refactor benim için Property kodlarını otomatik olarak yazıyor.

  Public Class Deneme

        Private Ozellik As Integer

        Private Ozellik2 As Integer

 

        Sub New()

 

        End Sub

 

        Sub New(ByVal Ozellik As Integer, ByVal Ozellik2 As Integer)

            Me.Ozellik1 = Ozellik

            Me.Ozellik21 = Ozellik2

        End Sub

        Public Property Ozellik1() As Integer

            Get

                Return Ozellik

            End Get

            Set(ByVal value As Integer)

                Ozellik = value

            End Set

        End Property

        Public Property Ozellik21() As Integer

            Get

                Return Ozellik2

            End Get

            Set(ByVal value As Integer)

                Ozellik2 = value

            End Set

        End Property

    End Class

Refactor tarafından tamamlanan yukarıdaki kodda dikkatinizi çektiyse Sub New kodundaki değerlerin aktarıldığı değişkenlerin isimleri de otomatik olarak Property isimleri ile değiştirilmiş durumda. Bir önceki örnekte olduğu gibi burada da eğer elle Property isimlerini değiştirirseniz Refactor otomatik olarak sınıf içerisinde diğer referansları da değiştiriyor.

Tüm bu işlemleri kod yazarken yapıyor olmak kolaylık sağlayabilir fakat esas mesele elinizde hazır kodları tamamlanmış bir proje varsa gerçekleşiyor. Projeyi inceleyerek sadece Refactoring araçlarını kullanarak daha okunabilir bir kod yaratmaya çalışıyorsunuz, hatta çoğu zaman kodun işleyişini değiştirmeden kodu kısaltabiliyorsunuz bile.

Refactoring'e giriş yapmanızı sağlayacak Refactor eklentisi ne kadar ücretsiz olsa da daha fazla reklamını yapmayacağım :) Refactoring dünyasını keşfetmek artık size kalmış.

Hepinize kolay gelsin.

Thursday, December 27, 2007 4:21:29 PM (GTB Standard Time, UTC+02:00)  #    Comments [2]   ASP.NET | ASP.NET 3.5 | Visual Basic 2005 | Visual Basic 2008 | Visual Studio 2005 | Visual Studio 2008  | 
 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  | 
 Thursday, November 08, 2007

Yazımın tamamen "yıkama yağlama" kokacağının farkında olarak başlıyorum bu cümlelere. Ben böyle bir yazı okuyacak olsam kesinlikle "yağcılık yapmış" derim :) Umarım sizler demezsiniz. En azından blogumu bir süredir takip edenler veya benle karşılaşmış olanlar beni daha net anlayacaktır diye ümit ediyorum. Bu temkinli girişten sonra konuya geçiyim.

Gelelim esas yazımın girişine :)

İlk olarak PCWorld Türkiye'de kapak konusu yazdığımda Lise 2'deydim. O günlerden bugüne bilişim teknolojiler üzerine çalışan birçok şirkette görev aldım, birçok şirketle kurumsal olarak çalıştık. Özetle, yaşımın yettiği ölçüde çok BT çalışanı ve çok BT yöneticisi gördüm. İngilizce blog sitemi de katarsak iki yıldır blog yazıyorum. Tüm bu bilgiler ışığında ilk defa böyle bir yazı yazma ihtiyacı hissettim. Peki ne yazacağım? :) Sabır.

Bundan yaklaşık üç ay önce PCnet ekibinden sevgili dostum, adaşım :) Daron Dedeoğlu'nun MSN'den gönderdiği titreşim ile başlayan dalgalanma bakın nerelere geldi. İlk olarak PCnet Ekim sayısında AJAX ve Silverlight içeriği sunmanın Türkiye'de bir ihtiyaca cevap olacağını söylediğimde gelen olumlu tepki beni biraz şaşırttı. Malum Silverlight yeni release olmuştu. Sevinçle yazılarımı hazırladım. Bir sonraki ay, Kasım ayı için içerik toplantısına Expression Blend, Web ve Design ile ilgili Türkçe içerik eksikliği olduğundan bahsederek dergide yer verilirse yararlı olacağını dile getirdim. Aslında epey ümitsizdim, çünkü ürünler yeni olmakla beraber sundukları teknolojiler de kısmen çok yeniydi. Yine "OK" dendi ve havalara uçarak Kasım sayısına da yazılarımı hazırladım ve bir anda PCnet'te her ay bu yepyeni ürünleri, teknolojileri yazıyor olduk.

Bu noktaya kadar yaşananlar beni şaşırtmakla beraber "Bravo! Vizyonları genişmiş!" diyerek haddim olmadan içten içe değerlendirmeler de yaptım.

Daha bundan üç gün önce bloguma Visual Studio 2008'in RTM sürümünün bu ay sonunda çıkacağı ile ilgili Microsoft'un basın açıklamasını taşıdım. Böylece partnerlar Visual Studio 2008 kullanarak ürün geliştirebilecekler. Şubat ayında beklenen resmi lansmanın da gecikmeyeceği ortaya çıktı. Hemen kolları sıvayıp tabiri caiz ise yüzsüzlük yaparak PCnet Yayın Yönetmeni Barış Nevreş'e çok kısa bir mail yazdım.

http://www.microsoft.com/presspass/press/2007/nov07/11-05TechEdDevelopersPR.mspx
VS 2008 ve .NET Framework 3.5 bu ay çıkıyor. Aralık sayısında OKUL bölümüne ASP.NET 3.5 bölümü eklemeyi teklif ediyorum? Pazartesiye yetiştirebilirim yazısını.

Yukarıdaki maile daha kısa ama daha değerli bir cevap geldi.

Ekleyelim.

İnanamadım! Aslında daha doğrusu "gözlerime inanamadım" çünkü daha önce yaptığım yüz yüze görüşmelerde edindiğim izlenimden yola çıkarak ümitliydim ama gözlerim :) inanmakta zorlandı. Bahsettiğimiz durum daha release olmamış bir teknoloji ile ilgili release olma tarihi basın açıklamasında duyurulduğu anda konuyla ilgili Türkçe kaynak yayınlamayı uygun gören bir VİZYON'a sahip olmaktır. PCnet'in böyle bir vizyona sahip olması hem PCnet adına, hem Türkiye adına beni sevindirdi, hem de bir PCnet yazarı olarak kendim için sevindim :)

Yukarıda bahsettiğim vizyon bugün çok az kurumda vardır diye tahmin ediyorum. Ben ilk defa karşılaşıyorum. O nedenle buradan PCnet'e ve Yayın Yönetmeni Barış Nevreş'e teşekkür ediyorum. Ben lisedeyken yeni çıkan bir teknolojiyle ilgili yazıları dergilerde bulamıyordum. Şimdiki gençler şanslı :)

SSS

Soru:Bu bir reklam mıdır?
Cevap:Amaç değil fakat araç olabilir.
Soru:PCnet ve Microsoft kanki midir?
Cevap:Çok da güzel Linux yazıları var dergide :) Dergininin Yazılım Editörü Daron Dedeoğlu Pardus programlama ekibindedir.
Soru:Bugün teknik bir makale yok mu blogda?
Cevap: Eeee.... Yok :)

Thursday, November 08, 2007 9:46:01 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET 3.5 | Genel  | 
Copyright © 2010 Daron Yöndem. Tüm hakları saklıdır.