ASP.NET State Management (Durum Yönetimi)

Durum yönetimi (State Management): kısaca açıklamak gerekirse; kontrolün, web sayfasının, nesnenin, dataların ve kullanıcının durumunu korumak anlamına gelir.

Bir asp.net uygulaması her sayfa yüklemesinde (post eventinde) server tarafından sunucuya yeniden oluşturularak sunulur. Bu durumda, sayfa üzerinde ki kullanıcı işlemlerinin ortadan kalkmasına veya işlem gören datalarınızın, değişkenlerinizin varsayılan değerlerine geri dönmesine sebep olur.

Örneğin, sayfa üzerinde bir anket formu doldurduğunuz düşünelim bu formu doldurma sırasında eğer sayfanızı yenilersiniz doldurduğunuz tüm form alanları yeniden yüklenileceğinden dolayı boş gelecektir. Bir başka örnek düşünecek olursak; sayfamızda bir değişken tanımladığımızı düşünelim bu değişkene kullanıcıdan alınan işlem sunucu bir değer yüklemesi yapacaksınız ve yüklediğiniz değeri daha sonra kullanmak isteyeceksiniz. Yine bir sayfa yenilemesinde veya başka bir sayfa gittiğinizde bu değişkeniniz varsayılan değerine geri dönecektir.

Bu nedenlerden dolayı, bu tip yapılardaki sorunları ortadan kaldırmak için asp.net bizlere durum yönetim araçları sunar. Şimdi hep birlikte bu araçları inceleyelim.

Durum Yönetimi (State Managment) Tipleri

Durum yönetimi (state management), istemci ve sunucu tarafından çalışanlar olmak üzere ikiye ayrılırlar.

Istemci Tarafı (Client-Side State Management)

  • Hidden Field
  • View State
  • Cookies
  • Control State
  • Query Strings

Sunucu Tarafı (Server-Side State Management)

  • Session
  • Application

Istemci Tarafı Durum Yönetimleri (Client-Side State Management)

1) Hidden Field

Asp.net tarafından istemcide az miktarda veri depolamak için kullanılan bir yöntemdir. C# tarafından tanımladığımız değişkenlere benzerler. Fakat, C# tarafından tanımladığımız değişken, sayfa her yenilendiğinde (post-back) varsayılan değerine geri dönecektir. Hidden Field ise bu tip durumda kaldığı yerden devam eder. Bu nedenle bu değişken değerinin sık sık değiştiği durumlarda tercih edilir. Hidden Field kontrolü kullanıcıya tarayıcı üzerinden gösterilmez. Hidden Field, standart kontrolün değeri gibi her bir istekle birlikte hareket eder.

Örnek: Hidden Field’a değer atama ve bu değeri her yenilemede 1 artırma işlemi.

aspx tarafı:

<form id="form1" runat="server">
   <div>
      <asp:HiddenField ID="HiddenField1" runat="server" Value="0" />
      <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
      <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
   </div>
</form>

aspx.cs tarafı:

protected void Page_Load(object sender, EventArgs e)
{
     if (HiddenField1.Value != null)
     {
          int val = Convert.ToInt32(HiddenField1.Value) + 1;
          HiddenField1.Value = val.ToString();
          Label1.Text = val.ToString();
     }
}

protected void Button1_Click(object sender, EventArgs e)
{
     //Bir eylem yok sadece, butona tıklayın post-back için.
}

2) View State

Asp.Net tarafından kullanıcının verilerini depolamak için sağlanan istemci taraflı bir mekanizmadır. Form düzeyinde verileri saklamak için kullanılır. Tüm kontrollerle ilgili değerleri Base64 olarak kodlanmış halde string nesnesi olarak ViewState isimli bir gizli input kontrolünde tutar. Varsayılan olarak aktif (true) olarak gelir. Müdahele edilerek ViewState pasif hâle getirilebilir. Kısaca açıklayacak olursak istemci (tarayıcı) ve sunucu arasında bilgi alışverişi yapar. Sunucuya gönderilen değerler viewstate içinde saklanır ve tarayıcıya dönen değerler, viewstate içerisine depo edilerek gönderilir. Eğer bilinçsiz bir şekilde kullanılırsa kontrolün içi şişer ve performans azalır. Bu tip durumlarda view state kontrolünü doğru yönetmek çok önemlidir.

