Microsoft Ajax CDN

Microsoft geçtiğimiz aylarda web uygulama geliştiriciler için kendi CDN(Content Delivery Network) hizmetini duyurmuştu. Bu hizmet sayesinde artık uygulamalarımızda kullanmak istediğimiz Microsoft Ajax Library ve jQuery script dosyalarını doğrudan proje içerisinde saklamaya ihtiyaç duymuyoruz. Şöyle ki, bu hizmet zaten bahsi geçen dosyaların Microsoft sunucuları üzerinde saklanmasını ve uygulamaların bu dosyaları referans olarak alması durumunda ilgili kütüphanelerin kullanabilmesini sağlıyor. Bu çok mu gerekli diye sorabilirsiniz, cevabı tamamen sizin ihtiyacınıza bağlı. Sonuçta aynı dosyaları kendi projeniz içerisinde barındırdığınızda, istediğiniz zaman istediğiniz kısımlarını değiştirme, güncelleme şansına sahipsiniz. Ancak diğer tarafta bahsettiğimiz kütüphanelerde zaten çok ciddi ekipler tarafından geliştirilen ve üzerinde çok da fazla değişiklik yapılmaya ihtiyaç duyulmayan kütüphaneler. Dolayısıyla bu kütüphanelerin güvenilir bir CDN hizmeti üzerinden kullanımı performans ve uygulamadaki dosya karmaşasını azaltmak adına doğru hareketler olacaktır. CDN hizmetini sunan kurum dünyanın farklı konumlarında bu dosyaları barındırması için belki de binlerce sunucu kullandığı için sizin uygulamanıza gelen talepler load balancer'lar aracılığıyla en hızlı hizmet sunacak konumdaki sunucuya yönlendiriliyor.

Microsoft Ajax Library olsun jQuery olsun eklenti dosyaları ile birlikte ciddi büyüklüğe sahip(Microsoft jQuery’nin core dosyaları dışındaki eklenti dosyaları için CDN hizmeti sunar mı, şimdilik bilinmiyor) Dolayısıyla bu kadar dosyayı sunucuda barındırmak özellikle JavaScript dosyaları için hiyerarşi karmaşasına yol açabilir. Böyle bir karmaşa içerisinde çalışmak istemeyenler için şiddetle Microsoft, Yahoo, Google, Amazon gibi sağlayıcıların CDN hizmetlerini kullanmalarını tavsiye ederim. Microsoft AJAX CDN için bu sayfadan gerekli bilgileri alabilirsiniz.

Gelelim basit bir örnek ile Microsoft CDN'i test etmeye. Aşağıdaki kod parçalarında bir text input kontrolüne Microsoft Ajax Library'de yer alan Calendar bileşenini bağlıyorum. Dikkat edeceğiniz gibi CSS ve JavaScript dosyalarının konumları ajax.microsoft.com adresi üzerinden verilmiş.

<link href="http://ajax.microsoft.com/ajax/beta/0911/extended/Calendar/Calendar.css" rel="stylesheet" type="text/css" />

 

<script type="text/javascript" src="http://ajax.microsoft.com/ajax/beta/0911/Start.js"></script>

<script type="text/javascript" src="http://ajax.microsoft.com/ajax/beta/0911/extended/ExtendedControls.js"></script>

 

<script type="text/javascript">

    Sys.require(Sys.components.calendar);

 

    Sys.onReady(function () {

        Sys.create.calendar("#txt1");

    });

</script>

Visual Studio'da JavaScript kodlarını yazarken dahi intellisense özelliğinin tıkır tıkır çalıştığını, Microsoft Ajax Library'de yer alan nesne ve fonksiyonlara kolayca erişebildiğinizi göreceksiniz. Sayfayı çalıştırırken Fiddler gibi bir web debugger uygulaması kullanarak sayfayı izlerseniz olayın detaylarını da güzel bir şekilde görebilirsiniz.

Göreceğiniz gibi kırmızı kutu içerisindeki dosyalar sadece bizim kod içerisinde referansını verdiğimiz dosyalar. Önceki yazımın Script Loader kısmında belirttiğim gibi Microsoft Ajax Library çalışma anında ihtiyacı duyduğu dosyaları da istemciye yüklemektedir. İşte resimde mavi kutu içerisinde gördüğünüz dosyalar da diğer script dosyalarıdır. Tüm dosyaların Host kolonundaki adres bilgilerine bakacak olursanız dosyaların ajax.microsoft.com adresinden çekildiğini görebilirsiniz. Sonuç olarak sorunsuz ve daha hızlı çalışan bir AJAX uygulaması elde etmiş olduk.

17 Ocak 2010 Pazar 14:54

Yorum - RSSYorumlar (1)


facebook'da Paylaş   twitter'da Paylaş   friendfeed'de Paylaş   del.icio.us'da Paylaş   stumpleupon'da Paylaş   Permalink

Microsoft Ajax Library (Yoksa ASP.NET AJAX 4.0 mı Desek?)

Geçtiğimiz ay içerisinde gerçekleşen PDC’09 konferansında Microsoft, ASP.NET AJAX adındaki AJAX kütüphanesini AJAX Control Toolkit ile birleştirerek artık Microsoft AJAX Library adında bir ürün ile yola devam edeceğini açıkladı. Microsoft AJAX Library! Kulağa hoş geliyor. Şu an Beta sürümü Codeplex üzerinden indirilip kullanılabilen bu kütüphane sadece ASP.NET WebForm uygulamalarında değil, ASP.NET MVC, PHP, Ruby on Rail gibi tüm web uygulamalarında kullanılabilir hale getiriliyor. Aslında ASP.NET AJAX jQuery’leşiyor diyebiliriz bu değişikliğe. Her ne kadar .NET Framework’den ayrı olarak geliştirilse de, ASP.NET 4.0 ile birlikte bu ürünün resmen duyurulması bekleniyor. Ben de geçtiğimiz haftalarda gerçekleştirdiğimiz INETA NEXT etkinlikleri vesilesiyle Microsoft Ajax Library’i inceleme şansına sahip oldum.

Microsoft Ajax Library ile neler değişiyor, ne gibi yenilikler geliyor. Şöyle kısaca özetlemeye çalışayım. İlerleyen zamanlarda fırsat bulursam belki detaylı yazılara da yer verebilirim.

Büyük ve düzenli bir JavaScript kütüphanesi: Temel Ajax kütüphanesi dışında Control Toolkit kontrollerinin istemci tarafında kullanılmasına olanak sağlaması nedeniyle JavaScript arşivi oldukça genişlemiş durumda. Debug dosyaları ile birlikte yaklaşık 200 .js dosyasına sahip bir kütüphanemiz var artık. Tabi ki akla ilk gelen bu dosyaların tamamını veya büyük kısmını uygulamamızda saklamak durumunda mıyız? İsterseniz saklayabilirsiniz, istemezseniz alttaki maddeyi okumanızı tavsiye ederim :)

Microsoft Ajax CDN: Microsoft kendi Ajax kütüphanesini ve jQuery kütüphanesini yine geçtiğimiz aylarda açtığı CDN(Content Delivery Network) hizmeti üzerinden ücretsiz olarak sunmakta. Yani yukarıda bahsettiğimiz JavaScript dosyalarının hiçbirini uygulamanızda barındırmadan kullanabilme şansına sahipsiniz. Bu hizmeti kullanarak uygulamanızın performansını daha iyileştirebileceğiniz gibi, sitenizin gereksiz bandwith tüketimini azaltmış olabiliyorsunuz. Yapmanız gereken tek şey .js dosyalarının referansını Microsoft’un sunucuları üzerinden vermek. Üstelik Visual Studio üzerinde çalışırken internete bağlı iseniz JavaScript intellisense özelliğini aynen kullanabiliyorsunuz.

