| 
      
        |  SİTE 
            İÇİ ARAMA |  
        |  |  
      
        |  Blogroll |  
        |  |    | 
        
            |  |  
            | 
                    
                        | ViewState’in Sunucuda Saklanması |  |  
                        | 
	
    
		
            | Gönderiliyor lütfen bekleyin... | 
 |  |  
            | ASPNET uygulamaları, doğaları gereği, Win32 ortamı içinde 
  çalışan Windows Forms uygulamalarından oldukça farklı yönlere sahiptirler: Bir 
  ASPNET uygulamasının görüntü ve durumunu saklaması, her ne kadar Windows Forms 
  uygulamalarına öykünse de, bir web programcısı için çok farklı yollara başvurma 
  gereği ortaya koyar. Session ve Application objeleri, uygulamayı geliştiren 
  kişinin en önemli olanaklarını belirlemektedir. Ancak pek çok programcı, bunların 
  yanında yadsınamayacak bir değer taşımakta olan ViewState’in varlığını hiçe 
  saymakta, ya da ona değerinin çok altında bir önem vermektedir. Bu makale sizlere 
  ViewState’i genel olarak tanıtacak, alternatif örneklerle, kullanımı konusunda 
  temel bilgiler verecektir. 
 İçerik:
 
 
 
  Genel Olarak ViewState Genel olarak ViewState Getirileri ve götürüleri  
    
  ViewState’in kullanımı Kullanıma yönelik alternatifler  
    
      Sunucuda Saklamak  
        
           Server’ın diski üzerinde saklamak SQL server ya da benzeri bir veri kaynağını kullanmak DataSet ve Session objeleri üzerinde saklamak 
 ASP.NET ile uygulama geliştirmek, tanımı ve çalışma şekli gereği, 
  “HTML çıktısı veren bir uygulama yazmak” olarak algılanabilir. Bu durum uygulama 
  geliştiricinin, ASP.NET’in üretmekte olduğu HTML’in sunumunu yapmakta olan IIS 
  ile browser arasında, sürekli veri gidiş-gelişlerini düşünmesini gerektirir. 
  Gerçekte her bir Page objesi, Init event’i ve PreRender event’leri arasında 
  oluşturulur, HTML çıktısı hazırlanır, ve bu çıktı browser’a gönderildiği anda 
  dispose edilir. Dolayısıyla hiçbir zaman, bir önceki durumunu kendi başına hatırlayabilen 
  bir Page objesinden söz edilemez. Programcı, Page objesine bu gidiş-gelişlerden 
  herhangi biri sırasında, eski durumunu hatırlaması konusunda yardımcı olabilmek 
  için ViewState ya da benzeri ortak bir depoya başvurmak zorundadır.
 
 Getirileri ve Götürüleri
 
 Performans
 
 ViewState’in kullanımı default olarak etkin durumdadır. 
  Kullanımı sırasında, Session ve Application objelerinin kullandığı sunucu kaynağından 
  daha az kaynak tüketir. Çünkü sunucu, veri tutma işini browsera verdiği ve her 
  seferinde geri aldığı ViewState datasını, sadece Init sırasında deserialize 
  etmek, ve PreRender sırasında, istemciye HTML göndermeden hemen önce serialize 
  etmek dışında bir kaynak kullanmadığı için daha az hafıza harcayacaktır. Herhangi 
  bir session sırasında bazen yüzlerce kere Page oluşturulmakta, ve dispose edilerek 
  hafızadan atılmaktadır. ViewState de Page’in bir parçasıdır.
 
 Hafıza kullanımının azalmasına rağmen ağ performansı konusunda 
  pek iyimser olmak mümkün değildir: ViewState her bir PostBack işlemi sırasında 
  ağ üzerinden istemciye gönderilmek ve geri alınmak zorundadır. Sayfalara bölünmüş, 
  büyük miktarda veri içeren datagridlerin kullanımı örnek olarak gösterilirse, 
  ViewState’in kilobyte’larca yer tutarak ve sayfayla birlikte taşınarak ağ üzerindeki 
  performansı önemli ölçüde azaltabildiği gözlenebilir.
 
 Güvenlik
 
 ViewState browser’a gönderilen bir string’den oluşmakta 
  olduğundan ve sadece Base64 olarak çevrimi yapıldığından, içeriğinin bir programcı 
  tarafından çalınması mümkündür. Ancak sanılanın aksine, browser’dan sunucuya 
  gönderilecek viewstate verisinin değiştirilmesi ile sunucunun kandırılması pek 
  mümkün değildir. Bunun nedeni, yine sayfa üzerinde tanımlı özelliklerden enableViewStateMAC’ın 
  default olarak “True” olmasıdır. (Pek çok kaynakta bu default değer “False” 
  olarak belirtilse de gerçekte “True” değeri almaktadır.)
 
 Browser’dan sunucuya gönderilmekte olan viewstate verisi, sadece 
  temel güvenlik kriterleri izlendiğinde (Kredi kartı vb. gibi bilgilerin ViewState 
  verisinin içine yerleştirilmemesi) doğal olarak bir güvenlik açığı yaratmayacaktır.
 
 ViewState’in Kullanımı
 
 ViewState’in ağ performansına yönelik negatif etkileri 
  nedeniyle kullanımı konusunda belli kriterler ya da alternatifler getirmek yerinde 
  olur:
 
 
 
  Kullanıma Yönelik Alternatifler Sabit sayfalarda enableViewState özelliği değerini “False”’a 
    çevirmek. Sayfa üzerinde state’in hatırlanması işlemini ViewState 
    yerine, Session ya da Application objeleri ile taşınacak verilerle belirlemek.Tüm sayfanın enableViewState’ini iptal etmektense, belli 
    kontrollerin ViewState kullanmasını engellemek. 
 ViewState’in network performansı üzerindeki negatif etkisini 
  azaltmak amacıyla bazı alternatif kullanım şekilleri geliştirilebilir. Bu yolda 
  atılması gerekli en önemli adım, Page nesnesi tarafından ViewState’in nasıl 
  kullanıldığının anlaşılmasıdır.
 
 Sunucuda Saklamak
 
 Page class’ı üzerinde ViewState’in alınması için yazılmış ve 
  Page’den türettiğimiz her bir sayfamız tarafından ViewState verilerinin serialize-deserialize 
  edilerek kullanılmasını sağlayan iki adet virtual metot bulunmaktadır:
 
 
 
  ve
    | protected 
        virtual object LoadPageStateFromPersistenceMedium() |  
 
 
  Bu metotlar, LosFormatter adlı, sadece sayfa üzerindeki ViewState 
  nesnesinin (StateBag class’ı) serialize ve deserialize edilmesi için geliştirilmiş 
  bir metot kullanmaktadırlar. LosFormatter’ın kullanımı konusunda bir ipucu yakalamak 
  için, LoadPageStateFromPersistenceMedium metodu içinde olması muhtemel default 
  kodlara şöyle bir göz atalım: 
    | protected 
        virtual void SavePageStateToPersistenceMedium(object viewState) |  
 
 
  Page class’ından türetilmiş sayfamız üzerinde LoadPageStateFromPersistenceMedium 
  ve 
    | string 
        strViewState = Request.Form["__VIEWSTATE"]; LosFormatter lf = new LosFormatter();
 object viewState = lf.Deserialize(strViewState);
 |  
 SavePageStateToPersistenceMedium 
  metotlarının override edilmesi ve bu metotlar içinde
 
 LosFormatter class’ının Deserialize ve Serialize metotlarının 
  kullanılmasıyla sunucu, ViewState verilerini hiçbir şekilde istemciye göndermeden 
  state bilgisini saklayabilir. Bu şekilde hem performans, hem de güvenlik konusunda 
  önemli artı değerler kazanılabilir.
 
 Aşağıda, bu konuda önerilebilecek üç ayrı alternatif hakkında 
  bilgiler bulabilirsiniz:
 
 Sunucunun Diski Üzerinde Saklamak
 
 Sunucuda ya da Web Farm üzerindeki herhangi bir ağ paylaşımında, 
  örneğin “SessionID.SayfaURL.viewState” adlı bir dosya tutulabilir. Aynı session 
  ID’sine sahip tüm dosyalar, session sona erdiğinde silinebilir. Aşağıda bununla 
  ilgili bir örnek bulabilirsiniz:
 
 Örnek, web uygulamasının bulunduğu klasörde “NT AUTHORITY\NETWORK 
  SERVICE” hesabının yazma hakkı bulunan “ViewStateData” adlı bir klasörün bulunduğu 
  kabul edilerek hazırlanmıştır.
 
 Öncelikle ViewState’i saklayacak ve okuyacak her iki virtual 
  metodu da override edelim. Bu iki override işlemi de ViewState’in diskte saklanmasını 
  istediğimiz Page class’ı içinde yapılacaktır:
 
 
 
  SavePageStateToPersistenceMedium metodu, LosFormatter ve StreamWriter 
  kullanarak, ve en altta belirlediğimiz GetViewStateFileName metodundan aldığı 
  string’e dayanarak dosya yoksa oluşturacak, varsa da üzerine yazarak, içeriğinde 
  ViewState verilerinin string olarak kalmasını sağlayacaktır. 
      
    | protected 
        override void SavePageStateToPersistenceMedium(object viewState) {
 LosFormatter 
        lf = new LosFormatter();
 StreamWriter 
        sw = new StreamWriter(Server.MapPath("ViewStateData\\" + GetViewStateFileName()));
 lf.Serialize(sw, 
        viewState);
 sw.Close();
 }
 
 protected 
        override object LoadPageStateFromPersistenceMedium()
 {
 LosFormatter lf = new LosFormatter();
 StreamReader sr = new StreamReader(Server.MapPath("ViewStateData\\" 
        + GetViewStateFileName()));
 string strViewState = sr.ReadToEnd();
 sr.Close();
 
 return lf.Deserialize(strViewState);
 }
 
 private 
        string GetViewStateFileName()
 {
 string sessionID = Session.SessionID;
 string pageURL = Request.Url.Segments[Request.Url.Segments.Length - 1];
 return sessionID + "." + pageURL + ".viewState";
 }
 
 
 |  
 LoadPageStateFromPersistenceMedium metodu ise ViewState’i string 
  olarak alıp, yine LosFormatter aracılığıyla StateBag objesine dönüştürecektir.
 
 Son olarak, Session bittiğinde gereksiz dosyaları silme işlemi 
  de Global class’ı içinde aşağıdaki handler aracılığıyla yapılabilir:
 
 
 
  SQL Server ya da Benzeri Bir Data Kaynağı Kullanmak 
      
    | protected 
        void Session_End(Object sender, EventArgs e) {
 string sessionID = Session.SessionID;
 System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(Server.MapPath("ViewStateData"));
 System.IO.FileInfo[] 
        files = dir.GetFiles(sessionID + ".*");
 
 foreach (System.IO.FileInfo file in files)
 {
 file.Delete();
 }
 }
 
 
 |  
 ViewState’in SQL sunucusunda bir tabloda saklayarak connected 
  senaryo ile almak da performansı arttıracak başka bir yöntem olarak düşünülebilir.
 
 Öncelikle SessionID, PageURL ve ViewState sütunlarından oluşan 
  bir tablo belirlenmeli ve SavePageStateToPersistenceMedium metonunun bu tabloya 
  yazarak ViewState’i saklaması, LoadPageStateFromPersistenceMedium metodunun 
  da bu tabloda tarama yaparak ViewState verisini alması sağlanmalıdır:
 
 
  
 
 
  Son olarak düşünülmesi gereken, Session bittiğinde SQL’den 
  gereksiz satırların silinmesidir. Bu işi de Global class’ı içinde aşağıdaki 
  gibi halletmek mümkündür: 
    | protected 
        override void SavePageStateToPersistenceMedium(object viewState) {
 
 SqlConnection 
        cn = new SqlConnection("data source=localhost;database=ViewStateDemo;trusted_connection=true");
 LosFormatter lf = new LosFormatter();
 
 StringWriter sw = new StringWriter();
 lf.Serialize(sw, viewState);
 System.Text.StringBuilder sb = sw.GetStringBuilder();
 string strViewState = sb.ToString();
 string strSessionID = Session.SessionID;
 string strPageURL = Request.Url.Segments[Request.Url.Segments.Length - 
        1];
 
 if (SatirVarMi())
 {
 SqlCommand cmd = new SqlCommand("update ViewStateData set ViewState 
        = @ViewState where SessionID = @SessionID and                PageURL 
        = @PageURL", cn);
 cmd.Parameters.Add("@ViewState", strViewState);
 cmd.Parameters.Add("@SessionID", strSessionID);
 cmd.Parameters.Add("@PageURL", strPageURL);
 
 try
 {
 cn.Open();
 cmd.ExecuteNonQuery();
 }
 
 catch (SqlException exp)
 {
 throw exp;
 }
 
 finally
 {
 cn.Close();
 }
 }
 
 else
 {
 SqlCommand cmd = new SqlCommand("insert ViewStateData (SessionID, 
        PageURL, ViewState) values (@SessionID,                @PageURL, 
        @ViewState)", cn);
 cmd.Parameters.Add("@ViewState", strViewState);
 cmd.Parameters.Add("@SessionID", strSessionID);
 cmd.Parameters.Add("@PageURL", strPageURL);
 
 try
 {
 cn.Open();
 cmd.ExecuteNonQuery();
 }
 
 catch (SqlException exp)
 {
 throw exp;
 }
 
 finally
 {
 cn.Close();
 }
 }
 }
 
 protected override 
        object LoadPageStateFromPersistenceMedium()
 {
 SqlConnection cn = new SqlConnection("data source=localhost;database=ViewStateDemo;trusted_connection=true");
 SqlCommand cmd = new SqlCommand("select ViewState from ViewStateData 
        where SessionID = @SessionID and PageURL =           @PageURL", 
        cn);
 cmd.Parameters.Add("@SessionID", Session.SessionID);
 cmd.Parameters.Add("@PageURL", Request.Url.Segments[Request.Url.Segments.Length 
        - 1]);
 string strViewState;
 
 try
 {
 cn.Open();
 strViewState = (string) cmd.ExecuteScalar();
 }
 
 catch (SqlException exp)
 {
 throw exp;
 }
 
 finally
 {
 cn.Close();
 }
 
 LosFormatter lf = new LosFormatter();
 return lf.Deserialize(strViewState);
 }
 
 private 
        bool SatirVarMi()
 {
 SqlConnection cn = new SqlConnection("data source=localhost;database=ViewStateDemo;trusted_connection=true");
 SqlCommand cmd = new SqlCommand("select count(*) from ViewStateData 
        where SessionID = @SessionID and PageURL =      @PageURL", 
        cn);
 cmd.Parameters.Add("@SessionID", Session.SessionID);
 cmd.Parameters.Add("@PageURL", Request.Url.Segments[Request.Url.Segments.Length 
        - 1]);
 int rowCount;
 
 try
 {
 cn.Open();
 rowCount = (int) cmd.ExecuteScalar();
 }
 
 catch (SqlException exp)
 {
 throw exp;
 }
 
 finally
 {
 cn.Close();
 }
 
 if (rowCount == 1)
 return true;
 else
 return false;
 }
 
 
 |  
 
 
  DataSet ve Session Objeleri Üzerinde Saklamak 
    | protected 
        void Session_End(Object sender, EventArgs e) {
 SqlConnection 
        cn = new SqlConnection("data source=localhost;database=ViewStateDemo;trusted_connection=true");
 SqlCommand cmd = new SqlCommand("delete ViewStateData where SessionID 
        = @SessionID", cn);
 cmd.Parameters.Add("@SessionID", Session.SessionID);
 
 try
 {
 cn.Open();
 cmd.ExecuteNonQuery();
 }
 
 catch (SqlException exp)
 {
 throw exp;
 }
 
 finally
 {
 cn.Close();
 }
 }
 
 
 |  
 Son olarak farklı bir alternatif, ViewState’in Session 
  objesi üzerinde bir dataset’te tutulması düşünülebilir. Aşağıda bu alternatifle 
  ilgili örnek kodlar bulabilirsiniz:
 
 Öncelikle DSViewState adında bir typed-dataset oluşturalım:
 
 
  
 Bu DataSet’in, oluşan her bir yeni session’da bir instance 
  olarak saklanması ve içindeki tabloya viewstate verilerinin DataRow’lar halinde 
  eklenmesi ya da değiştirilmesi ile viewstate yine sunucu tarafında ram’de saklanabilecektir.
 
 Global class’ı içinde aşağıdaki gibi bir Session değişkeni 
  içinde dataset oluşturularak tüm session içinde bu değer kullanılabilir:
 
 
 
  ViewState’in dataset’te saklanması istenen Page class’ı içinde 
  de aşağıdaki override işlemleri yapılarak da bu alternatif kullanılabilir. 
    | protected 
        void Session_Start(Object sender, EventArgs e) {
 DSViewState 
        ds = new DSViewState();
 Session["dsViewState"] = ds;
 }
 
 
 |  
 
 
  Sonuç olarak, örneklemeye çalıştığım bu üç alternatifle, 
  ViewState ağ performansı negatif olarak etkilenmeden kullanılabilecek, daha 
  hızlı çalışan ve ViewState’ten dilediğince yararlanan web uygulamaları geliştirmek 
  mümkün olabilecektir. 
    | protected 
        override void SavePageStateToPersistenceMedium(object viewState) {
 LosFormatter 
        lf = new LosFormatter();
 StringWriter 
        sw = new StringWriter();
 lf.Serialize(sw, 
        viewState);
 System.Text.StringBuilder 
        sb = sw.GetStringBuilder();
 string 
        strViewState = sb.ToString();
 string 
        strPageURL = Request.Url.Segments[Request.Url.Segments.Length - 1];
 DSViewState 
        ds = (DSViewState) Session["dsViewState"];
 
 if 
        (ds.ViewStateData.Rows.Contains(strPageURL))
 {
 DataRow 
        row = ds.ViewStateData.Rows.Find(strPageURL);
 row["ViewState"] 
        = strViewState;
 }
 else
 {
 DataRow 
        row = ds.ViewStateData.NewRow();
 row["PageURL"] 
        = strPageURL;
 row["ViewState"] 
        = strViewState;
 ds.ViewStateData.Rows.Add(row);
 }
 }
 
 protected override 
        object LoadPageStateFromPersistenceMedium()
 {
 DSViewState 
        ds = (DSViewState) Session["dsViewState"];
 string 
        strPageURL = Request.Url.Segments[Request.Url.Segments.Length - 1];
 DataRow 
        row = ds.ViewStateData.Rows.Find(strPageURL);
 string 
        strViewState = (string) row["ViewState"];
 LosFormatter 
        lf = new LosFormatter();
 return 
        lf.Deserialize(strViewState);
 }
 
 
 |  
 MCSD.NET, MCDBA, MCSE+I, MCSE (NT4, W2K, W2003), MCSA (W2K, 
  W2003), MCAD, MCP+I, MCP, MCT
 
 Trainer / Software Engineer
 
 [email protected]
 
 
 
                Makale:ViewState’in Sunucuda Saklanması ASP.NET Nazmi Savga
 |  
            |  |  
            |  |  
            | 
                    
                        
                            
                        
                            Eklenen Son 10 
                            Bu Konuda Geçmiş 10 
                        
                            Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
                         
                            Son Eklenen 10 Makale Yükleniyor
                         
                            Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
                         |  
            |  |  |