23 Şubat 2016 Salı

ASP.NET SESSION MANTIĞI VE YÖNETİMİ

     "Session" nedir sorusuna verilebilecek ilk cevap Web sayfaları arasında "Veri Aktarımı" yapılmasını sağlayan oturum nesnesidir diyebiliriz. Session kullanıcılara ait verilerin ( Kullanıcı adı , şifre , IP Adresi gibi) sunucu üzerinde tutulmasını sağlayan yapıdır.Bu oturum nesnesi Server Side (Sunucu) tarafında benzersiz bir "SessionId" ile her Client(istemci) için ayı ayrı oluşturulur.Bu oluşturulan Session nesneleri Server(sunucu) üzerinde tutulur.Bildiğiniz üzere Cookie nesneleri de veri aktarımında kullanılır fakat Cookie'ler Client tarafındaki Browser üzerinde tutulurken, Session nesneleri Server tarafında tutulur ki bu yüzden güvenli bir yöntemdir.O yüzden önemli bilgiler şayet tutulacaksa Cookie üzerinde değilde Session nesnesi üzerinde tutulmalıdır.

Session nesnesine değer atanması;

Session["UserName"] = txtUser.Text;

Session nesnesinden değer okunması;

if (Session["UserName"] != null)
{
    lblWelcome.Text = "Welcome : " + Session["UserName"];
}

    Session üzerinde Dataset nesneside tutulabilir ve sayfalar arasında taşınabilir.Yalnız Dataset nesnesi kendi başına bile bellek sorunu yaşatabilirken, serverda N tane client için oluşturulan N adet session üzerinde ayrı ayrı tutulacağını düşünürsek oturum boyunca ciddi bellek sorunlarına sebep olabileceği unutulmamalıdır.

Session["DataSet"] = objDataSet;

if (Session["DataSet"] != null)
{
    DataSet myDs = (DataSet)Session["DataSet"];
}

Session Üzerinde;
  -  Kullanıcı Adı, Şifresi,Kullanıcı Yetkileri, Oturum Açma Dili, Cient Ip'si, E-Ticaret Sitelerindeki Alış Veriş Sepeti İçerikleri (En Sağlam Yolu DB Tarafında Tutmaktır) gibi özellikler tutulabilir.

Unutulmaması gereken bir konu N tane Client sunucuya istekte bulunduğunda, Server tarafında N tane ayrı session nesnesi oluşturulur.Bu nesneler hiç bir zaman Client tarafına gönderilmez.Server side üzerinde bellekte tutulur.



Session Çalışma Modları

   Session nesnesinin "In-Proc", "SQLServer" ve "StateServer" gibi 3 temel çalışma modu bulunmaktadır. Default olarak In-Proc modda çalışmaktadır.In-Proc mod üstte de anlattığımız gibi session nesnesinin IIS Server tarafında tutulduğu klasik yöntemdir.SQLServer mod session nesnesinin SQL Server üzerinde veritabanında tutulduğu, StateServer mod ise session nesnesinin IIS server üzerinde değilde farklı bir sunucu üzerinde tutulduğu yöntemdir.

Server Üzerindeki Session Nesnesi ile Client Nasıl Haberleşir?

   -  Web sunucusundan bir sayfa talep edildiğinde, server ilgili client için benzersiz bir SessionId ile yeni bir session nesnesi oluşturur.(Uniqe)
   -  Bu SessionId 120 bitlik bir sayı olup ASP.NET algoritmasıyla oluşturulur
   -  Daha sonra bu SessionId Client tarafına(kullanıcıya) gönderilir.Client tarafında browser üzerinde default bir Cookie üzerinde tutulur.Böylelikle aynı SessionId değeri hem Server tarafında, hem Client tarafında tutulmuş olur
  -  Bu noktadan sonra Client tarafından Server'a gönderilen her postback'te bu SessionId ile Server tarafındaki kendine ait oturum eşlenir.Yani Server, Client tarafından gelen SessionId ile kendi üzerindeki Session nesnelerinden hangisinin ilgili kullanıcıya ait olduğunu bu şekilde anlamaktadır.
  -  Server, kullanıcının browseri kapatıp kapatmadığını bilemez.Client browseri kapatmadığı sürece kendi cookie'si üzerdinde daha önce açtığı session'a ait SessionId değerini saklar ve her postbackte bu değer ile istekte bulunur.Şayet Client browseri kapatırsa, yeniden açtığında eski oturuma ait Cookie olmayacağından herhangi bir SessionId ile istekte bulunmayacağından, Server bunu yeni bir istek olarak değerlendirecek ve bu Client'e ait yeni bir Session açacaktır.Eski session ise timeout süresi dolduğunda, bu süre zarfında o SessionId ile herhangi bir istek gelmeyeceğinden otomatik olarak sonlandırılacaktır.

   Peki cookie desteklemeyen browserlarda, veya Client tarafındaki browserin Cookie desteği kullanıcı tarafından kapatılırsa Session ile Client nasıl eşleşecektir?Yukarıda anlattığım üzere oturuma ait SessionId, client tarafındaki browser üzerinde Cookie ile tutulur.İlgili browserin cookie desteği yoksa veya kapatılmışsa Web.Config üzerindeki yapılacak bir kaç satırlık değişiklikten sonra oturuma ait SessionId, URL ile gidip gelecektir. Web.Config içindeki "SessionState" attributine ait "Cookieless" özelliği TRUE yapılırsa, SessionId link(URL) ile Client-Server arasındaki haberleşmeyi sağlayacak ve Server bu yapı sayesinde ilgili kullanıcıya ait Session nesnesini belirleyebilecektir.