Script Loader: Ajax Library’de yer alan script loader fonksiyonu(Sys.create) ile ihtiyaç duyduğunuz script dosyalarının sayfanın yüklenmesi esnasında istemciye gönderilmesi sağlanabiliyor. Nasıl yani, anlamadım demiş olabilirsiniz. Şöyle ki, malum artık kalabalık bir istemci kütüphanemiz var. Yapılacak bir işlem için veya oluşturulacak bir nesne için hangi JavaScript dosyaları gerekli sorusunu Script Loader sayesinde düşünmeye pek gerek kalmıyor. Sayfaya sadece temel script dosyalarını ekledikten sonra gerekli işlem veya kontrol ile ilgili çağırımları yaptığınızda arka planda gerekli tüm script dosyaları istemciye gönderilmekte. Örneğin Sys.require([Sys.components.dataView, Sys.scripts.WebServices]); ifadesi ile hem dataView nesnesini kullanacağınızı, hem de bir web servisine bağlanma işlemi yapacağınızı söylüyorsunuz, script loader da arka planda gerekli olan tüm script dosyalarını otomatik olarak istemciye yüklüyor.

İstemci Tarafında Data Yükleme(Client-side Data Binding): dataView adındaki nesne sayesinde artık istemci tarafında data binding işlemi yapılabiliyor. Microsoft Ajax Library’deki en göze batan yeniliklerden olan dataView nesnesi, arka planda bir AJAX talebi ile getirilen verilerin doğrudan istemci tarafında HTML koduna render edilmesini sağlıyor. Özellikle yoğun veri transferi yapılan iş uygulamalarında network trafiğini azaltmak ve hız adına müthiş bir yapı sunan bu özellik ile AJAX işlemleri daha performanslı hale geliyor. Diğer yandan dataView nesnesi sayfa ilk yüklendiğinde statik olarak HTML kodu içerisinde veri saklamayıp, {{ProductName}} şeklinde tanımlayıcıları bulundurduğu için, bu yapının arama motorları açısından bir dezavantaj olduğunu söyleyebiliriz. Tabi ki ilerleyen zamanlarda arama motorları bu tarz string veriler üzerinde özel indekslemeler yapacaktır diye temenni ediyoruz.

jQuery Entegrasyonu: Farklı JavaScript kütüphanelerine kolayca entegre edilebilen jQuery’nin Microsoft Ajax Library ile birlikte çalışması da sağlanmış durumda. Mesela jQuery seçicisi ile seçilen nesneye Ajax Library’de yer alan bir kontrolü kolayca bağlayabiliyorsunuz. Örneğin gerekli öntanımlamalar yapıldıktan sonra yazılan $("#txt1").calendar(); ifadesi jQuery ile seçilen txt1 elementine calendar nesnesi bağlamaktadır.

Client DataContext ve AdoNetDataContext: Açıkcası bu nesnelerle ilgili örnek yapma şansım olmadı, ama madem böyle bir yazı yazdık eksik madde kalmasın:) Burada belirtilen DataContext nesneleri ile bir web servisi veya Data Service üzerinden yapılan veri işlemleri iki yönlü olarak kolayca gerçekleştirilebilmekte. Somutlaştırmak gerekirse; web servisinden getirdiğiniz verileri istemciye yükledikten sonra, istemcinin bu veriler üzerinde yaptığı değişiklikleri ekstra efor sarfetmeden yine web servisi üzerinden sunucuya gönderebilmeniz mümkün. Tabi ki burada seçme ve güncelleme işlemini yapacak iki ayrı web metoduna ihtiyaç duyulacaktır.

Yine belirtilmekte fayda duyduğum önemli bir hususta Microsoft’un bu ürünün arkasında resmi olarak durması ve tam destek vereceğini belirtmesi. Bilindiği gibi bu zamana kadar Ajax Control Toolkit Microsoft tarafından resmi ürün olarak lanse edilmiyordu. Ajax Library içinde yer alan bu kütüphanede artık destek kapsamında. Görüldüğü gibi .NET Framework 4.0’ın çıkması ile sadece sunucu tarafında değil, istemci tarafında da çalışmamız gereken bir hayli ev ödevimiz var. İlerleyen zamanlarda bu konulara daha detaylı şekilde değinmek dileğiyle...

4 Ocak 2010 Pazartesi 00:20

Yorum - RSSYorumlar (3)


facebook'da Paylaş   twitter'da Paylaş   friendfeed'de Paylaş   del.icio.us'da Paylaş   stumpleupon'da Paylaş   Permalink

ASP.NET’te jQuery ile AJAX İşlemleri

jQuery artık web uygulamalarında sıklıkla kullanılır hale geldi. Gerek sayfa tasarımına harika görseller ve efektler katması, gerekse AJAX taleplerini basit ve hızlı gerçekleştiriyor olması bu kütüphaneyi programcılar ve tasarımcılar için çok cazip hale getiriyor. Son zamanlarda jQuery ile bir web servisinin veya PageMethod'un nasıl çağrılabileceği şeklinde sık sık sorular duyunca ben de jQuery ile ASP.NET uygulamalarında farklı AJAX taleplerinin nasıl yapılabileceği ile ilgili ufak bir uygulama hazırladım. Bu doğrultuda bu yazıda da;

  • ASP.NET sayfasına
  • Parametre alan bir ASP.NET sayfasına
  • Web servisine
  • PageMethod'a

jQuery ile nasıl AJAX talepleri yöneltebileceğimizi inceleyeceğiz.

Öncelikli olarak jQuery kütüphanesinde AJAX taleplerini gerçekleştireceğimiz ajax isimli fonksiyonu tanıyalım. ajax fonksiyonu parametre olarak talep yapılacak url, varsa parametre verilerini, bu verileri iletme yöntemini(GET,POST gibi), talep sonucunda okunacak verinin tipi gibi bilgileri alır. Bunların dışında işlemin başarılı gerçekleşmesi durumunda sayfada güncelleme yapılmasını sağlayan veya hata oluşması durumunda gerekli işlemlerin yapılmasını sağlayan iki fonksiyon tanımlamasını da kendi içerisinde bulundurabilir. Burada saydığımız parametrik değerlerin tamamı zorunlu değildir, yapılan talepteki duruma göre sadece ihtiyaç duyulan parametreler kullanılabilir. Aşağıda AJAX talebi için kullanılabilecek basit bir metot çağırımı görülmektedir.

$.ajax({

    type: 'GET',

    url: 'Sayfa.aspx',

    success: function(result) {

        $('#sonuc').html(result);

    },

});

Parametrelerin ne anlama geldiğine bakalım:

type: Yapılacak talebin veri iletim yöntemi. GET, POST gibi.
url: Asenkron talebin yapılacağı adres.
success: Talebin başarılı bitmesi durumunda çalışacak fonksiyon. Burada talep sonucunda gelen veriler sayfaya işlenir.

Bunlar dışında kullanılabilecek birkaç parametre daha var, bu parametrelere ilerleyen kısımlarda değineceğiz. Buradaki success parametresinin değer olarak aldığı fonksiyon tanımlamasını C# dilindeki isimsiz metotlara(anonymous methods) benzetebiliriz. success metodundaki result değişkeni AJAX talebi sonucunda okunan veriyi taşımaktadır. Bu fonksiyon içerisindeki $('#sonuc') ifadesi de sayfamızdaki sayfa id'sini taşıyan HTML elementini işaretleyen bir jQuery seçici ifadesidir. Dönen AJAX cevabı sonuc isimli HTML elementinin içeriğine yazdırılacaktır. Artık bir örnek ile bu talepleri nasıl yönetebileceğimizi incelemeye başlayalım.