*ViewState: sayfalar arası veri taşımaz. ViewState farklı bir sayfaya geçildiğinde silinir, sadece o sayfa için geçerlidir.

Örnek: Sayfamıza bir adet label, textbox ve bir de buton ekleyelim. Her butona bastığında label’ımızın değerini alarak üzerine textbox’a yazdığımız değeri alarak ekleyip tekrar gösterelim önce bunu Label’a müdahale etmeden daha sonrada Label’ın EnableViewState=”false” değerini atayarak gerçekleştirelim arada ki farkı hep birlikte inceleyelim.

aspx tarafı:

<form id="form1" runat="server">
    <div>
        <asp:Label ID="Label1" runat="server" Text="1"></asp:Label>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
    </div>
</form>

aspx.cs tarafı:

protected void Button1_Click(object sender, EventArgs e)
{
     Label1.Text = Label1.Text + TextBox1.Text;
}

Sonuç olarak, textbox sırasıyla 2 ve 3 yazın ve her seferinde butuna basınız. Label’ınızın texti: 123 olacaktır. Şimdi bu işlem Label kontrolümüzün View State durumunu false yaparak deneyelim.

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

Yine, textboxımıza sırasıyla 2 ve 3 yazıp her seferinde butona basalım. Bu sefer Label’ımızın textinin son yazılan değer olduğunu göreceksiniz (12, 13). Çünkü ViewState false yaptığımız için sayfa post-back olduğunda üzerinde ki değeri taşımayacaktır.

Tüm sayfada kapatmak için:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" EnableViewState="false" %>

3) Cookies

Çerezler (Cookies), kulanıcının tarayıcısı tarafında oluşturulan ve kullanıcının sabit diski üzerinde sakladığı text dosyalarıdır. Çerezler genelde 4096 byttır ayrıca çerez oluştururken kullanıcıda ne kadar süre saklanacağı da belirtilebilir. Çerezlerin avantajı kullanıcının bilgisayarında saklandığı için uzun bir süreçte farklı zamanlarda erişilebilir olmasıdır. Dezavantajı ise bazı tarayıcıların veya kurulu olan antivürüs programların bunları engellemesidir. Web projelerinde en sık kullandığımız alanlar üye girişi gibi bölümlerde beni hatırla olayıdır.

Örnek: sayfamız yüklendiğinde çerezimizi oluşturalım. Daha sonrasında oluşturulan çerezi butona tıklayınca textbox’ımızın içerisine yazalım.

Aspx tarafı:

<form id="form1" runat="server">
    <div>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
    </div>
</form>

Aspx.cs tarafı:

protected void Page_Load(object sender, EventArgs e)
{
     //Çerez oluşturma 1. Yöntem:
     Response.Cookies["BenimCerezim"].Value = "Fatih ALKAN";
     Response.Cookies["BenimCerezim"].Expires = DateTime.Now.AddDays(10); //Saklanma süresi

     //Çerez oluşturma 2. Yöntem:
     HttpCookie aCookieValPer = new HttpCookie("BenimCerezim2");
     aCookieValPer.Value = "www.alkanfatih.com";
     aCookieValPer.Expires = DateTime.Now.AddSeconds(10);
     Response.Cookies.Add(aCookieValPer);
}

protected void Button1_Click(object sender, EventArgs e)
{
     if (Request.Cookies["BenimCerezim"] != null)
         TextBox1.Text = Request.Cookies["BenimCerezim"].Value;
}

4) Control State

view state’in bazı eksikliklerini tamamlamak için oluşturulmuş bir mekanizmadır. Control state view state ile aynı veri yapısındadır. Fakat Control state view state özelliği kapalı olsa bile kullanılabilir.

5) Query String

