21 Haziran 2012 Perşembe

Viewstate nedir , Nasıl kullanılır ?



Viewstate temel olarak en basit haliyle bir web sayfasındaki verileri saklamak için kullanılan ve client tarafında tutulan bir değişkendir.

Web programlamaya yeni başlayan kullanıcılar için başlangıç da alışılması en zor olan durum değişken değerlerinin sayfa her post olduğunda kaybolmasıdır. Bu durum başlangıç da gerçekten alışılması zor bir durumdur hele uzun zamandır "Masaüstü Programlamayla" uğraşan bir yazılımcı için bu süreç oldukça sıkıntılı ve uzun sürebilmektedir.



Neden sıkıntılı ?
Masaüstü programlama yaparken ekrana bir textbox attınız ve Form'unuzun Load event'ında bu textbox a bir değer atadınız , bu değer siz elle bu textbox'ın değerini değiştirmediğiniz veya kod tarafında bu değeri değiştirmediğiniz sürece textbox üzerinde kalmaya devam edecektir.Form üzerinde istediğiniz butona basın istediğiniz Kontrol event'ını tetikleyin yinede bu textbox'ın değeri değişmeyecektir. Fakat websayfalarında durum Masaüstü Programlamada olduğu kadar kolay değildir.Çünkü bir websayfasında tetiklenen her event karşılığında sayfanız postback olur ve tetiklenen event'ın durumuna göre sayfanız sunucuya gider ve sunucuda gelen duruma göre gelen mesaj yorumlanır ve browser'a işlenmiş veri geri yollanır fakat bu durumda web sayfanızın önceki durumu kaybolur.Örneğin sayfanız postback olmadan önce sayfadaki X Textbox’ında "Merhaba" değeri varken sayfa yenilendikten sonra bu textbox'ın değeri temizlenir bunun yerine bu alanlara sunucudan gelen işlenmiş verideki değerler yüklenir.

Fakat bir çoğumuz Web Programlamayla uğraşıyoruz ve sayfa post olduğunda sayfadaki kontroller eğer sunucuda kontrol değeri değiştirilmediyse önceki değerlerini korumakta bu nasıl olmakta derseniz.

Asp.Net bunu default olarak "Viewstate" dediğimiz State Management yöntemiyle sağlamakta.Sayfa postback olduğunda kontrol değerlerinin saklanmasını ve sayfa sunucuda yorumlandıktan sonra kontrol değerlerinin yüklenmesi işlemi Viewstate aracılığı ile yapılır.

Nasıl yani ?
Sizin sayfanızdaki kontrollerinizin değeri Asp.Net tarafından oluşturulan gizli bir input değişkeninde saklanır.Sayfanız postback olduğu anda Asp.Net sizin sayfanızdaki kontrollerin değerini "__VIEWSTATE" isimli gizli inputa atar ve bu değişkenide sunucuya yorumlanmak üzere gönderilen verinin arasına ekler siz sunucuda bazı kontollerin değerini değiştirirseniz eğer bu değişkenlerin değerini günceller ve sunucu işlenmiş datayı tekrar Client'a göndereceği zaman bu değişkenide gönderir ve sayfanızdaki kontroller tekrar bu "__VIEWSTATE" değişkeni aracılığıyla yeni ve eski değerleri ile doldurulur.

NOT : "__VIEWSTATE" değişkenini de sayfa her post olduğunda client'tan - sunucuya , sunucudan - clien'ta gönderilir.

Client’ta oluşturulan gizli input değişkeni

 <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMzkwNTA5NDc2D2QWAgIDD2QWAgIBDx
BkDxYCZgIBFgIQBQVNdXJhdAUFTXVyYXRnEAUFxLBtcmUFBcSwbXJlZ2RkZOki+HzHOKCL/CxJcDm9SWy2mS6Z" />

Hemen aklınıza şu sorunun geldiğinden eminim.Peki bu "__VIEWSTATE" değişkeni sayfa her post olduğunda sunucuya gidip geliyorsa performans kayıplarına , sayfanın daha geç yüklenmesine sebep olmazmı ? 