NOT: jQuery'de seçiciler, olaylar gibi temel kavramlar hakkında detaylı bilgi almak isterseniz size jQuery'nin resmi sitesini veya bu konuda zengin Türkçe içeriğe sahip olan www.eburhan.com adresini incelemenizi tavsiye ederim.

NOT: jQuery'de ajax() fonksiyonu dışında get() ve post() isimli fonksiyonlarla da AJAX talepleri yapılabilmektedir. Aynı işlemleri yapan fakat farklı kullanım şekilleri olan get ve post isimli jQuery fonksiyonları ile ilgili de araştırma yapabilirsiniz.

ASP.NET Sayfasına Talepte Bulunmak

jQuery fonksiyonunu oluşturmadan önce sayfamız içerisindeki HTML elementlerini hazırlayalım.

Default.aspx

<input type="text" id="text1" />

<input type="button" value="Seç" onclick="CallAspxPage();" /><br />

<span id="sonuc"></span>

Butona tıklandığında çağrılacak JavaScript fonksiyonu içerisinde jQuery ile yapılacak çağrının cevabı sonuc adındaki alana yazdırılacak. Geldik işin asıl önemli olan kısmına; jQuery ajax fonksiyonunun yazımına. Aşağıda basit olarak bir ASP.NET sayfasına yapılacak jQuery talebi görülmektedir.

Default.aspx

<script type="text/javascript">

    function CallAspxPage() {

        $.ajax({

            type: 'GET',

            url: 'Ajax1.aspx',

            success: function(result) {

                $('#sonuc').html(result);

            },

            error: function() {

                alert('Talep esnasında sorun oluştu. Yeniden deneyin');

            }

        });

    }

</script>

url kısmında yer alan Ajax1.aspx isimli dosyaya talepte bulunuyor ve dönen cevabı sonuc isimli span elementine yazdırıyoruz. Burada az önce gördüğümüz standart ajax fonksiyonu tanımlamasının dışında bir de error adında bir parametreyi görüyoruz. error parametresine bağlanan isimsiz metot ise talep esnasında bir hata ile karşılaşılırsa çalışacak. Sayfayı çalıştırıp butona tıklamamız durumunda sonuc isimli elementin içeriğine Ajax1.aspx sayfasının çıktısı gelecektir. Buradaki örnek aslında tüm web sayfası dosyaları için geçerli bir kullanım şeklidir. htm, asp, aspx, ashx, php gibi dosyalara da buradaki kod parçasında gördüğünüz şekilde talepte bulunabilir ve oluşan çıktıyı okuyabilirsiniz.

ASP.NET Sayfasına QueryString ile Talepte Bulunmak

jQuery'de ASP.NET veya sunucu taraflı çalışan başka bir sayfaya QueryString ile parametre gönderebilmek için ajax fonksiyona data isimli parametre ile değer göndermek gerekir. Burada parametreleri göndermek için farklı bir yazım biçimi bulunmaktadır. data: '{ "name":"Uğur" }' şeklinde kullanılan bu parametrede dikkat edileceği üzere değer süslü parantez karakterleri({}) içerisinde taşınmakradır. Parametre adı ve değeri çift tırnak karakteri(") içerisinde taşınmakta, eşitlik operatörü olarak da iki nokta karakteri(:) kullanılmaktadır. Eğer birden fazla parametre iletilecekse parametreler virgül karakteri(,) ile ayrılmalıdır. Aşağıda bir Ajax1.aspx isimli sayfamıza URL üzerinden parametre iletilerek ajax talebinin nasıl gerçekleştirileceği görülmektedir. Sayfada yer alan button elementimizin onclick niteliğini de aşağıdaki fonksiyonun adı ile değiştirmek gerektiğini belirtelim.

Default.aspx

function CallAspxPageWithQueryString() {

    $.ajax({

        type: 'GET',

        url: 'Ajax1.aspx',

        data: 'name=' + escape($('#text1').val()),

        success: function(result) {

            $('#sonuc').html(result);

        },

        error: function() {

            alert('Talep esnasında sorun oluştu. Yeniden deneyin');

        }

    });

}

Sayfayı çalıştırıp text1 isimli elemente bir isim girişi yapacak olursak Ajax1.aspx sayfasına ismin QueryString ile gönderildiğini ve sonucun sayfamızda yer aldığını görebiliriz.

Not: Yukarıda kullanılan escape() JavaScript fonksiyonu olası Türkçe karakter problemlerini gidermek amacıyla kullanılmıştır.


Resim: QueryString ile sayfaya gönderilen AJAX talebinin sonucu alındı

Web Servisine Talepte Bulunmak

jQuery ile XML Web Servislerine yapılan talepler JSON formatında elde edilerek değerlendirilebilmektedir. Web servislerine yapılan talep normal bir sayfa talebiyle benzerdir. Web servislerine yapılan talebin POST metoduyla gerçekleşmesi, contentType, dataType ve data parametrelerinin ajax fonksiyonunda belirtilmesi gerekmektedir. Çağrılan WebMethod parametre almıyorsa dahi data parametresi boş olarak verilmelidir. Aşağıda yerel makinede(localhost) yer alan ve name ile surname parametrelerini alan bir web servisine talep gerçekleşmektedir. Web servisindeki HellojQuery isimli metot web servis URL'sinin sonuna yazılmıştır.

NOT: Çağrılacak web servis class'ının System.Web.Script.Services.ScriptService niteliğini(attribute) uygulaması gerekmektedir. Böylece servis nesnesi kendisine gelecek asenkron taleplere cevap verebilecektir.

Default.aspx

function CallWebservice() {

    $.ajax({

        type: 'POST',

        url: 'http://localhost:5199/JQueryWebService/Service.asmx/HellojQuery',

        data: '{ "name":"Uğur","surname":"Umutluoğlu" }',

        contentType: 'application/json; charset=utf-8',

        dataType: 'json',

        success: function(result) {

            $('#sonuc').html(result.d);

        },

        error: function() {

            alert('Talep esnasında sorun oluştu. Yeniden deneyin');

        }

    });

}

Görüldüğü gibi web servisine yapılan talep JSON formatında okunmakta ve gelen değerler sayfaya aktarılmaktadır. Eğer web servisi parametre almıyor olsaydı data parametresi; data: '{}' şeklinde boş değer ile yazılmalıydı.

PageMethod'a Talepte Bulunmak

ASP.NET AJAX uygulamalarında sayfa içerisine yazdığımız WebMethod niteliği uygulamış static metotları asenkron talepler ile çağırabilmekteyiz. Bu tip metotlara PageMethod adı verilmekte ve ScriptManager ile istemciye yüklenen JavaScript fonksiyonları sayesinde bu metotlar AJAX taleplerinde kullanılabilmektedir. Benzer şekilde bu metotları jQuery ile yapılan AJAX taleplerinde de kolayca kullanabilmekteyiz. İlk olarak sayfamızın code-behind dosyasına bir tane PageMethod ekliyelim ve jQuery ile bu metodu nasıl çağıracağımızı görelim.

Default.aspx.cs

public partial class _Default : System.Web.UI.Page

{

    [System.Web.Services.WebMethod]

    public static string jQueryPageMethod(string name)

    {

        return "<h3>jQuery - PageMethod Talebi</h3>Merhaba " + name;

    }

}

PageMethod'lar ile ilgili daha detaylı bilgi almak daha önceden yazdığım bu yazıyı inceleyebilirsiniz. Peki yazdığımız bu metodu nasıl çağıracağız? Aşağıda jQueryPageMethod isimli metodun ajax fonksiyonundan nasıl çağrıldığı görülmektedir. Çağırım şekli web servisi çağırımına oldukça benzemektedir.