Sayfalar arası veri taşımak için sıkça kullanılan en basit yöntemdir. Sakladığı bilgiyi diğer bir sayfaya URL aracılığı ile taşır. Taşınılacak veri sayfa adının ardından soru işrati (?) ile başlayan bir anahtar kelime oluşturulur ve eşittir (=) operatörü kullanılarak taşınacak veri atanır. Değişken tanımlamayla aynı mantığa sahiptir. Tek fark bu değerin URL ile gönderilmesidir. Query String yöntemiyle birden fazla anahtar kelime tanımlayarak istediğimiz kadar veri taşıyabiliriz. Query String kullanımının kolay olması bir avantaj olmakla beraber gönderdiğinizin değerin URL üzerinden kullanıcı tarafından görünür olması ise bir dezavantajdır. Çünkü bu şekilde gönderilen değere URL üzerinden kullanıcı müdahale edebilir bu da büyük bir güvenlik açığı meydana getirir.

Query String Güvenlik Açığı – (SQL Injection Nedir ? Nasıl Yapılır ? Saldırı Çeşitleri ? Nasıl Korunulur ?)

https://alkanfatih.com/sql-injection-nedir-nasil-yapilir-saldiri-cesitleri-nasil-korunulur/

Örnek: Bu örneğimizde iki sayfa programlayacağız. “Default.aspx” ve “Default2.aspx” Defaul.aspx’imizde oluşturacağımız butonun click eventini kullanarak Defaul2 ye QueryString ile veri taşıyacağız.  Default2 de ise default dan gelen QueryString değerlerimizi yakalayıp sayfamızda bulunan labellarımıza atıcaz.

default.aspx tarafı:

<form id="form1" runat="server">
     <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</form>

default.aspx.cs tarafı:

protected void Button1_Click(object sender, EventArgs e)
{
     //Sayfa adresimizden sonra, (?) ile birlikte anahtar kelimemimizi tanımlıyoruz.
     //Daha sonra anahtar kelimemize (=) ile birlikte değerimizi atıyoruz.
     //Eğer birden fazla QueryString oluşturmak istiyorsak (&) operatörü kullanıyoruz. 
     Response.Redirect("Default2.aspx?Adi=Fatih&Soyadi=Alkan&No=53");
} 

default2.aspx tarafı:

<form id="form1" runat="server">
    <asp:Label ID="lbl_ad" runat="server" Text="Label"></asp:Label>
    <asp:Label ID="lbl_soyad" runat="server" Text="Label"></asp:Label>
    <asp:Label ID="lbl_no" runat="server" Text="Label"></asp:Label>
</form>

default2.aspx.cs tarafı:

protected void Page_Load(object sender, EventArgs e)
{
    //Request.QueryString ile anahtar kelimenizi kullanarak Query yakalıyoruz.
    //Request.QueryString bize string cinsinden değer döndürür.

    lbl_ad.Text = Request.QueryString["Adi"];
    lbl_soyad.Text = Request.QueryString["Soyadi"];

    //Queryimizin indeks numarısını kullanarakda yakalayabiliriz. indeks 0 dan başlar.
    lbl_no.Text = Request.QueryString[2];
}

Sunucu Tarafı Durum Yönetimleri (Server-Side State Management)

1) Session

Session yönetimi, asp.net’de durumu korumak için kullanılan çok güçlü bir tekniktir. Genel olarak session nesnesi (oturum), kullanıcıların bilgilerini depolamak ve bir kullanıcıya benzersiz bir kimlik tanımlamak için kullanılır.

Kullanıcı bir web adresine girip sayfa çağırdığında, web sunucusu her kullanıcı için bir oturum başlatır. Bu oturum boyunca session nesnelerini saklar ve sayfalar arası taşır. Örneğin; E-Ticaret sitelerinde kullandığımız alışveriş sepetimiz veya üye bilgilerimiz her ikisine de veri girişi olduktan sonra tüm sayfalar boyunca bilgileri session yardımıyla taşıyabilir ve görüntüleyebiliriz.

Session; oturum süresi sona erdiğinde, web penceresi kapatıldığında veya kullanıcı oturumu kapattığında sonlanır.