Evet arkadaşlar bu konuda son derece haklısınız Viewstate'ler gereksiz kullanıldığı zaman gerçekten ciddi performans kayıplarına sebep olmakta. Bunun için kullanımına dikkat etmek gerekmekte Sayfanızdaki kontrol sayısı çok fazla ve bu kontrollerin sakladığı datalar çok fazla olursa sayfadaki "__VIEWSTATE" değişkeninin değeri şişmekte ve ciddi performans sıkıntıları doğurmaktadır.Hatta bazen bu Viewstate'lerin aşırı şişmesinden dolayı web sayfanız firewall ve proxy'lere takılabilr. Peki bunlarla nasıl baş etmeliyiz bunu makalemizin ilerleyen bölümlerinde anlatacağım.

Şimdi basit bir Web sayfası oluşturup içerisine bir textbox atalım ve Text özelliğine istediğiniz bir değeri atayın ve sayfanızı "F5" tuşu ile çalıştırın ve açılan sayfaya sağ tıklayıp kaynak kodu görüntüle diyin."__VIEWSTATE" isimli değişkenimizin Asp.Net tarafından oluşturulduğunu görüyoruz.












Sayfaya sağ tıklayıp kaynak kodu görüntüle deyince alınan ekran görüntüsü





















Peki bizim sayfamızdaki bütün kontrollerin değerleri Asp.Net tarafından saklanmak zorundamı bu benim sayfamın daha geç yüklenmesine sebep olmak'ta ben en azından bunu sayfamdaki bazı kontroller için kapatamaz mıyım.Bunu elbette ki yapabilmekteyiz bunun için değişkeninizin EnableViewState özelliğini "false" değerine çekmeniz yeterli olacaktır.Artık bu kontrolünüzün değeri Asp.Net tarafından saklanmayacaktır.Fakat bu dikkatli kullanılması gereken bir özelliktir dikkat edilmediği takdirde “ben kontrolün arkaplan resmini değiştiriyorum Yazısı kayboluyo , Fontunu ayarlıyorum arkaplan rengi kayboluyo” tarzında garip durumlarla karşılaşabilirsiniz.

Sadece bir kontrolde bu özelliği devre dışı bırakmak isterseniz.
<asp:TextBox ID="TextBox1" runat="server" EnableViewState="false"></asp:TextBox>

Komple sayfada devredışı bırakmak isterseniz
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableViewState="false" %>

Bütün projede bu özelliği kapatmak isterseniz web.config dosyasına aşağıdaki satırı eklemeniz yeterli olacaktır.
<pages enableViewState="false"></pages>



Bunu biraz örneklemek gerekirse.Aşağıda gösterildiği şekilde bir web sayfası tasarlıyalım ve Textbox’ımızın Text özelliğine default olarak “Viewstate Makale” yazalım ve Textbox’ımızın EnableViewState özelliğini “False” değerine çekelim ve kod tarafında butonlarımızın click eventlarına aşağıda gösterilen kodları bağlayalım.












    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnBackgroundYellow_Click(object sender, EventArgs e)
        {
            TextBox1.BackColor = System.Drawing.Color.Yellow;
        }

        protected void btnForeColorRed_Click(object sender, EventArgs e)
        {
            TextBox1.ForeColor = System.Drawing.Color.Red;
        }
    }

Şimdi sayfayı çalıştırıp önce “Arkaplanı Sarı Yap” butonuna sonrada “Yazı Rengini Kırmızı Yap” butonuna basalım ve olanları kendi gözlerimizle görelim.İlk butona basılınca Textbox’ın arkaplanı sarı olmakta fakat 2. Buttona basınca Arkaplan tekrar eski haline gelmekte yazı rengi kırmızıya dönmektedir.Aynı durumu sadece Textbox’ın EnableViewState özelliğinin değerini “True” yaparak tekrar deneyelim ilk butona bastığımızda önce Textbox’ın arkaplanı sarı olmakta 2. Butona basıncada arkaplan rengi sarı , yazı rengi kırmızı olan bir textbox karşımıza çıkmakta.