function CallPageMethod() {

    $.ajax({

        type: 'POST',

        url: 'Default.aspx/jQueryPageMethod',

        data: '{ "name":"Uğur" }',

        contentType: 'application/json; charset=utf-8',

        dataType: 'json',

        success: function(result) {

            $('#sonuc').html(result.d);

        },

        error: function() {

            alert('Talep esnasında sorun oluştu. Yeniden deneyin');

        }

    });

}

Bu şekilde bir ASP.NET uygulamasında farklı bileşenlere jQuery ile nasıl AJAX talepleri gönderebileceğimizi incelemiş olduk.

17 Aralık 2009 Perşembe 08:53

Yorum - RSSYorumlar (8)


facebook'da Paylaş   twitter'da Paylaş   friendfeed'de Paylaş   del.icio.us'da Paylaş   stumpleupon'da Paylaş   Permalink

Cache Nesnesine Erişimde Kullanılabilecek Design Pattern’ler

Caching(önbellekleme) web uygulamalarında kullanılan en önemli performans iyileştirme yöntemidir. Normal şartlarda üretilmesi gerek zaman, gerekse kaynak tüketimi açısından maliyetli olan sayfa ve nesneler caching mekanizması ile sunucunun belleğinde(RAM) saklanabilmektedir. Böylece çok hızlı erişilebilir bir nesne elde edilerek uygulamadaki sayfaların çok daha hızlı çalışması sağlanabilmektedir. Data caching yapılırken kullanılan Cache nesnesinin kullanımı pratikte oldukça basittir. Ancak Cache nesnesinin daha düzgün çalışabilir olması uygulamaların sağlığı açısından da önemlidir. Zira hiç hesapta olmayan durumlarda karşılaşılacak hatalar nedeniyle kullanıcılara hata sayfası görüntülemek zorunda kalabilir veya Cache nesnesini gereksiz yere tekrar üreterek performans kayıplarına yol açabilirsiniz. Bu yazımızda Cache nesnesinin kullanımında önemli olan iki farklı tasarım deseninin(design pattern) uygulanışını ve bu yöntemlerin faydalarını inceleyeceğiz.

Klasik Yöntem: Singleton Pattern Kullanımı

Öncelikli olarak Cache nesnesinin normal kullanımına ve bu kullanımda ne gibi bir sıkıntı olduğuna bakalım. Aşağıdaki kod örneklerinde veritabanından getirilen kayıtlar Cache nesnesinde saklanmaktadır. Cache nesnesi belirli aralıklarla doldurulmalı ve zaman aşımına uğradığında içeriği yenilenmelidir. Dolayısıyla aşağıdakine benzer bir if kontrolü akışın düzgün gitmesini sağlar. Aslında burada kullandığımız kodlama biçimi Singleton Pattern olarakta bilinmektedir.

Not: Örnekteki kodlar CacheHelper adındaki yardımcı bir sınıf içerisinde yer almaktadır.

CacheHelper.cs

public static class CacheHelper

{

    static Cache cache;

 

    static CacheHelper()

    {

        cache = HttpContext.Current.Cache;

    }

 

    public static DataTable GetProductsSingletonPattern()

    {

        //Cache nesnesinin daha önceden referansının oluşup oluşmadığı kontrol edilir

        if (cache["Products"] == null) //Cache nesnesinin içeriği ilk kez burada okunur

        {

            SqlConnection con = new SqlConnection("data source=localhost; database=Northwind; integrated security=true");

            SqlDataAdapter da = new SqlDataAdapter("Select * From Products", con);

            DataTable dt = new DataTable();

            da.Fill(dt);

            cache.Insert("Products", dt, null, DateTime.Now.AddMinutes(5), System.Web.Caching.Cache.NoSlidingExpiration);

        }

 

        return (DataTable)cache["Products"]; //Cache nesnesinin içeriği ikinci kez burada okunur

    }

}

Görüldüğü gibi öncelikli olarak Cache nesnesinin içeriğinin null olup olmadığı kontrol edilmektedir. Cache null ise veritabanına bağlanarak gerekli veriler alınmakta ve Cache nesnesine aktarılıp metottan geri döndürülmekte, null değilse doğrudan Cache içeriği metottan geri döndürülmektedir. Yazılış ve işleyiş açısından düzgün bir kod yazımı gibi görünse de burada ufak bir ayrıntı var.

Daha Etkili Bir Yöntem: State Bag Access Pattern Kullanımı

Yukarıdaki kod parçasında if koşulunun bulunduğu satıra gelindiğinde Cache null değilse, ama return ifadesinin yer aldığı satıra gelindiğinde Cache bellekten silinmiş ve null gelmişse ne olur? "Yok, o kadar da olmaz diyebilirsiniz", haklısınız. Çünkü iki satır arasındaki geçiş belki de birkaç milisaniye olacaktır. Ancak bu durumunda gerçekleşmesi az da olsa ihtimal dahilindedir. Eğer geliştirdiğiniz projede bu tip bir sorun nedeniyle kullanıcılara hata sayfası görüntülemeniz sıkıntı doğuracaksa burada yapılacak birkaç değişikle kodunuzu güzel şekilde optimize edebilirsiniz. Yapılacak iş ise metot içerisinde ilk olarak Cache nesnesinin değerini bir değişkene aktarmak ve değişken üzerinden gerekli işlemleri gerçekleştirmektir. Buradaki kod yazım biçimi literatürde State Bag Access Pattern olarak bilinmekte ve sadece Cache nesnesi değil, Session, Application gibi diğer durum yönetimi nesnelerinde de kullanmasında fayda olan bir tasarım desenidir.

CacheHelper.cs

public static DataTable GetProductsStateBagAccessPattern()

{

    //Bu desende Cache nesnesi sadece bir kez okunur

    DataTable dt = cache["Products"] as DataTable;

    if (dt == null)

    {

        SqlConnection con = new SqlConnection("data source=localhost; database=Northwind; integrated security=true");

        SqlDataAdapter da = new SqlDataAdapter("Select * From Products", con);

        dt = new DataTable();

        da.Fill(dt);

        cache.Insert("Products", dt, null, DateTime.Now.AddMinutes(5), System.Web.Caching.Cache.NoSlidingExpiration);

    }

 

    return dt;

}

State Bag Access Pattern'de durum(state) bilgisine erişim doğrudan nesne üzerinden değil, nesnenin referansını taşıyan bir başka nesne tarafından sağlanır. Yani erişimi sadece bir kez yapılarak nesne referansı farklı bir nesne ile ilişkilendirilir. Bu noktadan sonra Cache bellekten kaldırılsa dahi yeni nesne hala eski Cache'in bellekteki referansını işaretliyor olacaktır ve uygulama içerisinde istenilen veriye ulaşılabilecektir. Geliştirdiğiniz web uygulamalarında Cache nesnesine erişimi bu tasarım kalıbını kullanarak sağlamanızı tavsiye ederim(Best practices).

Cache Nesnesinin Gereksiz Yere Tekrar Üretilmesini Engellemek: Thread Safety Singleton Pattern

Şu ana kadar Cache nesnesine erişimi Singleton Pattern(klasik yöntem) ve State Bag Access Pattern ile nasıl yapıldığını gördük. Cache nesnesine erişimle ilgili bir diğer önemli durumda Cache nesnesine aynı anda birden fazla thread tarafından erişimin olma ihtimalidir. Sonuçta Cache'de genellikle üretilmesi zaman alan nesneleri saklarız. Örneğin veritabanından 10 saniyede sürede çektiğimiz bir veriyi Cache'e atıyoruz. Saat 12:00:00, 12:00:04 ve 12:00:08 gibi üç ayrı talebin geldiği bir durumda veritabanına 3 kez gidilir. Ancak bizim burada istediğimiz sadece ilk talepte veritabanına gidilmesi olacaktır. Bu durumu şekilde şöyle izah edebiliriz:


Şekil: Cache nesnesine gelen taleplerin sırası ve normal işleyişi

Görüldüğü gibi veritabanında 10 saniye sürecek bir işlem esnasında Cache nesnesine 10 saniyelik sürede gelen tüm talepler veritabanına gönderilecektir. Zira ilk talep sonrasında Cache nesnesi ancak 10 saniye sonra doldurulacaktır. Yani sonrasında gelen iki talepte Cache hala null görüneceği için bu işlemler yapılır. Halbuki caching'deki temel mantık veritabanında yoğunluğa yol açan sorguların azaltılması ve sadece belirli aralıklarla veritabanına gidilmesiydi. Burada performans açısından bizi veritabanına daha az götürecek bir yapı sağlıklı olacaktır. Singleton pattern'in Thread Safety yöntemi olarak bilinen nesne kilitlemesi işlemi burada belirttiğimiz sorunun giderilmesi için çözümümüz olacaktır. Thread Safety Singleton Pattern'de aynı anda birden fazla thread'in erişmesinin istenilmediği nesne bir lock bloğu ile kilitlenir. Bu kilitleme esnasında nesneye gelen diğer talepler bekletilecektir. Kitleme bittiğinde ise diğer threadler lock bloğuna giriş yapar ve gerekli işlemleri yaparlar. Dolayısıyla yukarıda şekilde anlattığımız senaryodaki 2. ve 3. talepler veritabanına gitmek yerine 1. talebin bitmesini bekleyecektir. Bu bekleme sonunda uygun if koşulunu yazarak veritabanına atılacak gereksiz sorguları engeleyebiliriz. Aşağıdaki kodlarda bu tasarım deseninin uygulanışı yer almaktadır.

CacheHelper.cs

public static class CacheHelper

{

    static Cache cache;

    static object obj;

 

    static CacheHelper()

    {

        cache = HttpContext.Current.Cache;

        obj = new object();

    }

 

    public static DataTable GetProductsThreadSafe()

    {

        //Bu desende ise Cache nesnesine eş zamanlı gelecek birden fazla talepten sadece ilk gelen talep

        //Cache nesnesini olusturacaktir

        if (cache["Products"] == null)

        {

            lock (obj) //Burada obj nesnesi kilitlenerek farklı thread'lerin blok içerisine erişimi engellenmektedir

            {

                if (cache["Products"] == null)

                {

                    SqlConnection con = new SqlConnection("data source=localhost; database=Northwind; integrated security=true");

                    SqlDataAdapter da = new SqlDataAdapter(" Select * From Products", con);

                    DataTable dt = new DataTable();

                    da.Fill(dt);

                    cache.Insert("Products", dt, null, DateTime.Now.AddMinutes(5), System.Web.Caching.Cache.NoSlidingExpiration);

                }

            }

        }

 

        return (DataTable)cache["Products"];

    }

}

lock bloğunda kullanılan obj isimli nesne class içerisine bir field olarak tanımlanmıştır. Burada Cache'in null gelmesi durumunda lock bloğuna girilecek ve obj nesnesi farklı talepler tarafından kullanılamayacaktır. Ne zaman ki lock bloğu dışına çıkılacak, bu andan sonra gelen talepler bu bloğa girebilecektir. Burada dikkat çeken noktalardan birisi Cache nesnesinin null olup olmama durumunun iki kez kontrol edilmesidir. Birinci if koşulu Cache'in null olmadığı durumlarda gereksiz nesne kilitlemesini engellemek, ikinci if ifadesi ise birinci talepten sonra gelen ve lock bloğunda bekleyen taleplerin Cache'i gereksiz yere tekrar oluşturulmasını engellemek için gereklidir. lock bloğuna giren ikinci, üçüncü ve sonraki talepler içerideki koşulda Cache'in null olmadığını görecek ve if blokları dışına çıkılarak Cache nesnesi okunacaktır. Aşağıdaki şekilde Thread Safe Singleton Pattern uygulanışında gelen taleplerin işleyişi görülmektedir.


Şekil: Thread Safe Singleton Pattern'in uygulanmasında ardarda gelen 3 talebin işleyişi

Bu yazımda Cache nesnesine erişim sağlarken kullanılan klasik yöntemi ve bu klasik yöntemin yol açabileceği sorunların nasıl giderilebileceğini inceledik. Cache nesnesine erişimde klasik Singleton Pattern'in uygulanmasından ziyade yukarıda incelediğimiz State Bag Access Pattern veya Thread Safe Singleton Pattern'in uygulanmasının daha faydalı olduğunu gördük. Şunu unutmamak gerekir ki bellek(RAM) uygulamalarda en hızlı ve en kolay erişebileceğimiz sistem kaynağımızdır. Eğer sunucuda yeterli miktarda bellek varsa(ki günümüzde uygulama sunucularının bellekleri çok büyük miktarlarda olabilmekte) işleyişi yavaşlatacak birçok işlemin çıktısının Cache'de saklayabiliriz. Tabi ki Cache'e erişimde de en kullanışlı ve sağlıklı yöntemi belirlemekte fayda olacaktır.

25 Kasım 2009 Çarşamba 21:48

Yorum - RSSYorumlar (2)

Kategori: ASP.NET

facebook'da Paylaş   twitter'da Paylaş   friendfeed'de Paylaş   del.icio.us'da Paylaş   stumpleupon'da Paylaş   Permalink

Authorization Ayarları ve CSS, JavaScript Gibi Dosyalara Özel Hak Tanıma

ASP.NET uygulamalarında Authorization mekanizmasını kullanarak kullanıcı tabanlı ve rol tabanlı güvenlik işlemlerini kolay şekilde gerçekleştirebiliyoruz. Uygulamanın tamamı veya belirli bir dizini web.config dosyası içerisindeki <authorization> elementinde belirlenecek kurallara göre güvenli şekilde erişilebilir hale getirilebilir. Tabi ki bu kadar kolay işin içerisinde bazen ufak tefek sorunlarla da karşılaşabiliyoruz. Bu yazımda geçmişte karşılaştığım ve çözümünün sizler için faydalı olabileceğini düşündüğüm bir ipucundan bahsetmek istiyorum.

Geliştirdiğiniz uygulamadaki tüm sayfalara(veya belirli bir dizindeki tüm sayfalara da olabilir) sadece sisteme giriş yapmış kullanıcılar erişsin istiyorsunuz. Dolayısıyla kullanıcılara login sayfanız dışındaki tüm sayfaları kapatmanız gerekiyor. Burada sorun yok; zira ASP.NET authentication ve authorization için gerekli ayarları yapmanız durumunda Login.aspx dışındaki tüm dosyaları kullanıma kapatacaktır. Dikkat! Tüm sayfalar değil, tüm dosyalar erişime kapatılacaktır dedim. Yani, eğer login sayfasında CSS, skin gibi stillendirme dosyaları, JavaScript, resim vb. dosyaları kullanırsanız, bu dosyalar da authorization ayarlarına takılacak ve kullanıcıya gönderilmeyecektir. Bu nedenle login sayfanıza erişen kullanıcı bu sayfayı sizin tasarladığınız gibi göremeyecektir. Eğer login sayfasının düzgün şekilde görüntülenmesini istiyorsanız, bu sayfa içerisinde kullandığınız diğer dosyalar için farklı authorization ayarları yapmanız gerekecek.