<sessionState 
     ...
    cookieless="true" 
    timeout="20" 
/>

Session Nasıl Sonlanır?

   Session nesnelerinin sonlanması;

  -   Kullanıcının browser'i (tarayıcı) kapatması
  -   Session TimeOut süresinin dolması
  -   Server'in (sunucu) yeniden başlatılması
  -   Session'ın kapatılmaya zorlanması (kodsal olarak)

gibi durumlarda gerçekleşir.Session nesnelerinin timeout süreleri vardır ve bu süre default olarak 20 dk'dır.Eğer 20 dk içerisinde Client herhangi bir işlem yapmamışsa, hiç bir sayfa gezmemişse, server tarafında istekte bulunacak herhangi bir Postback hareketi oluşturmamışsa oturum sonlanacak, session düşecektir.

  Session.timeout = 1;      --> dk cinsinden belirlenen süredir.

Oturumun sonlanması sadece session timeout ile değil, kullanıcının browseri kapatmasıyla da gerçekleşir.Kullanıcı şayet tarayıcıyı kapatırsa, server tarafındaki session sonlanır. Web sayfasına giden ilk istekte session yeniden açılır.

Dikkat Edilmesi Gereken Nokta

   Session nesnesinin Server üzerinde tutulduğundan bahsetmiştik.Dikkat edilmesi gereken nokta "Load Balancing" kullanan sistemlerde Session eğer In-Proc modda çalışıyorsa, sorun yasanabileceği konusudur. Çünkü Web Garden/Web Farm/Web Pool kullanan yapılarda birden fazla server bulunur ve clientin ilk istek gönderdiği server üzerinde Session nesnesi oluşturulur. Dolayısıyla bir sonraki istekte Load Balancer devreye girip, aşırı yük yoğunluğundan Cliente ait isteği başka bir server'a yönlendirirse bu server üzerinde ilgili SessionId ile bir session nesnesi olmayacağından hata alınır.



   Bunun çözümü olarak Load Balancer kullanılan sistemlerde session In-Proc Modda değilde, StateServer veya SqlServer Modda çalıştırılıp session bilgileri değişmeyen başka bir ortamda tutulmalıdır.







           

1 Şubat 2016 Pazartesi

ASP.NET RESOURCE YÖNETİMİ ( Global, Local Resources )

       Asp.Net ile oluşturulmuş web sayfalarına (ERP,E-Ticaret,Web Tabanlı Uygulamalar gibi) çoklu dil desteği getirmek için Resource dosyalarından faydalanırız.Örneğin aynı sitenin Türkiye'den açıldığında Türkçe, Amerika'dan açıldığında İngilizce açılmasını bu yapılar sayesinde sağlarız.Genellikle browser dilinden(language) yola çıkılarak sayfanın hangi dilde açılacağına karar verilebilir, yada alternatif olarak IIS servera istekte bulunan Client'in local konumundan bulunduğu ülke belirlenip ona göre web içeriklerinin görüntülenme dili runtime olarak ayarlanabilir.Bunların dışında dil seçimi sisteme login olan kullanıcıya bir combobox aracılığıyla seçtirilebilir, seçilen dile göre içerik görüntülenebilir ve bu içerik cookie yada session üzerinde tutulabilir.
        Resource yönetimi Global ve Local Resource olmak üzere 2 kısımda incelenebilir.
- Local Resourcelar sayfa bazlı olup, her sayfaya ayrı olarak tanımlanır ve App_LocalResources klasörü altına atılırlar (generate edilir).






- Global Resourcelar tüm web sayfalarının ortak kullandığı yapılardır App_GlobalResources klasörü altına atılırlar (generate edilir).







Resource dosyaları .resx uzantılı XML tabanlı dosyalardır.Bu dosyalarda ResourceKey(name)-Value ikilileri tutulur.Ayrıca istenirse Commentlerde eklenebilir.İstenilen dile göre uzantıları değişmektedir.Örneğin;

Türçe için GlobalResources.tr-TR.resx
Almanca için GlobalResources.de-DE.resx
Fransızca için GlobalResources.fr-FR.resx

Şeklinde CultureName uzantıları verilmektedir.Bu uzantılara aşağıdaki link yardımıyla erişebilirsiniz.
https://msdn.microsoft.com/en-us/library/ee825488(v=cs.20).aspx