Asp.net’de her kullanıcı için bir oturum başlatılır. Bu oturum, Session ID dediğimiz bir oturum kimliği kullanarak kullanıcı bilgilerini korur. Kullanıcılar bir oturum kimliği olmadan bir istek yaptığında, asp.net bir oturum kimliği oluşturur ve her kullanıcıya aynı isteği ve yanıtı gönderir.

Örnek: Bu örneğimizde iki adet sayfa tasarlayacağız ilk sayfamız olan Session.aspx’de bir label, bir textbox, iki tane buton kullanıcaz. İlk butonumuz olan Yükle tıklandığı zaman session nesnesi oluşturup label’a aktarcaz. İkinci buton olan Taşı ise tıklandığında Session2.aspx sayfasına yönlendirecek bizi, bizde yine aynı şekilde ikinci sayfada session nesnemizde olan bilgileri Label’a aktarıcaz. Daha sonra da silme ve oturum kapatma işlemlerini gerçekleştireceğiz.

session.aspx tarafı:

<form id="form1" runat="server">
     <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label></br>
     <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox></br>
     <asp:Button ID="Button1" runat="server" Text="Yükle" OnClick="Button1_Click" /></br>
     <asp:Button ID="Button2" runat="server" Text="Taşı" OnClick="Button2_Click" />
</form>

session.aspx.cs tarafı:

protected void Button1_Click(object sender, EventArgs e)
{
    //Session oluşturma: Yöntem 1 (Anahtar kelimeyle)
    Session["AdSoyad"] = "fatih alkan";

    //Session oluşturma: Yöntem 2 (Add metoduyla)
    Session.Add("No", TextBox1.Text);

    //Session değeri alma.
    Label1.Text = Session["AdSoyad"].ToString() + Session["No"].ToString();
}

protected void Button2_Click(object sender, EventArgs e)
{
    Response.Redirect("Session2.aspx");
}

session2.aspx tarafı:

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

session2.aspx.cs tarafı:

protected void Page_Load(object sender, EventArgs e)
{
     //Session değeri alma.
     Label1.Text = Session["AdSoyad"].ToString() + Session["No"].ToString();

     //Session Silme 
     Session.Remove("AdSoyad");

     //Tüm Sessionları Silme
     Session.RemoveAll();

     //Session Oturum Sonlandırma
     Session.Abandon();
}

Session Event Kullanımı

Asp.net de, Global.asax dosyasını kullanarak Session nesnelerinizin Eventlerini yönetebilirsiniz. Session iki adet Event sunar. session_start ve session_end yani session oturum açtığında ve bitirdiğinde çalışır.

session_start: yeni bir kullanıcı oturum kimliği olmadan bir istek yaptığı zaman ortaya çıkar. Yani kullanıcı siteye yeni bir tarayıcıdan (i.e, chrome, vb.) giriş yaptığında çalışır

protected void Session_Start(object sender, EventArgs e)
{
    Session["AdSoyad"] = "Adı Soyadı";
}

session_end: oturum zaman aşamasına uğradığında, sayfa kapatıldığında veya Session.Abondon() metodu kullanıldığı zaman çalışır.

Asp.net tarafından sağlanan 4 çeşit Session depolama yöntemi vardır.

  • In Process
  • State Server
  • SQL Server
  • Custom

In Process: In proc modu, asp.net tarafından varsayılan olarak sağlanan saklama sistemidir. Bu sistemde Session nesnesi web server’ın hafızasında saklanır. Eğer birden fazla IIS sunucusu varsa, session değerleri isteğin yapıldığı her sunucuda ayrı ayrı depolanır. Sunucu her yeniden başlamasında session nesneleri silinir.

State Server: Bu modda session nesnesini web server üzerinde saklar. Ancak uygulama alanının dışında tutar. bu mod kullanılırsa genelikle, oturumları depolamak için ayrı bir sunucu olacaktır, yani stateServer. Bu modun yararı IIS yeniden başlatıldığında oturumun kullanılabilir olmasıdır. Oturumu ayrı bir Windows hizmetinde saklar. State Server modu için web yapılandırma dosyasında açıkça yapılandırmamız ve asnet_state hizmetini başlatmamız gerekir.