Önce sorunumuzu somutlaştıralım. Basit bir Login.aspx sayfası tasarlıyorum ve web.config dosyasında authorization ayarlarını tüm sayfalara sadece sisteme giriş yapmış kullanıcıların erişebileceği şekilde değiştiriyorum. style.css adında bir de stil dosyamız var. Login.aspx ve style.css dosyalarının içeriği bizim için önemli değil. Önemli olan web.config;

web.config

<authentication mode="Forms"/>

<authorization>

    <deny users="?"/>

</authorization>

...


Bu değişikliklerden sonra sisteme giriş yapmamış olan kullanıcılar Login.aspx dışındaki hiçbir dosyaya erişemeyecektir. Eğer Login.aspx içerisinde style.css gibi bir dosyaya bağlantı kurulmuş ise bu dosya da erişilemez olacaktır. Dolayısıyla Login.aspx çalıştırıldığında istemciye style.css dosyası gönderilmeyeceği için sayfa görsel olarak istenildiği gibi görüntülenmez. Aşağıda zemin rengi mavi, font tipi de Arial olarak belirlenmiş olan sayfamızın bu ayarlardan sonraki görünümü bulunmakta.

Görüldüğü gibi ne zemin rengi mavi, ne de fontlar Arial :) Peki çözüm nedir? Bu tip durumlarda Login sayfanızın içerdiği tüm CSS, JavaScript ve resim dosyalarının düzgün şekilde istemciye gönderilmesini istiyorsanız web.config içerisinde bu dosyalar için özel hak tanımlaması yapmanız gerekiyor. web.config dosyasının en üst seviyesinde açacağınız <location> elementi ile dosyaları tanımlamalı ve bu dosyalara tüm kullanıcıların erişmesini sağlamalısınız. <location> elementi <configuration> elementinin içerisinde olmalı ve <configSections> tanımlamalarının altında yer almalıdır.

web.config
<configuration>

    <configSections>

        ...

    <location path="styles/style.css">

        <system.web>

            <authorization>

                <allow users="*"/>

            </authorization>

        </system.web>

    </location>

style.css dosyası sisteme giriş yapmamış kullanıcılar tarafından da görülebilir hale geldi. Buradaki allow veya deny elementleri içerisinde kullanılan * karakteri tüm kullanıcılar, ? karekteri ise sisteme giriş yapmamış(anonim) kullanıcılar anlamına gelmektedir. Şimdi Login.aspx sayfasına tekrar bakıyoruz.

style.css dosyası istemciye gönderildiği için artık stiller sayfaya uygulanabilecektir. Umarım faydalı bir ipucu olmuştur.

22 Ekim 2009 Perşembe 00:55

Yorum - RSSYorumlar (0)

Kategori: ASP.NET

facebook'da Paylaş   twitter'da Paylaş   friendfeed'de Paylaş   del.icio.us'da Paylaş   stumpleupon'da Paylaş   Permalink

AutoCompleteExtender ile Google Suggest Görünümünde Otomatik Tamamlayıcı Hazırlamak

AJAX'ın artık çoğu web uygulamasında kullanılır hale gelmesi web sitelerindeki standartları da arttırdı. Artık çoğu sitenin kendi arama motorunda ziyaretçilere yardımcı olması için otomatik tamamlayıcı metinleri kullandığını görebiliyoruz. Yani siz gidip arama kutusuna birkaç harf yazdığınızda arka planda sunucuya iletilen bir taleple size yardımcı olabilecek arama kriterleri bulunuyor ve size dinamik açılan bir kutuda seçenek olarak sunuluyor. Bu yazımda ASP.NET uygulamalarında kullanabileceğimiz Control Toolkit kütüphanesinde yer alan otomatik metin tamamlayıcı kontrolümüz olan AutoCompleteExtender kontrolünü nasıl özelleştirebileceğimizi inceleyeceğiz. Bu incelemenin sonunda da AutoCompleteExtender kontrolünü aslında Google Suggest görünümünde çalıştırabileceğiz.

AutoCompleteExtender kontrolü adından da anlaşılacağı üzere bir extender; yani ancak başka bir kontrole bağlanarak çalıştırılabilir. TextBox ile birlikte kullanılan bu kontrol kullanıcının TextBox içerisinde belirli sayıda karakter yazması ile tetiklenmeye başlar ve bu noktadan sonra her harf değişiminde tetiklenmeye devam eder. Böylece kullanıcının yazdığı her ifadeyi yakalayabilir ve bu ifadeler ile sunucuya AJAX talepleri yollayabilir ve gelen sonuçları da otomatik olarak açılan bir pencereden kullanıcıya sunabilirsiniz. Aslında AJAX'ın web sayfalarına uygulanışının en güzel örneklerinden birisi. Bu kontrol sunucuda yapacağı talepleri bir web servisi üzerinden gerçekleştirir. Çağrılacak olan web servisine kullanıcının yazdığı ifade yollanır ve sunucuda veritabanı vb. bir kaynaktan istenilen kayıtlar çekilerek TextBox'ın hemen alt kısmında seçilebilir öğeler olarak listelenir. AutoComplete kontrolü hakkında fazlasıyla hikaye anlattım sanırım. Gelin şimdi bu işi nasıl yaparız, bir inceleyelim.

Web servisi ile işe başlayalım. Amaç basit olarak işe yarar metinler döndürmek olduğu için sade bir metot hazırladım. AutoCompleteExtender TextBox'a girilen değeri web metoduna prefixText parametresi olarak göndererektir.

MusicService.asmx

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

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[System.Web.Script.Services.ScriptService]

public class MusicService : System.Web.Services.WebService

{

    [WebMethod]

    public string[] GetSong(string prefixText, int count)

    {

        string[] songList1 = new string[] { "sevme|3", "seviyorum|7", "sevdim sevilmedim|5" };

        string[] songList2 = new string[] { "zaman|7", "zaten|2" };

 

        if (prefixText == "se")

            return songList1;

        else if (prefixText == "za")

            return songList2;

        else

            return null;

    }

}

Bu örnek için basit bir web servisi hazırlıyorum. Gerçek senaryolarda bu metot içerisinden veritabanındaki ilgili tablonuza uygun LIKE koşullarıyla SELECT cümleleri göndermeniz ve elde ettiğiniz sonuç kümesini yine string dizisine eklemeniz yeterli olacaktır. Oluşturduğumuz string dizisi içerisinde yer alan değerlere bakacak olursanız ilk bakışta enteresan gelecek bir format dikkatinizi çekecektir. Örneğin; zaman|7 Buradaki | işareti aslında bizim için ayıraç görevi üstlenecek. Aslında makalenin başlığına bakacak olursanız amacımız AutoCompleteExtender'ı özelleştirerek Google Suggest tarzında görüntülemek. Dolayısıyla bir metin ve o metinden kaç tane sonuç geleceğini getirmemiz gerekiyor. | simgesinin solunda tamamlayıcı metnimiz, sağında ise o metinden toplam kaç tane sonuç bulduğumuz yer alıyor(zaman kelimesinden toplam 7 tane sonuç var gibi)

Gelelim AutoCompleteExtender kontrolünü hazırlamaya. Bir ASP.NET sayfasına ToolkitScriptManager ve TextBox kontrolü ekliyoruz. TextBox'ın sağ üst köşesindeki smart-tag ikonundan Add Extender diyerek AutoCompleteExtender'ın textbox'a bağlanmasını sağlayabiliriz. Aslında sadece bağlama işlemi yeterli olmayacak bu örnek için, ek olarak birkaç tanımlama daha yapmamız gerekecek. Aşağıdaki kodlar basit şekilde web servisini çağırabilmenizi sağlayacaktır. Bunların dışında bu örnek için gerekli JavaScript tanımlamaları da aşağıda yer alıyor.