Resource dosyalarının XML tabanlı dosyalar olduğunu söylemiştik ve ayrıca Designer'ları bulunmaktadır. Bu designer üzerinden resource girişleri kolaylıkla yapılabilir.Aşağıda bir resource dosyasının designer ile açılmış halini ve içeriğini görebilirsiniz.Alt satırlara istenildiği kadar resource girişi yapılabilir.








Local Resource Kullanımı
      Local Resourcelar sayfa bazlı olup App_LocalResources klasörü altına oluşturulurlar.Sayfa bazlı tanımlandıklarından sayfaAdi.aspx.resx standardında oluşturulmaktadırlar.Örneğin Customer yönetimi ile ilgili bir sayfa yapıyorsak oluşturulacak resource dosyasının adı Customer.aspx.resx veya ingilizce uzantılı olacaksa Customer.aspx.en-US.resx şeklinde olacaktır. Şimdi local resource dosyasını nasıl tanımlayacağımıza bakabiliriz.Öncelikle aşağıdaki gibi basit bir login formu tasarlayabiliriz;


















Formu tasarladıktan sonra designer kısmına geçip Tools - Generate Local Resource tıklanırsa App_LocalResouce altına Login.aspx.resx dosyasının oluşturulduğu görülecektir.Dosya oluşturulduktan sonra ilgili resource dosyası üzerine çift tıklanıp içerikler girilebilir.









İçerikler girildikten sonra tekrar çalıştırılırsa formdaki string alanlar artık resource dosyasından gelecektir.Alanların code behind (aspx) tarafında text verilerini   meta:resourcekey="Ad"  şeklinde aldıklarına dikkat ediniz.Ayrıca local resource kullanımında sayfa üstünde yer alan Culture ve UICulture taglarının değiştirilebilir olduğunu, gerekirse farklı dillere çekilebileceğini göz önünde bulundurmanızda fayda olacaktır.








Şimdi App_LocalResources dosyasına sağ tıklayıp Add - ResourceFile tıklayarak İngilizce resource dosyasını Login.aspx.en-US.resx şeklinde ekleyip, resourceların İngilizce karşılıklarını girelim.(Siz buna istediğiniz herhangi bir dili girebilirsiniz.)



Sayfa üzerindeki Culture kısımları aşağıdaki gibi değiştirilirse, İngilizce resource dosyasından okuma yapılacağından sayfamız artık İngilizce açılacaktır.












Global Resource Kullanımı
    Global Resourcelar sadece bir sayfada değil,tüm projede geçerli genel resource keyleri için kullanılmaktadır.Örneğin "Ad" resourceu global olarak tanımlanırsa bu resourceu çağıran tüm sayfalarda resource value değeri ne ise o olarak gözükür, fakat local resource olarak tanımlandığında sayfa bazlı olacağından resource tanımına bağlı olarak a.aspx sayfasında "Ad" olarak çıkabileceği gibi, b.aspx sayfasında "İsim" olarak ekranda çıkabilir.
Şimdi de bir önceki gibi basit bir form tasarlayalım ve oluşturduğumuz proje üzerine sağ tıklayarak Add - Add ASP.NET Folder - App_GlobalResources seçeneğini tıklarsak projenin için App_GlobalResources dosyasının oluşturulduğunu görürüz.Daha sonra bu dosyanın üzerine de sağ tıklayarak Add - Resource File seçilerek resource dosyamız eklenir. Ben hem Türkçe hem de İngilizce resource dosyamızı GlobalResources.resx ve GlobalResources.en-US.resx adı ile bu şekilde ekleyip (siz başka bir isim verebilirsiniz) içeriklerini tasarladığım forma uygun giriyorum.










Daha sonra da itemlara ait  resource tanımlarını code behind tarafında aşağıdaki şekilde yapıyorum. Aşağıdaki Global Resource tanımın Local Resource tanımından farklı olduğuna dikkat etmenizi öneririm.Global Resourceda Text="<%$Resources:GlobalResources,TestButton%>" şeklinde bir tanım yapılmaktadır.














Bu tanım code behind tarafında text kısımları boş bırakılarak, server side kısmında aşağıdaki şekillerde de de set edilebilir.Sonuç aynı olacaktır.











Bir önceki uygulamamızdan farklı olarak projenin dil ayarlamasını bu kez Web.Config üzerinden yapıyorum.













Web config üzerinde tüm siteyi etkileyecek olan Globalization tagı yer almaktadır.Buradaki Culture kısmını İngilizceye çekip projeyi çalıştırıyorum.







Bu konuyla ilgili bir çok senaryo üretmek mümkündür. Örneğin dil ve resource tanımları DB'de tutulup bir ekran aracılığıyla son kullanıcıya girdirilebilir, bunun neticesinde resourcelar db'den okunarak herhangi bir exe veya uygulama içine gömülerek resource dosyaları otomatik olarak oluşturulabilir.Yine projenizdeki tüm uyarı mesajları,kullanıcıya gösterilen exceptionlar,log kayıtları vs  gibi her şey resource yapılarına bağlanıp tüm site dinamik bir şekilde yönetilebilir.

Umarım faydalı olmuştur.Bir sonraki yazımızda görüşmek üzere.
İyi Çalışamalar