SQL Server: Sql Server mod ile session nesnesi SQL Server DataBase üzerinde saklanır. Bu mod, IIS’den ayrı olduğu için IIS yeniden başlatılsa bile session nesneniz kullanılabilir durumda olur. Bu modun avantajı güvenilir olmasıdır. Dezavantajı ise verilerin serileştirilmesi ile kaynaklanan ek yüklerdir. Güvenilirlik performanstan daha önemli olduğunda bu mod kullanılmalıdır.

web.config yapılandırma dosyası:

<sessionstate mode="InProc" cookieless="false" timeout="10" stateConnectionString="tcpip=127.0.0.1:80808" sqlConnectionString="Data Source=.\SqlDataSource;User ID=userid; Password=password"/>

Custom Session: Genellikle Process state server modu veya Sql Server modu tercih etmeliyiz. Ancak başka teknikler kullanarak Session nesnenizi saklamak istiyorsanız bu modu tercih etmelisiniz. Bu mod Asp.net’e özel bir session modu sağlar. Bu mod ile herşeyin kontrolünü bizim kordine etmemiz gerekmektedir. Session ID üretilmesi, dataların saklanması, güvenlik gibi.

Özellik Tanım
Cookieless
true/false
Session nesnemizin Cookie kullanılarak veya kullanılmayarak saklanmasını
kontrol eder. Varsayılan olarak False’dır.
timeout Session nesnemizin süresini temsil eder. Varsayılan olarak 20 saniyedir.
StateConnectionString Session nesnemizin uzak bilgisayarda (sunucuda) depolandığını gösterir.
Bu özellik oturum modu StateServer olduğunda gereklidir.
SqlConnection
String
Session nesnemizin veri tabanında saklandığını gösterir. Bu özellik oturum moduSqlServer olduğunda gereklidir.

2) Application

Application (Uygulama durumu) bir diğer sunucu taraflı durum yönetimi tekniğidir. Uygulamanın tamamını kapsayan değişkenler oluşturup kullanılmak istenildiğinde tercih edilir. Application modda saklanan data tüm kullanıcılar için ortaktır ve uygulamanın her yerinden erişim izni verilir. Yani herkes tarafından ve her yerden erişilebilen bir değişken gibi düşünülebilir. Avantajı uygulamaya özgü olmasıdır. Yani, IIS çalıştıkça değişkenlere erişilebilir. Tarayıcı kapatılsa bile değişkenler bellekte kalır. Dezavantajı ise uygulamada saklanan veriler küçük boyutta olmalıdır.

*Not: Application nesnesinin genellikle uygulamanızın durum yönetimlerini yönettiğimiz alanlarda tercih ederiz. Uygulama takibi (Log tutma), Kullanıcı hareketlerinin takibi (Analiz işlemleri) gibi.

aspx tarafı:

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

aspx.cs tarafı:

//Application değer atama yöntemleri.
Application["Deger"] = "www.alkanfatih.com";
Application.Add("Deger2", "fatih alkan");

//Application yüklü değere erişim.
Label1.Text = Application["Deger"].ToString() +    Application["Deger2"].ToString();

Application Event Kullanımı

Asp.net de, Global.asax dosyasını kullanarak Application nesnelerinizin Eventlerini yönetebilirsiniz. Application beş adet Event sunar. Bunlar, Application_Start, Application_BeginRequest, Application_AuthenticateRequest , Application_Error ve Application_End eventleridir.

Application_Start: Uygulamaya ilk istek geldiğinde ortaya çıkar ve sunucu kapatılıp tekrar açılana kadar çalışmaz.

Application_BeginRequest: Uygulamaya bir istekte bulunulduğunda ortaya çıkar. Genellikle gelen talebin durumuna göre işlem yapılmak istenirse bu event kullanılır.

Application_AuthenticateRequest: Uygulamaya giriş yapmak istediğimizde ortaya çıkar. Giriş yapan kullanıcının kimliğine bakılarak yetkilendirme, yönlendirme gibi işlemler yapılabilir.

Application_Error: Uygulamada hata oluştuğunda ortaya çıkar.