Peki Viewstate sadece Asp.Net’in kullanabileceği bir özellikmi biz developer’lar kod tarafında bu “Viewstate” nimetinin özelliklerinden faydalanamazmıyız.Elbette ki faydalanabiliriz peki neden lokal değişkenler değilde Viewstate kullanmalıyız ? Bunun yine en büyük sebebi lokal değişkenlerinizin sayfa her postback olduğunda bir önceki değerlerini kaybetmelerinden kaynaklanmalıdır.Masaüstü uygulamalarında olduğu gibi kullanıcı Formu kapatana kadar değerini koruyan değişkenler kullanılmak istendiğinde Viewstate devreye girmekte(Bunun yerine kullanılabilecek farklı yapılar elbeteki var fakat şu an konumuz Viewstate’ler olduğu için bununla devam edeceğiz) çünkü Viewstate’ler kullanıcı sayfayı en baştan yüklemediği veya sayfayı kapatmadığı sürece değerlerini korurlar.Sayfanın postback olmasından etkilenmezler fakat yine bu “Viewstate” değişkeninin kullanıcının bilgisayarında tutulduğunu unutmamak lazım.Bu durum bizim için avantajda olabilir , dezavantajda.

Viewstate’in kod tarafında kullanılması

Database tarafında bir sorgu çalıştırdınız ve sorgunuz database tarafında son derece zahmetli bir işlem yapıp size matematiksel bir sonuç döndürdürdü ve sizde database’den gelen bu sonuca göre ekrandaki farklı işlemler yapmak istiyorsunuz.Bu değeri her kullanmak istediğinizde tekrar database gidip bu değeri tekrar tekrar hesaplamak yerine bu değeri sadece bir kez hesaplayıp gelen sonucu’da bir Viewstate değişkeninde saklarsanız bu değere her ulaşmak istediğinizde database gidip bu sorguyu çalıştırmak yerine bu Viewstate’in değerini kullanabilirsiniz.


    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                //Sayfa ilk açıldığında database'deki ilgili sorguyu çalıştır ve gelen sonucu Viewstate'de sakla

                int dbQueryValue = 0;
                {
                    //Databasede işlem yapılmasını sağlayan işlem bloğu burda yer alacak
                    //Bir Stored Procedure tetiklenebilir.

                    //Hesaplanan sonucu al

                    dbQueryValue = 25;
                }

                //Artık DB'ye gitmeye gerek yok gelen değer viewstate'de saklanıyor.
                ViewState["Key"] = dbQueryValue; 

                //Not yukarıda örnek olması açısından ViewState["Key"] değişkenine direk değer ataması yaptım fakat sayfalarınızda
                //kullandığınız Viewstate'ler için get { } - set { } blokları yazmak işini son derece kolaylaştıracaktır.

            }
        }

        //DB'den gelen değerin karesini al
        private double KareAl()
        {
            double rValue = 0;

            //DB'ye gidip bu değeri tekrar hesaplatmak yerine ViewStaten al
            rValue = Convert.ToDouble(ViewState["Key"]);

            rValue = rValue * rValue;

            return rValue;
        }

        //DB'den gelen değerin karekökünü al
        private double KareKokAl()
        {
            double rValue = 0;

            //DB'ye gidip bu değeri tekrar hesaplatmak yerine ViewStaten al
            rValue = Convert.ToInt32(ViewState["Key"]);

            rValue = Math.Sqrt(rValue);

            return rValue;
        }
    }


Yukarıdaki örnekte Viewstate değer atama işlemi ViewState["Key"] = dbQueryValue; şeklinde yapılmıştı alternatif olarak ViewState.Add("Key", dbQueryValue); şeklinde bir atama işlemi’de yapabilirdik.

Önemli NOT : Viewstate sayfa bazlı tutulan bir değerdir sayfalar arası veritransferi için kullanılamaz yani  ViewState["Key"] viewstate'nin değeri'ne A sayfasında bir değer atayıp B sayfasında bu değeri almaya çalışırsanız alacağız değer NULL olacaktır.Kullanımsal olarak Session'la ayrıldıkları temel noktalardan biride budur.Sayfalar arası Veri Transferi için Session ve farklı yöntemler kullanılmaktadır.

Evet arkadaşlar basit şekliyle Viewstate nedir, ne işe yarar, nasıl kullanılır bunları dilim döndüğü kadar anlatmaya çalıştım aslında detayına girilecek o kadar fazla konu varki onlarıda inş. başka bir makalemde sizlerle paylaşmak istiyorum.