Default.aspx

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

    <cc1:ToolkitScriptManager ID="scriptManager1" runat="server">

    </cc1:ToolkitScriptManager>

 

    <asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>

    <cc1:AutoCompleteExtender ID="txtSearch_AutoCompleteExtender" runat="server"

       DelimiterCharacters="" MinimumPrefixLength="2" Enabled="True" TargetControlID="txtSearch"

       BehaviorID="AutoCompleteEx" ServicePath="MusicService.asmx" ServiceMethod="GetSong"

       OnClientPopulated="onClientPopulated" OnClientItemSelected="onItemSelected">

    </cc1:AutoCompleteExtender>

</form>

AutoCompleteExtender kontrolünün tanımlamasının son iki satırında yer alan nitelikler anlattığımız örnek için olmazsa olmaz değerleri saklamakta. Bu niteliklerin görevlerine ve nerelerle bağlantılı olduklarına kısaca değinelim:

- ServicePath: Bağlanacağımız web servisinin adresi
- ServiceMethod: Web servisi içerisinde yer alan ve string dizisi olarak bize sonuç listesini döndürecek web metodu.
- BehaviorID: JavaScript fonksiyonları içerisindeyken AutoCompleteExtender kontrolünün içeriğindeki listeye erişmemizi sağlayan özellik
- OnClientPopulated: İstemci tarafında web servisinden gelen veriler yüklendiği esnada tetiklenen olay fonksiyonu. Az sonra hazırlayacağımız onClientPopulated isimli JavaScript fonksiyonunda servisten gelen değerlerin istenilen formatta listede yer almasını sağlayacağız.
- OnClientItemSelected: Tamamlama listesinden bir seçenek seçildiği esnada istemci tarafında tetiklenecek olay fonksiyonu. Bu JavaScript fonksiyonda ise seçilen seçeneğin düzgün şekilde textbox'a aktarılmasını sağlayacağız.

Web servisinden gelen veriler "zaman|7" gibi bir formatta olduğu için eğer istemci tarafında bu verilerin üzerinde oynama yapılmazsa aynen textbox içerisinde görüntülenir. Bu verilerin değiştirilebilmesi için istemci tarafında servis verilerini değiştirme işini yapacak bir JavaScript fonksiyonuna ihtiyacımız olacak(onClientPopulated). AutoComplete kontrolü seçim yapıldığında kendi koleksiyonunda hala servisten gelen orjinal veriyi saklamaktadır. Bu nedenle kullanıcı bir değeri seçtiğinde textbox'a zaman|7 yerine zaman yazabilmemiz için bir de listeden seçim işlemini istemci tarafında yakalamamız ve seçilen değeri düzgün şekilde textbox'a aktarmamız gerekecektir. Bu işlemi de onItemSelected isimli JavaScript fonksiyonunda yapacağız. AutoCompleteExtender'ı Google arama motorunun kullandığı formata benzetebilmek için iki tane CSS class'ı tanımlıyoruz(bu da autocomplete kutusunun daha şık görüntülenmesi için). Css class'ları ve JavaScript fonksiyonlarını aşağıda bulabilirsiniz. JavaScript fonksiyonları ile ilgili detaylı açıklamaları yorum satırlarında bulabilirsiniz.

Default.aspx

<head runat="server">

    <title>AutoComplete Örneği</title>

    <style type="text/css">

        .metin{ float:left; font-family:Arial; font-size:11px }

        .bulunan_kayit{ float:right; color:Green; font-family:Arial; font-size:11px }

    </style>

 

    <script type="text/javascript">

        //Listenin client tarafında yüklenmesi esnasında tetiklenen fonksiyon.

        //Listeye eklenecek olan "zaman|7" şeklindeki metnin "zaman   7 sonuç" şeklinde listelenmesini sağlar.

        function onClientPopulated(sender, e) {

            var completionList = $find("AutoCompleteEx").get_completionList(); //Orhinal liste alınır

 

            //Orjinal listedeki her item istenilen formata getirilir

            for (i = 0; i < completionList.childNodes.length; i++) {

                var okunanDeger = completionList.childNodes[i]._value.split('|');

                var metin = okunanDeger[0];

                var kayitSayisi = okunanDeger[1];

                completionList.childNodes[i].innerHTML = '<span class="metin">' + metin + '</span><span class="bulunan_kayit">' + kayitSayisi + ' sonuç</span>';

            }

        }

 

        //Menüden seçim yapıldığında tetiklenen fonksiyon.

        //Seçilen index değerine göre AutoCompleteList'te yer alan değer bulunur.

        //Bu index'te yer alan değer alınarak | simgesinin solundaki bilgi(metin) textbox'a aktarılır.

        function onItemSelected(e) {

            var index = $find("AutoCompleteEx")._selectIndex;

            var deger = $find("AutoCompleteEx").get_completionList().childNodes[index]._value;

            var okunanDeger = deger.split('|');

            var metin = okunanDeger[0];

 

            document.forms[0]['txtSearch'].value = metin;

        }

    </script>

</head>

AutoCompleteExtender kontrolünde sadece görünüm olarak değişiklik yapmak isterseniz CSS class tanımlamaları yapmak ve bu tanımlamaları CompletionListCssClass, CompletionListHighlightedItemCssClass gibi özelliklere bağlamak yeterlidir. Ancak bu örneğimizde gerek web servisinden gelen verinin ayrıştırılarak farklı şekillerde görüntülenmesi, gerekse AutoCompleteList üzerinden seçilen seçeneğin düzgün şekilde textbox'a aktarılması gerektiği için sadece CSS class'ları işimizi görmez, JavaScript fonksiyonları ile AutoCompleteExtender içeriğinin doldurulması ve üzerinde seçenek seçme işlemlerini de ele almamız gerekir. Gerekli kodları hazırladıktan sonra artık AutoCompleteExtender kontrolünün çalışmasını test edebiliriz.

AutoCompleteExtender'ın Görünümü
Resim: AutoCompleteExtender kontrolümüz Google Suggest’i taklit ederken :)

Resimden de anlaşılacağı gibi Google Suggest'e oldukça benzer bir görünüm elde edebilmişiz.

25 Ağustos 2009 Salı 21:23

Yorum - RSSYorumlar (1)

Kategori: ASP.NET

facebook'da Paylaş   twitter'da Paylaş   friendfeed'de Paylaş   del.icio.us'da Paylaş   stumpleupon'da Paylaş   Permalink

ScriptManager.IsInAsyncPostBack Özelliği

Önceki yazılarımda AJAX kontrollerini kullanarak geliştirdiğiniz ASP.NET uygulamalarında yapacağınız asenkron postbacklerde sayfanın sunucu tarafında sıfırdan üretildiğinden bahsetmiştim. WebMethod'larla AJAX Sayfalarını Daha da Hızlandırın başlıklı yazımın ilk paragrafını konunun kısa detayı için okuyabilirsiniz. Aynı makalede WebMethod’ları kullanarak AJAX uygulamalarında daha hızlı işlemler gerçekleştirileceğinden bahsetmiştim. Ancak uygulama içerisinde WebMethod’lar değil de UpdatePanel’lerle asenkron işlemleri gerçekleştiriyorsanız yine uygulamanızı hızlandırmak için önemli bir ipucu var. O da ScriptManager kontrolünün IsInAsyncPostBack özelliği(property). Adından da anlaşılacağı üzere yapılan talebin asenkron postback olup olmadığı bilgisini getiriyor. Özelliğin kullanımına örnek olması açısından şöyle bir kod parçası üzerinden gidelim:

protected void Page_Load(object sender, EventArgs e)

{

    //Veritabanından son eklenen 40 haberi getir

    //Haberlere yapılan son 10 yorumu getir

}

 