Application_End: Uygulama sonlandığında ortaya çıkar.

4 comments

  1. Hocam merhabalar,

    Üye girişi için ayrı bir giris sayfası değilde masterpage üzerinde sabit olarak sitenin header bölümüne login paneli yaptım. Giriş yapan kullanıcının adını ve soyadını veritabanından okuyup oluşturduğum session ile labele “Hoşgeldiniz Xxxx Xxxx” şeklinde karşılama oluşturdum fakat sayfa değiştirince logout oluyor. Sayfa değiştirdiğimde sessionı tutmak için ne yapmam gerekiyor?

    1. Master Page üzerinden session tutarsanız master page uyguladığınız veya uygulamadığınız tüm sayfalarda session’u tutar zaten. Session nesnesinin mantığı budur çünkü sayfadan bağımsız sunucu tarafında veri iletişimi sağlar. Sizde başka bir problemden dolayı session hata veriyordur. sayfa değişimlerini nasıl yaptınız acaba linklerinizi kontrol edebilir misiniz? Mesela a href koduna site başlığı ile birlikte href=”www.alkanfatih.com/page1″ gibi verirseniz sayfa yenileneceğinden session yeniden yaratılabilir. Bu durumda boş olarak gelir.

  2. Linkleri sayfa şeklinde verdim. Ben biraz karıştırdım sanırım. Açıkçası saatin 04:00 olmasından da kaynaklansa ki kafam da karıştı 🙂 Masterpage üzerinde sabit bir üye giriş paneli yapmak istiyorsak iki adet mi masterpageimiz olmalı hem üye girişi yapanları karşılayacak masterpage hemde üye girişi yapmayan ziyaretçilere görünecek olan masterpage’li sayfalar olacak değil mi? Ben tek masterpage ile yapmaya çalıştım olmadı çünkü. Şöyle yaptım butongiris_click içerisine session oluşturuyorum giris yapan kullanıcının veritabanından adını ve soyadını okuyarak bu session da tutuyorum daha sonra giriş yapan kullanıcının yine veritabanından yetkisini sorguluyorum. adminkarsila adında bir linkbuton oluşturdum buna link olarak “admin.aspx” sayfasını verdim. Giriş yapan kullanıcı admin ise adminkarsila.text görünsün değil ise de bu sefer uyekarsila adın da oluşturduğum linkbuton görünsün dedim buna da link olarak “userprofil.aspx” verdim. Kişi login olduğunda oluşturduğum session ile “Hoş geldin xxxx xxxx” diye kullanıcının adını ve soyadını yazarak karşılıyor. Kullanıcı adının ve soyadının üzerine tıkladığında admin ise “admin.aspx”‘e şayet üye ise “userprofil.aspx”‘e gidiyor buraya kadar problem yok ama kullanıcı giriş yaptığı anasayfa ile aynı masterpage’i kullanan diğer sayfalara geçiş yaptığında logout oluyor çünkü ana masterpage’in page_load’u boş. masterpage’in page_load’una session kodumu yazdım olmadı. masterpage’i bağladığım sayfaların page_load’ına yazdım yine olmadı. Ben de çareyi iki farklı masterpage oluşturmakta buldum oldu. hatta adminle beraber 3 masterpage oluşturdum. Bir tane ana.masterpa üye olmayan ziyaretçilerin göreceği sayfalara bağladığım. bir tane üyelerin masterpage’i bir de admin.master. Anca bu şekilde çözebildim ama ortak sayfalar nasıl olacak index sayfası gibi ya da iletişim sayfası gibi mesela bu sayfaları üye girişi yapanda yapmayan da görebilecek. Her sayfadan 3 tane oluşturmam gerekiyor sanırım. Siteye ilk girişte headerında üye girişi paneli olan “index.aspx”, uye girişi yapan için “uyeindex.aspx” giriş yapan admin ise “adminindex.asp” şeklinde. 3 farklı masterpage oluşturunca her şey çok karıştı. Başta yapmaya çalıştığım gibi tek masterpage ile olmuyor değil mi?

Bir Cevap Yazın