ENGLISH BLOG |  HAKKIMDA  |  ARSIV   | DELETE LANGUAGE COOKIE

Enes TAYLAN

Mind Hegemony - Mood 1.0 - Total Control Edition

Sayfa Kontrollerini Linq ile Filtrelemek ve Listelemek

clock Şubat 16, 2010 18:28
Linq genel olarak Linq to Sql, Linq to Entities veya Linq to XML datası üzerinde CRUD işlemleri yapmak için kullanılır. Fakat Linq .NET' te tüm collection (listeler, List, Array, ObservableCollection vb.)'lar üzerinde çalışma yeteneğine sahiptir. Bu yazıda, Sayfa Controlleri (Page Collection) üzerinde Linq ile nasıl çalışabilir ve filtreleme ölçütümüze göre istediğimiz kontrolleri nasıl seçebiliriz bunlara bakacağız. Bunun için de sayfada içinde yazı olan TextBox'ları seçmek istediğimizi düşünelim. (Örneğimizin çalışıp çalışmadığını kontrol etmek için seçtiğimiz TextBox'ların içindeki yazılara "--seçildi" yazısı ekleyelim.)

Şimdi bir .aspx sayfası açalım ve bu sayfaya birkaç tane textbox, bir tane de button ekleyelim. Bu textboxları direk olarak sayfanın içine veya başka bir control'un içine (örneğin panel'e) ekleyebiliriz.Button'un click eventini aşağıdaki şekilde yazalım:
protected void Button1_Click(object sender, EventArgs e)
{
    KontrolleriGetir(this.Page);
    //işlemi başlattığımız yer
}


//aşağıda yazdığımız method recursive bir method. Kendisine verilen
//kontrol'ün Controls collection'ı üzerinden çalışmaya başlıyor

private void KontrolleriGetir(Control anaControl)
{
    //linq kodumuz kendisine verilen anakontrol'ün kontrolleri 
    //arasından içinde yazı olanları seçiyor
    var kontroller = from k in anaControl.Controls.Cast()
                     let txt = k as TextBox
                     where (txt != null && txt.Text.Length > 0)
                     select k;

    //seçtiğimiz texboxları "-- seçildi!" olarak işaretlediğimiz er
    foreach (var kontrol in kontroller)
    {
        (kontrol as TextBox).Text += "-- seçildi!";
    }


    //burda da anacontrollerin kontrolleri arasından, kendisi de 
    //1 veya daha fazla kontrole sahip olanları seçiyoruz veya
    //recursive olarak bu kontroller üzerinde methodumuzu çağırıyoruz
    foreach (Control kontrol in anaControl.Controls)
    {
        if (kontrol.Controls.Count > 0)
        {
            KontrolleriGetir(kontrol);
        }
    }         
}


JSON NEDİR VE JQUERY İLE JSON KULLANAN ASP.NET AJAX METHODLARI NASIL KULLANILIR?

clock Ekim 8, 2009 08:40

Günümüzde server tarafında yükü kullanıcı (client) tarafına aktarmak, Web yazılımı alanındaki en temel hedeflerden biri. XMLHttpRequest objesinin tarayıcılara eklenmesi, sonrasında JavaScript'in geliştirilmesiyle birlikte tarayıcıyı yazılım geliştirme ortamı olarak kullanmak, dolayısıyla server tarafında yapılabilecek işlemleri kullanıcı tarafında yapabilmek mümkün oldu. AJAX kütüphanelerinin yazılması, JQuery gibi frameworklerin geliştirilmesi kullanıcı tarafını çok daha güçlendirdi. Bu gelişmelerde en son nokta, herhalde kompleks kullanıcı kontrollerini (user control) tarayıcıda yaratmak ve gerekli datayı Web Servislerden çekerek, kullancı tarafında formatlayarak sunmak. Bu şekilde, örneğin Microsoft'un önümüzdeki ayda tam sürümü çıkacak AJAX Control Toolkit'ini kullanarak, tamamen servis tabanlı .html (.aspx, .php veya .jsp değil) sayfaları oluşturabilir, gerekli data oluşturma mantığını servera ama hangi datanın alınması gerektiği ve bu datanın nasıl kullanıcıya sunulacağı gibi işlerin arka planını tarayıcı tarafına yerleştirerek dinamik sayfalar yapabiliriz.

Servislerle tarayıcı arasındaki ileitişim formatı olarak günümüzde en çok kullanılan teknolojiler XML ve JSON. Birçok platform (ASP.NET, JAVA, JavaScript ve daha birçoğu) iki formatla da yazılım geliştirebilmemizi mümkün kılan kütüphaneleri ve sınıfları bize sunuyor. Fakat birçok avantajından dolayı JSON ön plana çıkmaya başladı. En önemli avantajlarından biri bandwith'i daha verimli kullanabilmemizi (ki AJAX işlemlerinin asıl amacı) sağlayan yapısı. Yani kısaca bahsedecek olursak XML ile bir datayı:

<Jeep><marka isim="Lincoln"><model isim="navigator">plaka numarası</model></marka></Jeep> şeklinde gösterirken, aynı datanın JSON formatı:

{
     "Marka" :   "Lincoln.", 
     "Model" :   "Navigator", 
     "Motor" :   "300 HP"
}

şeklinde gösterilebilir. Yukardaki örnekte gönderilen datanın bahsedilen özellik türleri (attribute) artarsa XML datanın büyüklüğü daha da artacaktır.

Şimdi kısaca JSON data nasıl kullanılır ona bakalım:

var jsonObje =  { 
    "JeepSayısı": "2", 
    "Jeepler": 
    [
        { "Marka": "Lincoln", "Model": "Navigator", "Motor": "300HP"},
	  { "Marka": "Cadillac", "Model": "Escalade", "Motor": "400HP"},
    ]
};

Yukardaki .js kodunun taslak olarak ne anlama geldiğini şu C# koduyla kolaylıkla anlayabiliriz:

public class Jeepler
{
    int JeepSayısı;
    List jeepler = new List();
}

public class Jeep
{
    string Marka;
    string Model;
    string Motor;
}

Bu örneğin Object Oriented mantığına ne kadar uygun olduğu tartışılır :) önemli olan açıklayıcı bir örnek verebilmek, tabii ki.

Yani, JSON'da obje oluştururken gerekli datayı {} arasına yazıyoruz. "özellik adı": "özellik değeri" şeklinde bir formatı var. Farklı özellikleri virgül ile ayırıyoruz. [] ise arrayleri göstermek için kullanılıyor. Arrayin içerisinde objeler tanımlamak istersek [{obje formatını uygula}]'ı kullanmamız gerekiyor. Basit bir array tanımlamak isteseydik: [1,2,3,4] şeklinde yapabilirdik (string array'i tanımlamak isteseydik: ["Pazartesi", "Salı"] olurdu).

JSON formatı object oriented bir şekilde datayı manipule edebilmemizi sağlar. Örneğin yukardaki jsonObje için şu .js kodunu yazabiliriz:

var markaIsmi = jsonObje.Jeepler[0].Marka;
alert(markaIsmi);

Şimdi JSON ile ASP.NET AJAX methodlarını (Web Method) nasıl kullanabiliriz ona bakalım. Kodumuzda bilgisayarda çalışan işlemleri (Ctrl+Alt+Delete) ile görebildiğimiz işlemlerin özelliklerini, Web Method ile çevirelim. Sonra bu methodu tarayıcı tarafında JSON ile çağırıp listeleyelim: (Öncelikle VS'de bir web projesi açalım ve App_Code dosyası içerisinde IslemBilgisi.cs dosyasını yaratalım ve aşağıdaki kodu yazalım)

public class IslemBilgisi
{
    public string IslemAdı { get; set; }    
    public long SayfalanmisMemoryBuyuklugu { get; set; }
}
Şimdi Default.aspx.cs dosyasına şunu ekleyelim:
[System.Web.Services.WebMethod]
public static List IslemleriAl()
{
    var query = (from p in System.Diagnostics.Process.GetProcesses()
                 select new IslemBilgisi
                 {
                     IslemAdı = p.ProcessName,                         
                     SayfalanmisMemoryBuyuklugu = p.PagedMemorySize64
                 }).ToList();
    return query;
}

Dikkat: Method static olmalı

[System.Web.Services.WebMethod], altına yazdığımız methodu tarayıcı tarafından çağırabilmemizi sağlar. Server tarafında yukarıdaki bilgiyi aldıktan sonra şimdi JQuery ile yukardaki datayı JSON formatında alalım (extra bir iş yapmamıza gerek yok. Objeleri List içerisinde çevirdiğimizden dolayı otomatik olarak JSON data geliyor).

        $(document).ready(function() {            
                $.ajax({
                    type: "POST",
                    url: "Default.aspx/IslemleriAl",
                    data: "{}",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    async: true,
                    success: function(msg) {
                        var islemBilgisi = msg.d;                        
                        for (var i = 0; i < islemBilgisi.length; i++) {                            
                            var satir = "Islem Adı: " +
                                        islemBilgisi[i].IslemAdı +
                                        "
" + "Sayfalanmış Memori Buyuklugu: " + processInfo[i].SayfalanmisMemoryBuyuklugu; $("#Sonuclar").append("
" + satir + "
"); } } }); });

Dikkat: Yukarıdaki kodu JQuery için gerekli <script> tagını ekledikten sonra yazalım.

Şimdi kodu inceleyelim. $(document).ready... yazarak DOM yüklenir yüklenmez hangi function'ın çağrılması gerekiyor, onu belirliyoruz. $.ajax, ajax callbackleri (Postback'in tersine tüm sayfayı yenilemeden) yapabilmemizi sağlayan bir method.

type:POST ile HttpPost yapıyoruz. url:Default.aspx/IslemleriAl, ASP.NET'in bize sunduğu çok güzel bir özelliği kullanabilmemizi sağlıyor: Sayfa url'inin arkasına, Web Method'un ismini eklememiz bu methodu çağırabilmemiz için yeterli. contentType ve dataType ile JSON formatında data alınması gerektiğini belirtmiş oluyoruz.

async:true ile asynchronous (arka planda denilebilir) bir şekilde işlemi gerçekleştirmiş oluyoruz. false olsaydı serverdan tüm data gelene kadar sayfadaki tüm işlem donmuş olurdu. success: ile data başarılı bir şekilde geldiğinde, bu datayı formatlayıp sayfaya sunacak function'u belirtmiş oluyoruz.

$("#Sonuclar") ile id'si olan HTML elementini (örnekte <div> elementi) alıp içindeki testini belirliyoruz. for döngüsü içerisinde serverdan List<IslemBilgisi> olarak çevirdiğimiz listenin (JSON formatı olarak array) üzerinden geçiyoruz. Önemli olan nokta ise bu arrayin herbir elementi object olarak gelmiş oluyor. Yani server tarafında IslemBilgisi sınıfında tanımladığımız IslemAdı ve SayfalanmisMemoryBuyuklugu'nu attribute olarak kullanabiliyoruz. $("#Sonuclar").append ile de #Sonuclar div'inin içerisinde (dışına değil) tüm datayı gösterebiliyoruz.



AsyncFileUpload ile Dosya Yükleme

clock Ekim 3, 2009 01:13

AJAX Control Toolkit'in yeni versiyonu çıktı. (http://ajaxcontroltoolkit.codeplex.com/)  (http://stephenwalther.com/blog/archive/2009/10/01/new-ajax-control-toolkit-release.aspx) Yeni kontrol toolkitle gelen özelliklerden biri de Asynchronous bir şekilde file upload'u yapabilmemizi sağlayan Asyncfileupload kontrolu. PostBack yapmadan dosya upload'u için (Hotmail ve Gmail, dikkat etmişseniz, ajaxla dosya yüklemesi yapıyor zaten.Yani sayfa yenilenmesi olmuyor) şu ana kadar dolambaçlı çözümler kullanılıyordu. (UpdatePanel içerisine klasik FileUpload kontrolünü eklemek de yeterli değildi) Ama artık Asyncfileupload ile bu işlemi yapmak çok kolay. Şimdi bu kontrolü nasıl kullanabiliriz ona bakalım:

Bir proje açalım ve şu .aspx dosyasını oluşturalım: (VS2008'e önceden yeni kontrol tookiti eklemeyi unutmayalım)

<form id="form1" runat="server">
    <asp:
ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div>
        <asp:
Image ID="YuklemeResim" runat="server" ImageUrl="~/spin2.png" />
        <br />
        <br />
        <asp:
UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <cc1:
AsyncFileUpload ID="AsyncFileUpload1" runat="server" ThrobberID="Image1" 
                   
UploaderStyle="Modern" />
                <br />
                <asp:
Button ID="YukleButton" runat="server" onclick="YukleButton_Click" Text="Kaydet" />
                <br />
                <br />               
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>

Bu kodda dikkat edilmesi gerekenler sayfanın başına ScriptManager eklenmesi (tüm ajax kontrol toolkit işlemleri için gerekli) ve AsyncFileUpload'un UpdatePanel içerisinde bulunması. Eğer bunu yapmazsanız klasik yöntemi kullanmış olursunuz - yani tam sayfa yüklemesi.
Eklediğimiz Image kontrolü (YuklemeResim) ise yükleme işlemi devam ederken kullanıcıya göstereceğimiz resmi belirliyor. AsyncFileUpload bunu tam olarak destekliyor - ThrobberID="YuklemeResim" kullanarak. (bekleme işlemleri sırasında gördüğümüz resimlere Throbber deniyor. Kendi Throbber'ınız yapmak için http://ajaxload.info/ sitesine girebilirsiniz.)  Diğer bir attribute ise UploaderStyle="Modern". Diğer bir seçeneğimiz "Classic" seçeneğiydi. Bu seçeneklerle iki farklı tasarım kullanabiliyoruz: 

Traditional:


Modern:     


Şimdi de .aspx.cs dosyasındaki YukleButton_Click eventine bakalım:
protected void YukleButton_Click(object sender, EventArgs e)
{
      AsyncFileUpload1.SaveAs(Server.MapPath(AsyncFileUpload1.FileName));

}

Bu kodda yaptığımız klasik FileUpload kontrolünde kullandığımız SaveAs metodunu kullanmak. AsyncFileUpload kontrolünün kullanımı gördüğümüz gibi bu kadar basit...



ASP.NET' TE CACHE VE CACHE DEPENDENCY KULLANIMI

clock Eylül 6, 2009 22:54

Cache , genel bir programlama tekniği olarak performansı arttırmak için kullanılır. Böylece access time'ı ( bağlantı süresi ) görece uzun olan ve dolayısıyla verimi düşüren disktteki veya network üzerindeki bir kaynakta bulunan data, son derece hızlı olan RAM' e aktarılır. Bu blog yazısında, herhangi bir ana klasördeki alt klasörlerin isimlerini döndüren bir metod üzerinde çalışacağız ( bu metod, kullanıcıya App_Themes klasöründeki temaların isimlerini bir DropDownList' te gösterip istenilen temanın seçilebilmesini sağlamakta kullanılabilir ).

Not: .NET cache sınıfları System.Web.Cache içerisinde bulunur. Kodunuzun başında using System.Web.Cache; yazmayı unutmayın.

Cache kullanımıyla ilgili bir sorun da "Data Cache'de ne kadar kalmalı?" Data geçerliliğini yitirdikten sonra kalmaya devam ederse sistemin yanlış bir inputla çalışmasının yanında RAM'i gereksiz yere kullanarak performansı da düşürür. Eğer gereğinden önce silinirse, o zaman da Cache'in bir anlamı kalmaz. Bu problemi çözmek için CacheDependency sınıfı bize Cache'lediğimiz datayı bir data kaynağına ( örnekte dosyaya ) bağlamamızı ve "Ne zaman bu dosya değiştirilirse, dosyaya bağlı olan Cache datasını da sil!" komutunu verebilmemizi sağlar. Şimdi koda bakalım:

public static string[] TemalarıGetir()
{  
      if (HttpContext.Current.Cache["SiteTemaları"] != null)  
      {  
    	 //Cache'de gerekli bilgi varsa direk getir  
          return (string[])HttpContext.Current.Cache["SiteTemaları"];  
      }  
   
      else //Cache'de aradığımız data yoksa
      {  
            string temalarKlasoru = HttpContext.Current.Server.MapPath("~/App_Themes");  
 
             string[] temalar = Directory.GetDirectories(temalarKlasoru);  
            //System.IO kullanarak temalarKlasoru içerisindeki tüm alt klasörleri alıyoruz  
     
             for (int i = 0; i < temalar.Length; i++)  
             {  
                   temalar[i] = Path.GetFileName(temalar[i]);  
             }  
     
             CacheDependency dep = new CacheDependency(temalarKlasoru);  
             //temalar klasoru ile CacheDependency tanımladık 
     
             HttpContext.Current.Cache.Insert("SiteTemaları", temalar, dep);      
             //temalar array'ini temelarKlasoru ile bağlayarak Cache'e ekledik
     
     
             return temalar;
      }  
  }  

Cache'de data key-value (anahtar-değer) çiftleri olarak tutulur. (anahtar SiteTemaları string'i, değer ise temalar arrayi) Yukardaki kodda App_Themes klasörü değiştirildiği zaman (yeni bir tema eklendiği, eski bir tema silindiği veya isim değişikliği olduğu zaman) SiteTemaları-temelar çifti de silinir. Performans kazancımız ise; son derece yavaş olan IO işlemlerini kullanarak App_Themes klasörünü her defasında okumak yerine, sadece değiştirildiği zaman bu klasörü okumak.



SQL SERVER TABLOLARI ÜZERİNDE CACHE - 1

clock Temmuz 17, 2009 02:46

SQL database üzerinde bulunan datayı RAM'de cache'lemek (diğer bir ifadeyle database tabloları üzerinde dependencyler tanımlamak) ASP.NET 2.0'dan beri desteklenen bir özellik. Pratikte bu, elimizdeki datayı datanın kaynağı olan database update edilene kadar RAM'de tutmak demektir. Bu cache mekanizması SQL Server 7 ve sonrası (SQL 2005 ve SQL 2008) tarafından desteklenir. SQL 2005 ve SQL 2008 aynı zamanda diğer bir cache invalidation tekniğini de destekler. İlk cache tekniğini Tablo seviyesinde SQL Cache, ikincisini de Command (database querysi anlamında) seviyesinde SQL Cache olarak adlandırıyorum. Bu makalede  "Tablo seviyesinde SQL Cache" hakkında bahsedeceğim. "Command seviyesinde SQL Cache" için "SQL SERVER TABLOLARI ÜZERİNDE CACHE - 2" ye bakabilirsiniz.

Tablo seviyesinde SQL Cache
Bu cache mekanizması polling kullananır ve AspNet_CacheTablesForChangeNotification adında cache yapacağımız database üzerinde bir tablo oluşturur. Üzerinde çalışacağımız herbir tablo için de bu özel tabloda yeni bir girdi (entry) yaratılır. ASP.NET Runtime Engine bu herbir entride bir sayaç tutarak bunu ayarlanabilen bir zaman aralığında kontrol eder. Eğer sayacın değeri değişmiş yani tablo update edilmişse cache edilmiş datayı RAM'den siler. Gerekli database şablonunu oluşturmak için aşağıdaki commandları command linedan çalıştıralım.        

aspnet-regsql.exe -E -S .\SQLServerİsmi -d Database ismi -ed
 -E: Windows Integrated Security kullanmak için
 -S: Sql Server ismi için
 -d: Database ismi için
 -ed: database'i aktive etmek için

Yukardaki commandların dışında gerekli tablolar, triggerlar, stored procedurelar için aşağıdakilerini de çalıştırıp herbir tablo için gerekli girdileri oluşturalım:

aspnet-regsql.exe -E -S .\SQLServerİsmi -d Database -t Müsteriler -et
 -t: tablo ismi için
 -et: tabloyu aktive etmek için

Son olarak da web.configde gerekli ayarlamaları yapalım:

 <connectionStrings>
  <add name="MyConString"............ //diğer detaylar buraya />
 </connectionStrings>
 
 <system.web>
  <caching>
   <sqlCacheDependency enabled="true" pollTime="20000">
    <databases>
     <add name="MyCustomCache " connectionStringName="MyConString" pollTime="5000" />
    </databases> 
   </sqlCacheDependency>
  </caching>
 </system.web>
</configuration>


pollTime sayacların ne kadarlık bir zaman diliminde kontrol edileceğini belirtir. Yukarda bu default değer olarak 20000 milisaniye yani 20 saniye olarak ayarlandı. Şimdi de cache'i kullandığımız koda geçelim:

public List UrunleriGetir()
{
    List urunIsimleri = null;

    if (Cache["UrunIsimleri "] != null) 
    {
        urunIsimleri = (List)Cache["UrunIsimleri "];
        //if cache already contains the info return it
    }

    else
    {
        using (SqlConnection conn = new SqlConnection(_connString))
        {
            SqlCommand cmd = new SqlCommand("SELECT UrunIsimleri FROM Urunler", cn);
            urunIsimleri = cmd.ExecuteReader().FillListFromReader(cmd.ExecuteReader());

            //FillListFromReader ExecuteReader() methodunun sonucunu List'e
	    //çevirmek için kullandığım bir method

            SqlCacheDependency dep = new SqlCacheDependency("MyCustomCache", "Urunler");
            //MyCustomCache web.config'de yazdıgımız isim
            //Urunler üzerinde cache yapmak istedigimiz tablonun ismi


            Cache.Insert("UrunIsimleri ", urunIsimleri , dep);
        }
    }
}


ASP.NET 4.0' LA BİRLİKTE GELEN YENİ ÖZELLİKLER

clock Temmuz 13, 2009 05:53
ASP.NET 3.5 gibi ASP.NET 4.0 da birçok yeni özellikle birlikte karşımıza çıkıyor. Şu ana kadar yazmaya fırsat bulamadığım MIX09 konferanslarında ASP.NET 4.0'ın getirdiği yeniliklerle ilgili birçok oturum yapılmıştı. Şimdi bu yeniliklere bakalım ama öncelikle ASP.NET'in web geliştirme ortamına getirdiği yeniliklerin büyük resmini görmek amacıyla 3.5'un getirdiklerine bir bakalım:

  • Microsoft Entity Framework
  • ADO.NET Data Servisleri
  • Dinamik Data
  • Microsoft Ajax Yenilikleri
               --Tarayıcı Geçmişi
               --Script Birleştirimi

Şimdi de ASP.NET 4.0 neler getirmiş onlara bakalım:

Web Formlar:.net hierachy
  • <asp:formView kontrolü artık "RenderTable" özelliğine sahip. "RenderTable=False" şeklinde yazdığımız zaman FormView içeriğini <table>..</table> tagları içerisinde kullanıcıya göndermiyor. Bu özellik önemli çünkü günümüzde artık yazılımcılar <div>.....</div> taglarını .css dosyalarıyla kullanmayı tercih ediyorlar. (<div>'in <table>'a göre avantajları için bak)

  • <asp:ListView kontrolünde bundan sonra <Layout>.....</Layout> bölümünü yazmak zorunda değiliz. Büyük miktarda datayı güzel bir arayüzle sunmak istediğimiz zaman <Layout>'lar işimize yaramasına rağmen büyük küçük her işte kullanmaya gerek olmadığından kullanıcılar için yararlı bir gelişme bu.

  • ViewState, ASP.NET 4.0'da özellikle ayarlanmadığı sürece kullanılmayacak. Yani bundan sonra oturup ViewState'i kapatmak yerine onu gerektiği zaman açmamız gerekecek. Bu da gerekli gereksiz her yerde kullanılan bu özelliğin gereğinden büyük .html kodu üretmesini engelleyecek. Bunu herbir konrol için ayrı ayrı (aynı zamanda @Page için) "ViewStateMode=enabled,disabled,inherit" kullanrak ayarlayabiliriz.

  • Kullanıcı tarafına gönderilen html kodundaki html kontrollerinin ID'leri üzerinde daha fazla kontrol sahibi olacağız. ASP.NET'in bu ID'leri birazda rastgele bir şekilde belirlemesi özellikle JavaScript'le çalışırken ciddi sorunlar oluşturabiliyordu. Örneğin: "document.getElementByID(kontroID)". Bu kodda kontrolün gerçek ID'sini bilmemiz gerekmektedir. ASP.NET 4.0 bu sorunu (control.clientIdMode -->> legacy,static,predictable,inherit(default)) kullanarak çözer.  ( Static "benim verdiğim ID'yi kullan.HTML'de bir sorun olursa ben sorunluyum" anlamına gelir. Predictable ise "rastgele bir şekilde değil de container'ların hiyerarşik sırasını dikkate alarak ID'yi belirle anlamındadır.)

  • Description ve Keyword özellikleri bundan sonra @Page kısmında belirlenebilir. (şu ana kadar klasik html'de meta tagları tek opsiyondu)

  • Web standartlarında güçlendirilmiş kontrol.(xhtml standarts, accessibility standarts section508, wcag, aria) VS2010 içerisinde bu standartların kontrolleri otomatik olarak yapılabilecek.

  • QueryExtender yeni bir ASP.NET kontrolu olarak IQueriable arayüzünü kullanan tüm sınıflar ve entitiler üzerinde sorgu yapabilmemizi sağlayacak.

  • ASP.NET 4.0'da yazılımcılar kendi Cache providerlarını yazabilecek.

  • Session state ziplenmesi (out-of-proc)  GZip kullanılarak mümkün olacak.


ASP.NET Ajax 4.0
  • Burası gerçekten heyecan verici...Ajax 4.0'la birlikte tarayıcı tarafında da databinding yapabileceğiz ve bunun için gerekli kontroller elimizin altında olacak.

  • jquery VS2010'un eklentisi olarak gelecek ve Intellisense'e sahip olacak.

  • Geliştirilmiş Ajax Control Toolkit  (hem server tarafında hem de tarayıcı tarafında)


ASP.NET MVC
  • Kendi başına, tam bir framework olarak gelecek.

ASP.NET Dinamik Data
  • Yeni kontrollerle gelecek.


İYİ BİR WEB SİTESİ HANGİ ÖZELLİKLERE SAHİP OLMALI ?

clock Haziran 19, 2009 23:15
Veriye dayalı (data-driven), içerik temelli (content-based), gerçek bir ihtiyaca cevap verebilecek (real-world) ve piyasada kullanılabilecek kalitede (enterprise level) sitelerin ortak özellikleri nelerdir? Bu özellikler artık çok daha önemli, çünkü sosyal ağ sitelerinin çok daha yaygın kullanıldığı günümüzde artık kullanıcılar daha farklı ihtiyaçlarına cevap arıyorlar ve bunun sonucu olarak karmaşıklaşan web sitelerinin sahip olması gereken nitelikler de artıyor. Yarışın çok daha kızıştığı günümüzde web sitelerinin sahip olması gereken özellikler:

1. Çekici bir Arayüz: Görünüm son derece önemli çünkü siteye giren kullanıcının ilk karşılaştığı sitenin arayüzü. İlk izlenimler her zaman önemlidir. Wink Arayüzün sadece grafikler olmadığını da unutmamak lazım bu arada. Sitenin iyi bir şekilde organize edilmiş olması, kullanıcıların istediklerine kolay bir şekilde ulaşabilmesi ve arayüzün de buna izin vermesi önemli. Diğer önemli bir özellik de sitemizin farklı tarayıcılarda tutarlılığını devam ettirebilmesi. Bundan 5-6 sene önce bunun pek bir önemi yoktu belki çünkü IE'nin kullanım oranı çok yüksekti oysa şimdi diğer tarayıcılar son derece yaygın bir şekilde kullanılıyor. Bu tarayıcıların özellikle .css kullanımlarının farklılığı göz önüne alındığında bunun önemi ortaya çıkıyor

2. Kullanıcı Sadakati: Başarılı bir site kullanıcıların sadakatini yani onların siteyi düzenli bir şekilde siteyi ziyaret etmelerini garanti eder. Bunu sağlamanın yolu ise kullanıcılara; siteye kolay bir şekide içerik yazma, anketlere katılma ve site hakkındaki yorumlarını paylaşabilme imkanı sunmaktır. Ayrıca her kullanıcının bir kullanıcı adı ve şifreye sahip olması ve bunun teknik altyapısının sağlanması, kullanıcıda siteye karşı bir adiyet hissi oluşturur.

3. Kolay Güncellenebilirlilik: Sitede içeriğin kolaylıkla güncellenebilme, yeni içerik kaydedebilme mekanizması olması gerekir. Site canlı, hayatta olmak için sürekli olarak yeni içerik ister. Girdiğimiz bir sitede en son içeriğin 1 sene önce girildiğini görmek istemeyiz. Web'de her şey çok hızlıdır ve dinamiktir. Bunun içinde adminlere kolay kullanılabilir bir site yönetim mekanizması sunulmalıdır.

4. Haber Bültenleri - RSS: Her kullanıcı siteyi sürekli olarak ziyaret etmek istemez. RSS beslemelerini kullanmak isteyenler için, site içeriğini RSS üzerinden de sunmalıdır. Kullanıcıların siteyi belli bir süre sonra tamamen unutabileceğini göz önünde tutarak maillere düzenli bir şekilde haber bültenleri göndermek ve son yazılar, yeni içerik, kampanyalar vb. hakkında bilgilendirme yapmak da önemlidir.
 
5. Kullanıcıdan Geri Bildirim almak: Kullanıcıların sitede beğendikleri ve beğenmedikleri özellikler neler? Bunları öğrenmek ve siteyi geliştirmek için kullanıcılardan geri bildirim alınmalı, arasıra anketler düzenlenmeli.

6. Sosyal Paylaşım: En önemli maddelerden biri... Sosyal ağlar çağında, kullanıcılar arası iletişim bir sitenin ziyaret sayısı ve kullanıcı sadakati için en önemli gerekliliktir. Kullanıcılar chat yapabilmek, olayları ve haberleri tartışabilmek için gerekli altyapıya sahip olmalıdır. Bu siteye aidiyet hissini de güçlendirir.

7. Ana Sayfa:
Web sitelerinin gittikçe karmaşıklaşması ve içeriklerinin artması sonucu ana sayfalar taşmaya başlar. :) Bu noktada kullanıcıların ilgi alanlarına girmeyen içerikle karşılaşabileceğini düşünerekten, kullanıcı spesifik ana sayfaların oluşturulmasını sağlayabilmeliyiz.


CISCO'NUN ÖNÜMÜZDEKİ 5 YIL İÇİN TREND TAHMİNİ

clock Haziran 19, 2009 22:18

Cisco Ceo' su John Chambers geçen hafta bir konferasta "Web"de videoların gelecekte en fazla kullanılan araç olacağını ve iletişimin çoğunlukla videolar üzerinden yapılacağını söyledi. Chambers' a göre bu değişim sadece sitelerin sunduğucisco logo içeriklerde değil gönderdiğimiz maillerde de kendsini gösterecek. Tabi, doğal olarak video'nun temel iletişim aracı olarak kullanılması internet trafiğinin çok daha artmasına yol açacak. Cisco'nun tahminlerine göre internet trafiği önümüzdeki 5 yıl çerisinde 667 exabyte'a ulaşacak ve bunun %90'ın video aktarımı oluşturacak. (günümüzde bu trafik 500 exabyte civarında - 1 exabyte = 1 milyon terabyte) Bu büyüklükte bir trafik ayda 10 milyar DVD'lik bilginin internet üzerinden gönderilmesi demek. Konferasta ayrıca Cisco'nun stratejisini bu araştırma üzerine kuracağı da açıklanmış.

Cisco nedir, kimdir?

Cisco Systems, Inc. bir uluslararası şirket, 66000 çalışanı ve 39 milyar dolar yıllık geliri var. Merkezi San Jose, California'da. Network ve iletişim teknolojisi satıyor. 2008'deki net karı ise 8 milyar dolar. Fortune 500 listesinde 57. sırada.



FACEBOOK, GOOLE'DAN GREG BADROS'U TRANSFER ETTİ

clock Haziran 19, 2009 22:03
Geçtiğimiz hafta Facebook, Google' da birçok projeye imza atmış ve "Senior Director of Engineering" ünvanıyla çalışan Greg Badros' u transfer etti. Greg Badros hem Matematik hem de Bilgisayar Mühendisi bir isim ve 2003' ten beri Google' da çalışıyordu. Bu trasferi ilginç kılan ise Greg Badros' un "Google Calendar, Google Reader, Gmail" gibi projelerin yanında aynı zamanda Google' ın online reklam projesi "Google AdSense" in de takım lideri olması. Bu Facebook'un online reklam alanında ne kadar iddialı olduğunu gösteriyor. Sosyal ağların, online reklam alalında iddiasının ve potansiyelinin tartışıldığı şu günlerde Facebook'un attığı bu adım aynı zamanda son zamanlarda Google' a gelen bir darbe daha denilebilir. ( Microsoft'un arama motoru piyasasında  Bing ile atağa geçmesi gibi ) Badros, Facebook'ta da "Senior Director of Engineering" ünvanıyla çalışacak.
 
Facebook'un resmi açıklaması:

    “Greg Badros has joined Facebook as a director of engineering, reporting to Mike Schroepfer. Greg is one of the most accomplished engineering talents at Google, and it’s wonderful that he has decided to bring these talents to Facebook and take on numerous responsibilities across the engineering organization.”


İpuçları ve Kısayollar 2 : RUNTIME'DA MASTER PAGE NASIL DEĞİŞTİRİLİR?

clock Haziran 15, 2009 08:51
Kişiye özel sayfa tasarımı sırasında, temalar ve css dosyaları dışında bir seçeneğimizde "Master Page" leri değştirmektir. Bunun için Pre_Init event' inde aşağıdaki kodu yazmalıyız. (sadece Pre_Init event'inde bu değişikliği yapabiliriz, sonrasında Master Page ile Content Page zaten birleştirilme aşamasını geçmiştir.)
protected void Page_PreInit(object sender, EventArgs e)
{
    this.MasterPageFile = "~/ikincilMasterPage.master";
}


SAYFA YENİLEDİKTEN SONRA İMLEÇ KONUMU NASIL KORUNUR?

clock Haziran 12, 2009 08:29

ASP.NET' te sayfa yenilendikten sonra ( PagePostBack yapıldıktan sonra ) sayfanın tarayıcıdaki konumunu devam ettirmek, özellikle uzun web sayfalarında önemli olabilir. ASP.NET bunu gerçekleştirmek için Page objesinin maintainScrollPositionOnPostBack propertisini ( özelliğini ) sunar. Bu özelliği şu 3 yöntemle kullanabiliriz:

       1.Uygulama Seviyesinde: Web.config üzerinde aşağıdaki konfigurasyonu yapmamız gerekir:

               <pages maintainScrollPositionOnPostBack="true">

       2. Sayfa Seviyesinde: Herhangi bir .aspx sayfasında:

              <%@ Page MaintainScrollPositionOnPostback="true" ... 

       3.Kod üzerinde: Programlayarak bu işi yapmak istersek:

              Page.MaintainScrollPositionOnPostBack = true;



SERVERDAN TARAYICIYA GİDEN HTTP ÇIKTISINI ZİPLEME

clock Haziran 2, 2009 03:50
Server'la tarayıcı arasındaki iletişim HTTP protokolüyle sağlanır. Server, gerekli bilgiyi HTTP mesajlarıyla gönderir ve istekleri de yine aynı şekilde alır. Günümüz tarayıcılarının çoğu gelen HTTP çıktısının "gzip" ve "deflate" algoritmalarıyla sıkıştırılmış mesajlarını tekrar orjinal şekline getirme özellğine sahip olduğundan; ASP.NET' le kullanıcıya ziplenmiş HTTP göndererek "bandwith" ten ciddi kazançlar sağlayabiliriz. Bunu yapmamız için "HttpModule" kullanmamız gerekiyor. Öncelikle VS2008 de Windows Class Library açalım, C#'la.

Note: HttpModule'ler Request ve Response'ları kontrol eden kontrollerdir. Yani HttpModule kullanarak ASP.NET'in kullanıcıya gönderdiği çıktıyı, gönderilmeden hemen önce, rafine etmiş oluyoruz bir bakıma.
 
 
Name kısmına "ZipModule" yazalım. "CompressionModule" adıyla yeni bir sınıf ekleyelim projeye. Proje ismine sağ tıklayıp "Add Reference"i seçip "System.Web"i ekleyelim. Sonrasında da aşağıdaki kodu yazalım:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace ZipModule
{
    //Modülümüzün HttpModule olması için "IHttpModule" arayüzüne implement etmeliyiz

    public class CompressionModule : IHttpModule  
    {

        #region IHttpModule Members

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
		//"default" "eventhandler" dışında kendi "handler" ımızı yazmalıyız.
		//context -->> HttpModule'ü çağıran "projemiz"
        }

        void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
		//HttpModulu'müzü çağıran projeyi "app" olarak isimlendirdik

            string encodings = app.Request.Headers.Get("Accept-Encoding");
		//"Accept-Encoding" tarayıcıların, zipleme işlemlerini destekleyip
		//desteklemediklerini server'a bildirdikleri HttpHeader'ı

            if (encodings == null) //desteklemiyorsa çık
                return;

            Stream s = app.Response.Filter;
		//destekliyorsa server çıktısını filtrele

            encodings = encodings.ToLower();

            if (encodings.Contains("gzip"))
            {
                app.Response.Filter = new GZipStream(s, CompressionMode.Compress);
		    //burası server çıktısını ziplediğimiz yer (gzip kullanarak)
			
                app.Response.AppendHeader("Zipleme Yöntemi", "gzip");
		    //burası modülümüzün çalışıp çalışmadığını kontrol
		    //için ilerde kullanacağımız kısım
		
                app.Context.Trace.Warn("GZIP Compression on");
            }

            else
            {
                app.Response.Filter = new DeflateStream(s, CompressionMode.Compress);
		    //tarayıcı "gzip"i desteklemiyorsa "deflate" 
		    //kullanarak sıkıştırıyoruz
			
                app.Response.AppendHeader("Content-Encoding", "deflate");
                app.Context.Trace.Warn("Deflate compression on");
            }

        }

        #endregion
    }
}

 
Projeyi "build" ettikten sonra Proje klasöründe bulunan "bin" klasöründen "ZipModule.dll" dosyasını, VS2008'den açtığımız Website'a ekleyelim. Sonrasında "Add Reference" kısmına girip "Browse" dan dll'imizi siteye referans olarak ekleyelim. Şimdi "web.config" dosyasına:
 
<httpModules>
    <add name="HttpCompressionModule" type="ZipModule.CompressionModule"/>
</httpModules>
<trace enabled="true"/>


yazalım. "<trace enabled="true"/>" yazarak herbir Request ve Response sırasında ne yapılmış edilmiş onu göreceğiz. ( web.config dosyasına yukardaki xml'i yazdıktan sonra HttpModule'ümüzün çalışması gerekiyor artık, ekstra bir ayarlamaya gerek yok. ) Şimdi "Default.aspx" sayfasını açalım ve "../Default9.aspx/trace.axd" yazalım. "View Details" e tıkladığımızda "Gzip compression on" yazısını görebiliyorsak (aşağıdaki resimdeki gibi) HttpModülümüz çalışıyor demektir, yani artık ziplenmiş, sıkıştırılmış Http mesajları gönderebiliyoruz.
 


.NET' TE I/O İŞLEMLERİ - 2 (Dosya okuma ve yazma işlemleri)

clock Haziran 2, 2009 01:56
System.IO'ya kaldığımız yerden devam ediyoruz. (ilk makaleyi görmek için) .NET IO'da hangi okuma ve yazma işlemi yapıyorsanız yapın bir "stream" kullanmak zorundasınız. Yani dosyaya yazarken, dosyadan okurken, porta yazıp, porttan okurken vb. "Stream" soyut sınıfınından türetilen özelleşmiş stream'leri kullanmamız gerekiyor. Birkaç tanesini yazmak gerekirse

  • System.IO.FileStream
  • System.IO.MemoryStream
  • System.Net.Sockets.NetworkStream
  • System.IO.BufferedStream

Bu makalede System.IO.FileStream'i kullanağız, dosyaya yazma ve dosyadan okuma işlemleri için. Örneğin şu koda bakalım:

FileStream fs = new FileStream(Server.MapPath("deneme.txt"), FileMode.Open);
//FileStream kullanarak dosyayı okumaya başlıyoruz. FileMode.Open dosyanın
//sadece açılacağını üzerinde başka bir işlem yapılmayacağını gösteriyor.
//diğer değerler şunlar olabilirdi: Append,Create,Truncate,CreateNew,OpenOrCreate

byte[] data = new byte[fs.Length];

fs.Read(data, 0, (int)fs.Length); 
//işlemin istediğimiz aralıktaki sonucunu, örnekte tamamını 
//0'dan length'e kadar, array'a yazıyoruz

foreach (byte k in data)
{
     Response.Write(k.ToString());
}
//ve aldığımız sonucu kullanıcıya gönderiyoruz

Bu örneği denediğiniz zaman anlamsız sayılarla karşılacaksınız, ekranda. Sebebi "FileStream" lerin dosyadan okuduğu data'yı "byte" olarak vermesi. Bu "byte" ları tekrar anlaşılabilir bir şekle çevirme işlemini yapmak istemiyorsak "System.IO.StreamWriter" ve "System.IO.StreamReader" sınıflarını kullanmamız gerekiyor.

StreamWriter writer = new StreamWriter(File.Open(Server.MapPath("enes.txt"), FileMode.Open));
//file.open() -->> streamwriter icin filestream olusturur bizim için

writer.Write("dosyaya yaz");
writer.Close();

//////////////////////////////////////////////////////////

StreamReader reader = new StreamReader(File.Open(Server.MapPath("enes.txt"), FileMode.Open));

Label1.Text = reader.ReadLine(); 
reader.Close();
"System.IO.StreamWriter" ve "System.IO.StreamReader" sınıfları bizim için "System.IO.FileStream" objelerini kendileri oluşturur. "Label1.Text = reader.ReadLine(); " kodu dosyayı satır satır okumamızı sağlar. Eğer tüm dosyayı bir keresinde okumak isteseydik: "Label1.Text = reader.ReadToEnd();" yazmamız gerekirdi. Bu metodların dışında "System.IO.File" sınıfının işimiz kolaylaştıran, tüm işlemleri en kısa yoldan yapan statik metodları da var.
string k = File.ReadAllText(Server.MapPath("enes.txt"));     
ve
File.WriteAllText(@"C:\temp.txt",data);