Şimdide bir Viewstate ne zaman kullanılmalıdır Artıları Nedir ? Eksileri Nedir ? biraz bunlardan bahsedelim.

Viewstate’tin Artıları Nelerdir.
1-) Kullanımı son derece kolay ve kullanıcıdan soyutlanmış durumdadır.
2-) Sunucu tarafında tutulmadığı için sunucuyu kaynaklarını kullanmaz.
3-) İçerisinde sakladığı verileri normalde kodlayarak tutar fakat istendiği takdirde gerekli konfigürasyonlar yapılarak bu içerik şifrelenebilr.
4-) Viewstate içeriğinin istenilen durumlarda parçalanıp dağıtılabilmesi.

Viewstate’tin Eksileri Nelerdir.
1-) Viewstate Client’ta yani kullanıcının bilgisayarında tutulduğu için veriler dışarıya açıktır önlem alınmadığı takdirde bu verilere kolayca erişilebilir.
2-) Gerekli önlemler alınmaması durumunda şişebilecek bir Viewstate sunucunun tepki süresini artıracaktır ve dolayısıyla sayfanın daha geç yüklenmesine sebep olup ciddi performans kayıplarına sebp olabilir.

Viewstate kullanımında size önerebileceğim bir kaç noktayıda burda belirtmek istiyorum.


Öneriler
1-) Viewstate saklayacağınız verilerin boyutları küçük ise viewstate kullanılması mantıklıdır.
2-) Viewstate saklamayı düşündüğünüz datalar düşük öneme sahip olmalıdır
3-) Sayfada kullandığınız bir kontrolün özellikleri hiç değişmiyorsa bu kontrol için EnableViewState özelliği kapatılmaldır.
4-) Sayfanızda kullandığınız bir kontrolün değeri sayfa her post olduğunda yeniden hesaplanıyorsa Viewstate kullanmak mantıklı değildir.
5-) Viewstate içeriği şişecek gibi fakat viewstate kullanmanız gerekiyorsa viewstate içeriği parçalanmalıdır.
6-) Eğer Viewstate önemli veriler saklayacaksanız veya verinizin dışarıdan erişilmesiniz istemiyorsanız viewstate içeriğini  “AES” ,“3DES” ,”SHA1” veya “MD5” algoritmaları ile şifrelenmelidir.(Bu ayarları machine.config dosyasında yapmalısınız)
7-) Viewstate’leri direk kullanmak yerine get { } set { } bloklarını kullanmak işinizi son derece kolaylaştıracaktır.

6 yorum:

  1. Güzel bir makale eline sağlık...

    YanıtlaSil
  2. Ne demek ferdi bey umarım faydalı olmuştur.Blogumda fırsat buldukça güzel makaleler paylaşacağım düzenli olarak takip ederseniz sevinirim :)

    YanıtlaSil
  3. o kadar güzel anlatmış sınızki tebrik ederim

    YanıtlaSil
  4. Bu güzel yorumunuz için çok teşekkür ediyorum.Dilim döndüğü kadar anlatmaya çalıştım umarım faydalı olmuştur.Şu an iş yoğunluğumdan dolayı makale yazamıyorum fakat kısa süre sonra daha güzel makaleler paylaşmayı düşünüyorum.Takip ederseniz sevinirim.

    YanıtlaSil
  5. valla kardeşim o kadar yerde okudum anlamamıştım hep bir eksik kalıyordu gayet güzel olmuş tam olarak kafamda oturdu sadece anlamadığım şu bir sayfadaki kontroller üzerinde bilgiler saklamak niye gereksinim olsunkü ? örneğin büyük sitelere bakıyorum hepsibuarada.com vs burda hiç viewstate kullanmıyorlar

    son olarak bunu bulamadım bir siteyi 2 sunucuda barındırmak istediğimde sunucular arası viewstate taşıma gibi bir şey varmış bunla ilgili makale arıyorum teşekkürler

    YanıtlaSil
  6. o kadar güzel anlatmış Allah razı olsun

    YanıtlaSil