protected void Button1_Click(object sender, EventArgs e)

{

    //Döviz bilgilerini getir. Bu kısım partial postbackte çalışacak

}


Bu şekilde hazırlanan bir sayfada Page_Load’da eriştiğiniz kontroller UpdatePanel’in içerisinde değilse ve UpdatePanel’in içeriğini Button1’e tıklamak güncelleyecekse yukarıda görmüş olduğunuz Page_Load metodundaki kodlar Button1’e her tıklandığında gereksiz yere çalışacaktır. Dikkat edeceğiniz üzere sadece Button1’e tıklanması yeterli değil, Page_Load’da yapılan işlemlerin de UpdatePanel içeriğiyle ilgili olmaması gerekiyor. Page_Load metodunu aşağıdaki şekilde düzenlediğinizde artık Button1 üzerinden gerçekleşen partial postback işlemlerinde sunucu tarafında daha az kod çalışacak ve sayfanın daha hızlı şekilde güncellenecektir.

protected void Page_Load(object sender, EventArgs e)

{

    if (!scriptManager1.IsInAsyncPostBack)

    {

        //ScriptManager üzerinden asenkron işlem yapılmıyorsa;

 

        //Veritabanından son eklenen 40 haberi getir

        //Haberlere yapılan son 10 yorumu getir

    }

}


11 Ağustos 2009 Salı 23:09

Yorum - RSSYorumlar (5)

Kategori: ASP.NET

facebook'da Paylaş   twitter'da Paylaş   friendfeed'de Paylaş   del.icio.us'da Paylaş   stumpleupon'da Paylaş   Permalink

GridView – Silme ve Güncelleme İşlemlerindeki Hataları Yönetmek

Bildiğimiz gibi GridView kontrolünü DataSource kontrolleri aracılığıyla veriye bağladığınızda eğer istenirse Update ve Delete sorguları da oluşturulabiliyor. Bu sorgulardan yola çıkarak tek satır dahi kod yazmadan listelenen kayıtlar üzerinde güncelleme ve silme işlemleri yapabiliyoruz. Herşeyin otomatik olduğu böyle bir ortamda bazen hesapta olmayan(aslında veritabanı tasarımında hesaplanan, yani aslında hesapta olması gereken) sorunlarla da karşılaşabiliyoruz. Ne gibi sorunlar derseniz; örneğin listelediğimiz kayıtlardan bir tanesini silmek istediğimizde eğer farklı bir tabloda bu kayıda bağlı başka satırlar varsa(constraint ile silinmesi kısıtlanmışsa) silme işlemi hataya yol açacaktır. Yine güncelleyeceğiniz satırın bir alanına hatalı bir veri girişi yaparsak(null değer almayan bir alanı boş bırakmak gibi) başka bir hata ile karşılaşırız. Bu tip durumlarda iki farklı çıktı ile karşılaşabiliriz, eğer özel hata sayfalarını aktifleştirmemiş ve debug modda çalışmayı kapatmadıysak doğrudan üretilen SqlException tipindeki hata mesajını, ya da özel hata sayfalarını aktifleştirdiysek hata sayfamıza yönlendiriliriz. İlk durumdaki hata çıktısı eminim ki sizlere pek yabancı gelmeyecektir(buyrun resime bakalım)

Bu sayfadan özel hata sayfalarını aktifleştirirsek kurtulabiliriz. Ancak bu hata sayfaları projemizin genelinde görüntüleneceği için GridView’da oluşan hatalar için kendimiz farklı bir hata sayfası tasarlamak isteyebiliriz. Böylece burada alınan SqlExcpetion tipindeki hatayı kullanıcıya görüntüleyerek ne tarz bir hata yapıldığı konusunda daha doyurucu bir bilgi sunabiliriz. GridView üzerinde bir işlem yapılırken çalışma zamanında oluşan bir hatayı yakalamak istiyorsak sayfamızın Error eventi için yazılabilecek Page_Error metodunu kullanabilir veya yine sayfada yer alan OnError isimli virtual metodu ezebiliriz(override edebiliriz). Aklımıza, GridView’ın kendine özel bir hata eventi yok mudur sorusu gelebilir, cevabını hemen vereyim maalesef yoktur:) O zaman parmaklarımızı hazırlıyoruz ve klavyemizden aşağıdaki sihirli kodları yazıp neler olacağına göz atıyoruz.

Default.aspx (RowDeleting ve RowUpdating eventlerini metotlarına bağlıyoruz)

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"

    DataKeyNames="ProductID" DataSourceID="SqlDataSource1"

    onrowdeleting="GridView1_RowDeleting" onrowupdating="GridView1_RowUpdating">


Default.aspx.cs

private string command; //Islem tipini saklamak icin

 

//Sayfada hata olustugunda OnError metodu tetiklenir

protected override void OnError(EventArgs e)

{

    base.OnError(e);

 

    //Olusan son hatanin mesaj bilgisini aliyoruz

    string errorMessage = Server.GetLastError().Message;

    if (command == "Delete")

        Session["gridHata"] = "Silme işleminde hata! Hata mesajı: " + errorMessage;

    else if (command == "Update")

        Session["gridHata"] = "Güncelleme işleminde hata! Hata mesajı: " + errorMessage;

    Server.Transfer("Hata.aspx");

}

protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)

{

    //Islemin tipini Delete olarak belirleyip Session'a null degerini atiyoruz

    //Silme islemi basarili olursa Session'daki deger silinecek

    command = "Delete";

    Session["gridHata"] = null;

}

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)

{

    //Islemin tipini Update olarak belirleyip Session'a null degerini atiyoruz

    //Guncelleme islemi basarili olursa Session'daki deger silinecek

    command = "Update";

    Session["gridHata"] = null;

}

 

Neler yaptığımızı özetleyecek olursak; GridView1_RowDeleting ve GridView1_RowUpdating metotlarında yapılan işlemin tipini saklayıp Session nesnesinin içeriğini boşalttık. Ezdiğimiz OnError metodunda ise oluşan hatanın mesajını alıp Session’a kaydettik, ardından da talebi Hata.aspx adındaki bu iş için oluşturacağımız hata sayfasına yönlendirdik(Server.Transfer ile yönlendirmemizin sebebi URL satırında hala Default.aspx’in saklı kalmasını sağlamak. Çok kritik bir durum değil, Response.Redirect ile de yönlendirme yapılabilir) Hata.aspx sayfamızın da Page_Load metodunda Session bilgisine bakarak ekrana hatayı yazdırdığımızda artık senaryomuz çalışır hale gelecektir.

Hata.aspx

protected void Page_Load(object sender, EventArgs e)

{

    if (Session["gridHata"] != null)

        Response.Write(Session["gridHata"].ToString());

 

    Session["gridHata"] = null;

}

10 Temmuz 2009 Cuma 23:36

Yorum - RSSYorumlar (1)

Kategori: ASP.NET

facebook'da Paylaş   twitter'da Paylaş   friendfeed'de Paylaş   del.icio.us'da Paylaş   stumpleupon'da Paylaş   Permalink

Bağlantılar



Takip Et

RSS Feed twitter friendfeed

Seminer/Webiner Programım

  • Seminer-WebinerADO.NET Entity Framework (Yıldız Teknik Üniversitesi)
    6 Mart 2010

  • Seminer-WebinerASP.NET 4.0 ile Gelen Yeni Özellikleri Yakından Tanıyın (Microsoft)
    18 Şubat 2010

  • Seminer-WebinerC# 4.0 ve Visual Basic 10 ile Uygulama Geliştirmenin Püf Noktaları (Microsoft)
    28 Ocak 2010

>> Etkinlik Takvimi