SİTE
İÇİ ARAMA |
|
Blogroll |
|
|
|
Her Yönüyle ViewState Kavramı |
|
Gönderiliyor lütfen bekleyin... |
|
|
Güzide Windows uygulamalarından, karanlık ASP.Net sayfalarına geçildiğinde yadırganılan ilk konulardan biri heralde veri aktarımı ve bu verilerin saklanmasıdır. Sonuç olarak sayfa her post back olduğunda veriler kaybolmakta ve buda programcılara bunalımlardan bunalım beğendirmektedir. İşte
bu ihtiyaç, Durum Yönetimi (State Management) olgusunun ortaya çıkmasının sebebi
olmuştur. Sayfa veya tüm uygulama bazında verileri saklamak için ASP.NET çatısı
altında bize sunulan teknolojiler işte şunlardır:
Durum Yönetimine Genel Bakış
|
-View State
-Control State
-Hidden Form Fields
-Cookies
-Query String
-Application State
-Session State
|
Biz makalemizin konusuna geri dönerek View State kavramının anlamına bir bakalım.
ViewState soyut olarak nedir?
ViewState (Görüntü Durumu), verileri saklamak için default olarak kullanılan
tekniktir. Sayfa post back olduğunda ve geri geldiğinde aynı sayfadaki
değerlerin saklanması işlemini ViewState yapar. Kısacası sayfanın tarayıcıdan
dönerkenki haline ulaşabilmemizi ve sayfa geri gönderilirken otomatikman tekrar
bu bilgilerle gitmesini sağlar. Dolayısıyla sayfalar arası veri taşımaz. ViewState 2 türlü kullanılır.
İlki ASP.NET tarafından otomatik olarak yönetilmesidir. Kapatılmadığı sürece
arkada çalışmaya devam eder. İkincisi ise kod kısmında koleksiyon olarak
kullanılmasıdır. Peki ViewState nasıl çalışır? ASP.NET arka tarafta gizli bir input kontrolü
yaratır. Bu input kontrolünün içinde, sayfadaki istenilen kontrollerin bazı propertylerini
base64 koduna çevirerek saklar.
Bu gizlenmiş ViewState kontrolü sayfayla birlikte yaşar ve seyahat eder.
Dolayısıyla eğer dikkatli ve kontrollü olarak kullanılmassa, View State
kontrolümüz gittikçe şişer ve ciddi performans sıkıntılarına sebep olur. Üstelik
aspx sayfamızın içinde bulunan bir kontrol olduğu için hem post back hem de
request süresini uzatır.
Bu kadar teorik bilginin ardından View State kavramına biraz da pratik olarak
bakalım
ViewState somut olarak nedir?
Basit bir web uygulaması açalım. İçersinde hiç bir değişiklik yapmadan debug edip,
kaynak kodunu açtığımızda şu html çıktısı ile karşılaşırız;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
Untitled Page
</title></head>
<body>
<form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUJNzgzNDMwNTMzZGRKSpuLejDHB6P+RKbZyCauWTRAqA==" />
</div>
<div>
</div>
</form>
</body>
</html> |
Burada görüldüğü üzere ASP.NET bizim için kendiliğinden bu gizli kontrolü
oluşturmaktadır. Value özelliğine baktığımızda ise sayfadaki bazı bilgilerin
kodlanmış hali görülmektedir.
Şimdide kısa bir örnekle ViewState nerelerde kullanılabilir ona bakalım.
Öncelikle yeni web projesi açıp içine bir adet DropDownList ve bir adette Button
nesnesi ekleyelim. Senaryomuz gereği, Button nesnemize basıldığında DropDownList
içindeki nesneler ters sırayla yazılmalıdır (yada kısaca Reverse() metodu
çalıştırılmalıdır);
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DropDownList1.Items.Add("CSharp");
DropDownList1.Items.Add("Nedir");
DropDownList1.Items.Add(".com");
}
}
protected void btnSirala_Click(object sender, EventArgs e)
{
ArrayList ary = new ArrayList();
ary.AddRange(DropDownList1.Items);
ary.Reverse();
DropDownList1.Items.Clear();
foreach (object obj in ary)
{
DropDownList1.Items.Add(obj.ToString());
}
} |
Yukarıdaki kod çalıştırıldığında hiç bir sorun çıkmaycaktır. Çünkü ViewState
bizin için herşeyi yapmıştır. Sayfa post back olduğunda !Page.IsPostBack
olmasına rağmen DropDownList1 boş gelmemiştir. Bir de ViewState'i kapatarak bu programı
çalıştıralım;
<asp:DropDownList ID="DropDownList1" runat="server"
EnableViewState="false" > |
ViewState kapatıldığında ise düğmeye basıldıktan sonra dropDownList1 boş
gelecektir. Sebebi çok aşikardır. Sayfa post back olunca tüm html kontrolleri
sunucuda yeniden hazırlanıp gönderilmiştir. !Page.IsPostBack deyimi de olduğu
için DropDownList'imizin items koleksiyonu boş kalmıştır. Peki
!Page.IsPostBack'in kaldırılması çözüm olacak mıdır? Hayır, bu seferde
dropDownList1'e her seferinde aynı liste baştan eklenecek dolayısıyla Reverse
metodu istediği kadar çalıştırılsın devamlı ".com, Nedir, Csharp" şeklinde
sıralama olacaktır. Senaryomuzu farklı bir şekilde kurgulayalım. Datalarımızın
çok fazla olduğunu ve bir veritabanından çekilmesi gerektiğini düşünelim.
ViewState olmadığı takdirde her Page_Load olayında veri çekme işleminin
yapılması gerekir. Bu da Request süresini hep uzatmaktadır. Tabi eğer çekilecek
verilerin boyutları büyük ise bu seferde ViewState çok şişecek ve bize faydadan
çok zararı olacaktır. Bu gibi durmlarda da ViewState kapatılmalıdır.
Şimdide kod tarafında ViewState ile nasıl oynayabiliriz ona bakalım. Buradaki
senaryomuzda Bir ListBox kontrolü içine istediğimiz kelimeleri ekleyip
çıkartalım:
|
Kod kısmımız ise şöyledir;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnEkle_Click(object sender, EventArgs e)
{
ViewState.Add(txtEkle.Text.ToString(), txtEkle.Text);
//ViewState kontrolümüze dışarıdan bir nesne eklenmeye çalışıldığı zaman
aynı Hashtable gibi çalışır. Bizden bir 'Key' birde 'Value' değeri ister.
Hashtable'dan farklı olarak 'Key' değerini string olarak alır.'Value'
değerini ise object olarak aldıktan sonra StateItem tipine cast eder. Artık
eklendikten sonra bu verilere, istenildiği kadar post back yapılsın, ne zaman
arzu edilirse 'Key' değeri üzerinden ulaşılabilir.
Tazele();
}
protected void btnCikar_Click(object sender, EventArgs e)
{
ViewState.Remove(txtCikar.Text.ToString());
//Remove metodu ise sadece key değeri üzerinden işlem yapmaktadır.
Tazele();
}
private void Tazele()
{
//ListBox1.Items.Clear(); Normalde bu metodu yazmadığımız takdirde
ListBox nesnemiz içeriğini ViewState vasıtasıyla taşımaya devam eder. Bu da
verilerin birikmesine sebep olmaktadır. Dolayısıyla html tarafında ListBox'ın
ViewState özelliğini kapatarak hem bu satırı yazmaktan kurtuluruz, hem de
ViewState'i daha az yorarız. Burdan da şu anlaşılmaktadır; Biz kod tarafında
herhangi bir kontrolün Items.Clear() metodunu çalıştırdığımız zaman
ViewState'ten o kontrole ait nesneler kaldırılmaktadır.
foreach (StateItem sti in ViewState.Values)
{
ListBox1.Items.Add(sti.Value.ToString());
}
} |
|
ASP.NET bizim girdiğimiz StateItem nesneleri ile kendi yarattığı StateItem
nesnelerini ViewState içerisinde ayrı ayrı saklamaktadır. Dolayısıyla kod
tarafında ViewState'ten sadece kendimizin 'Key' değeri girerek oluşturduğu
verilere ulaşabilirz. |
Peki bu nesne arka tarafta nasıl çalışmaktadır, bir de ona bakalım. Öncelikle C#
tarafında ViewState yazıp 'Go To Definiton' dersek karşımıza şu sonuç
çıkmaktadır:
public class Control : IComponent, IDisposable, IParserAccessor,...
{
...
protected virtual StateBag ViewState { get; }
...
}
|
Görüldüğü üzere ViewState aslında, Control sınıfı altında, StateBag isimli bir
sınıfın tipinden, get bloğu olan bir
özelliktir. Bir de StateBag üzerinden 'Go To Definiton' yaparsak;
public sealed class StateBag : IStateManager, IDictionary, ICollection,
IEnumerable
{
public StateBag();
public StateBag(bool ignoreCase);
public int Count { get; }
public ICollection Keys { get; }
public ICollection Values { get; }
public object this[string key] { get; set; }
public StateItem Add(string key, object value);
public void Clear();
public IDictionaryEnumerator GetEnumerator();
public bool IsItemDirty(string key);
public void Remove(string key);
public void SetDirty(bool dirty);
public void SetItemDirty(string key, bool dirty);
}
|
StateBag sınıfının türediği arayüzlerden ilki State Management için kullanılan
temel arayüzdür. Son üç arayüz ise bakın hangi sınıflarda da vardır;
public class Hashtable : IDictionary, ICollection, IEnumerable ...
public class SortedList : IDictionary, ICollection, IEnumerable ... |
Burada ViewState'in Hashtable yapısına benzerliğinin sebebi
anlaşılmaktadır. Hatta kullanımları bile çok benzerdir.
ViewState ve Hashtable'ın kullanımlarını karşılaştırırsak:
ViewState Kullanımı
|
Hashtable Kullanımı
|
for (int i = 0; i < 10; i++)
{
ViewState[i.ToString()] = i;
} |
Hashtable ht = new Hashtable();
for (int i = 0; i < 10; i++)
{
ht[i] = i;
} |
Üstteki iki kontrol arasında dört adet fark vardır:
1- ViewState 'Key' değer olarak string alırken, Hashtable object almaktadır.
2- ViewState 'Value' değerini StateItem, Hashtable ise object tipine çevirir.
3- Hashtable 'Key' değerlerini unique olarak istemektedir ve aynı olursa hata
vermektedir. ViewState ise aynı 'Key' değeri olduğu durumlarda en son ekleneni
alır.
4- Hashtable bir sınıf olduğundan ilk başta örneklenmesi gerekir. Fakat View
State virtual olmasından dolayı bizim tarafımızdan örneklenemez. Eğer böyle bir
yapıya sahip olsaydı sayfa her post back olduğunda içindeki değerler
sıfırlanırdı. Sonuç olarak View State, kapalı veya açık olsun, her
sayfada mutlaka debug sırasında bir adet örneklenir ve html kodları arasına
yerleştirilir. Daima bir tane olmasının sebebi ise bazı kontrollerin ViewState'e
ihtiyaç duymasıdır.
ViewState'in yüklenmesi ve kaydedilmesi
ASP.NET, sayfadan gelen ViewState'in içeriğindeki veriyi almak
için LoadViewState, ViewState'e yeniden düzenlenmiş veriyi kaydetmek içinse
SaveViewState metodunu kullanmaktadır. Bu iki metod framework tarafından
otomatikman kullanıldığı gibi bizim tarafımızdan da istediğimiz yerde
yazılabilir. ASP.NET bu metodları yaşam döngüsünde şu aralarda çalıştırmaktadır:
-Initialize
-TrackViewState() :'Bu metoda az aşağıda değinilmektedir.'
-LoadViewState()
-Process postback data
-Load
-Send postback change notifications
-Handle postback events
-Prerender
-SaveViewState()
-Render
-Dispose
-Unload |
ViewState hakkında yanlış bir izlenim olabilir. ViewState kontrollerin sadece
text veya koleksiyonlarını değil hemen hemen tüm özelliklerin saklayabilir.
Örnek vermek gerekirse, aspx sayfamıza bir Label ve birden fazla Button kontrolü ekleyelim.
Her bir düğmede Label'ın bir özelliğini değiştirelim.
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "Çarşı .Net'e karşı";
}
protected void Button2_Click(object sender, EventArgs e)
{
Label1.BackColor = Color.Red;
}
protected void Button3_Click(object sender, EventArgs e)
{
Label1.CssClass = "style1";
} |
Her düğmeye basıldığında Label'ın değişen özelliği ViewState'e
eklencektir.
Başlangıçta sayfamız bu haldedir:
Button1’e basıldığında:
Button2’ye basıldığında:
Button3’e basıldığında:
Küçük bir tüyo vermek de gerekirse ViewState'inizin
boyutuna şu javascript kodunu yazarak bakabilirsiniz:
<script type="text/javascript">
var size = document.getElementById("__VIEWSTATE").value.length;
document.write(size+"bytes");
</script>
|
ViewState’i takip etmek: ViewState sakladığı
verilerin her birine ekstra olark bir de 'dirty' özelliği ekler. Bu dirty
özelliği o StateItem'ın değişip değişmediğini belirtir.
SaveViewState metodu sırasında eğer dirty özelliği false ise ViewState'e
kaydedilmez, eğer true ise kaydedilir. Ayrıca ViewState bu
dirty özelliğini takip etmeden önce TrackViewState metodunu çalıştırır.
TrackViewState metodu Page_Init zamanında çalışır ve SaveViewState metodu
çalışana kadar çalışmaya devam eder. ViewState'e yeni bir item kod tarafından
eklensede SaveViewState metodu çalışmadan ViewState'e kaydedilmez. Şöyle bir
örnekle olayı aydınlatalım:
Sayfamıza bir DropDownList ve iki adet Button nesnesi ekleyelim. Button
nesnelerinin görevi ViewState'e ekliyeceğimiz nesnenin dirty özelliğine true
veya false atamaktır.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ViewState["key"] = "value";
}
}
protected void Button1_Click(object sender, EventArgs e)
{
ViewState.SetItemDirty("key", true);
DropDownList1.Items.Clear();
foreach (StateItem sti in ViewState.Values)
{
DropDownList1.Items.Add(sti.Value.ToString());
}
}
protected void Button2_Click(object sender, EventArgs e)
{
ViewState.SetItemDirty("key", false);
DropDownList1.Items.Clear();
foreach (StateItem sti in ViewState.Values)
{
DropDownList1.Items.Add(sti.Value.ToString());
}
}
|
Bu kod çalıştırıldığında şöyle bir sonuç olmaktadır.
DropDownList'e 'value' muhakkak bir kez eklenmektedir. Eğer TRUE düğmesine
basarsak eklenmeye devam eder. Fakat FALSE düğmesine basıldığı anda son bir kez
daha eklenir sonra silinir. Daha sonra TRUE'ya basılsa bile artık bu StateItem
ViewState'ten kaldırıldığı için bir daha ulaşılamaz.
Buradan şu sonuç çıkmaktadır. Biz ViewState["key"]=value; kodunu yazdığımız anda ViewState’e bu veri eklenmek için SaveViewState metodunu bekler ve ’dirty’ özelliği ne olursa olsun eklenir.
Fakat eğer bu veri ViewState’e sadece bir kez ekleniyorsa, (Yukarıdaki
!Page.IsPostBack metodu içerisinde olduğu anlar gibi) ’dirty’ özelliği, true olana kadar taşınmaya devam eder ama false ise son bir kez taşınıp daha sonrasında silinir. ViewState.Remove()
metodu ise hiç ViewState’e eklemeden siler.
-ChildControls ve TrackViewState: Eğer
sayfaya bir kontrolü dinamik olarak ekliyorsak şu duruma dikkat etmemiz gerekir.
Kontroller dinamik olarak eklendiği zaman TrackViewState metodu, kontrolü sadece formun
Add() metodu çalıştırıldıktan sonra etkilemeye başlar. Dolayısıyla Add metodu,
dolaylı olarak da TrackViewState metodu çalıştırılmadan önce yazılan veriler
kontrole eklenir fakat ViewState'e eklenmez:
protected void Page_Load(object sender, EventArgs e)
{
DropDownList drpList = new DropDownList();
if (!Page.IsPostBack)
{
for (int i = 0; i < 10; i++)
{
drpList.Items.Add(i.ToString());
}
}
this.form1.Controls.Add(drpList);//Bu durumda
TrackViewState metodu burada çalıştırılır. Dolayısıyla veriler ViewState'e
eklenmez sadece kontrole bir kereye mahsus olmak üzere eklenir. Postback
olduğunda DropDown boş gelir.
}
//Bunun yerine Kontrolü önce forma ekleyip sonra verileri bağlamak daha
sağlıklı olur.
protected void Page_Load(object sender, EventArgs e)
{
DropDownList drpList = new DropDownList();
this.form1.Controls.Add(drpList);//Artık
TrackViewState metodu buradan itibaren çalışmaya başlıyacaktır ve veriler hem
DropDown'a hemde ViewState'e eklenecektir.
if (!Page.IsPostBack)
{
for (int i = 0; i < 10; i++)
{
drpList.Items.Add(i.ToString());
}
}
} |
ViewState'te güvenlik
ViewState bilindiği üzere değerleri base64 kodlarına
çevirmektedir. Şunu söylemek gerekir ki base64 kodları şifreli değildir ve
kırılması çok basittir. ViewState'in diğer kötü yanlarından biri de
bir html nesnesi olmasından dolayı herkes tarafından görülebilmesidir. Bu iki
etken bir araya gelince veri güvenliği diye bir kavram kalmamaktadır. İşte
değerli verilerimizi ViewState ile taşıdığımız anlarda yardımımıza ViewStateMac koşmaktadır.
ViewStateMac: EnableViewState özelliği ile
EnableViewStateMac özelliği karıştırılmamalıdır. ViewStateMac(ViewState Machine
Authentication Check) güvenlik amaçlı konulmuş bir özelliktir. ViewState
üzerindeki orjinal datanın bozulmasına yönelik herhangi bir saldırı olup
olmadığını kontrol eder ve verileri base64 yerine hash koduna çevirir. Default olarak açıktır ve ViewState özelliğinin olduğu
heryerde bu özellikde vardır. ViewStateMac, sayfa tarayıcıya giderken verileri
hash kodundan geçirir ve post back olduğunda gelen verilerle daha önceden
oluşturduğu hash kodunu karşılaştırır. Bunun için küçük bir test yapalım. Boş
bir web sayfası açıp <%@ Page %> kısmına EnableViewStateMac="false"
özelliğini ekleyelim. Ardından debug edip sayfanın kaynak koduna bakalım.
ViewState'in value değeri şu 24 haneli string çıkmıştır:
"/wEPDwUJNzgzNDMwNTMzZGQ=" . Şimdide ViewStateMac'i aktif hale getirelim. Bu
sefer value değerimiz 52 hanelidir: "/wEPDwUJNzgzNDMwNTMzZGTOg2Hi9CvgCScuhB5ASVZPIeJCsw=="
. Bunun sebebi ViewStateMac açıldığından değerlerin hash koduna çevrilmesidir.
Bu işlem verilerin değiştirilmesini çok zorlaştırır fakat diğer yandan da sayfanın boyutunu da
arttırmaktadır.
ASP.NET’in kullandığı hash kodu standartlarına bakmadan önce web.config dosyasını kısaca bir hatırlayalım:
|
machine.config aynı web.config dosyası gibi xml tabanlı bir dosya olup o
sunucuda bulunan tüm siteleri etkiler. ASP.NET'te özellikler aşağıdaki
hiyerarşiye göre belirlenir:
1- Makine bazında: machine.config
2- Site bazında: web.config
3- Sayfa bazında: <%@ Page %>
4- Kontrol bazında.
Fakat üstünlük bakımından ise bu sıra tam tersidir. ASP.NET, özellikleri önce
<%@ Page %> takısından kontrol etmeye başlar. Yani <%@ Page %> web.config'den,
web.config'de machine.config'den daha önceliklilidir.
*machine.config dosyasına ulaşmak için ise şu path izlenir:
WINDOWS\Microsoft.NET\Framework\Framework sürümü\CONFIG\machine.config
|
Hash Kodları: ASP.NET default olarak SHA1'ı
kullanmaktadır. Eğer bu standart değiştirilmek istenirse web.config dosyasına
başvurulması gerekir:
<configuration>
<system.web>
<machineKey validation="SHA1" /> |
Bu validation özelliği altındaki diğer hash algoritmaları ve
anahtar büyüklükleri şunlardır:
-AES (Advanced Encryption Standart): 128, 192 veya 256 bit
-3DES (Triple Data Encryption Standart): 56x3 bit
-SHA1 (Secured Hashing Algrotihm 1): 160 bit
-MD5 (Message-Digest algorithm 5): 128 bit
Anahtar büyüklüğündeki
Bit boyutunun artmasıyla doğru orantılı olarak kodun kırılma zorluğu da artar.
SHA1 ve MD5: Bu iki algoritma şifreleme
yapmazlar. Şifreli
olmamaları yanlış anlaşılmamalıdır. Bu tamamen açık oldukları anlamına gelmez,
sadece ileri düzey hash kodlarından geçirilmediğini gösterir. Fakat bugün brute force saldırılarıyla kırılabilmektedirler. SHA1, MD5'a göre
daha fazla yer tutar ve daha yavaş çalışır fakat daha güvenlidir.
- Tamper Proofing (Kırılmaya dayanıklı):
ViewState'imizi eğer orta derecede güvenlik altına almak istiyorsak öncelikle
EnableViewStateMac özelliğine true atamamız gerekir. Daha sonrasında ise
machine.config dosyasına şu özellikler yazılmalıdır:
<configuration>
<system.web>
<machineKey
validationKey="AutoGenerate,IsolateApps"
validation="SHA1" />
'veya MD5' |
ViewStateMac, ValidationKey değerini taşınan veriyi doğrulamak için kullanır.
Buradaki AutoGenerate framework'ün bizim için rastgele bir anahtar değeri
belirlemesini sağlar. Eğer sitemiz bir web farm üzerindeyse kendimizin bir değer vermesi
gerekir ve bu özellik hexadecimal
sayıları kabul etmektedir. O zaman ise validationKey şöyle bir görüntü almalıdır: validationKey="21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75D7AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B"
IsolateApps ise sunucuda bulunan her bir site için farklı bir id belirleyerek bu
anahtar değerlerini birbirinden soyutlar. validationKey ile aynı şekilde çalışan bir de
decryptionKey vardır. Bu özellik ise şifreleme yapılırken kontrol etmek için bir
anahtar değer üretir.
AES ve 3DES: Bu algoritmalar ise verileri
şifrelerler. Kırılmaları çok zordur ve maliyetlidir. AES, 3DES'e göre çok yeni
bir standarttır. Dolayısıyla 2.0 ile birlikte eklenmiştir ve 3DES'e göre çok
daha güvenlidir. 3DES'in yaptığı iş verileri 56 bitlik anahtar büyüklüğündeki
hash kodundan 3 kere geçirmesidir. AES ise 3 ayrı anahtar değerine sahiptir.
- Encryption (Şifreleme): ViewState'in şifrelenmesi için bir kaç ayar vardır.
İlk başta ViewStateMac açılmalıdır. Daha sonrasında web.config'e veya <%@
PAGE &>'e şu özellik eklenir:
...
<system.web>
<pages viewStateEncryptionMode="Always"></pages>
... |
Eğer her sayfanın şifrelenmesini istemiyorsanız ve bu işi framework’e emanet etmek istiyorsanız
şifreleme modunu ’Auto’ yapabilirsiniz. Bu işlemin ardından kod kısmına şu satır eklenmelidir:
Page.RegisterRequiresViewStateEncryption();
|
Son olarakta machine.config kısmında şu özellikleri
belirleriz:
<configuration>
<system.web>
<machineKey
validationKey="AutoGenerate,IsolateApps"
decryptionKey="AutoGenerate,IsolateApps"
validation="AES"
'veya 3DES'
decryption="Auto 'Bu özellik şifrelenmiş veriyi
hangi standartla çözüceğimizi belirtmemizi sağlar. Özel bir durum olmadıkça Auto
olarak ayarlanmalıdır. '/> |
Bu işlemlerin ardından artık ViewState’imiz daha korunaklı bir hale getirilmiştir.
dipnot: Eğer siteniz bir web farm vasıtasıyla çalışmıyor
ise bu özellikleri kullanınız.
View State'ten faydalanmamak
Her ne kadar bir çok yerden kolaylık sağlasada, bazı
durumlarda, özellikle boyutunun çok büyüdüğü anlarda ViewState'in kapatılması
gerekebilir. ViewState şu yöntemler kullanılarak kapatılabilir.
1- Kontrol bazında; |
<asp:TextBox ID="TextBox1" runat="server" EnableViewState="false"></asp:TextBox> |
2- Sayfa bazında; |
<%@ Page Language="C#"
AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"
EnableViewState="false" %> |
3- Tüm sitede ViewState özelliğinin kapatılması için ise web.config
dosyasının içine şu kod yazılır; |
...
<system.web>
<pages enableViewState="false"></pages>
... |
Her ne kadar ViewState web.config'den bile kapatılsa, gizli
input kontrolümüz hala sayfada yerini korumaktadır. Bu kontrolü kaldırmanın bir
yolu yoktur. Fakat şu iki metod override edilerek ViewState etkisiz hale
getirilebilir.
protected override void SavePageStateToPersistenceMedium(object viewState)
{
}
protected override object LoadPageStateFromPersistenceMedium()
{
return null;
} |
ViewState'in bölünmesi (ViewStateChunking)
ViewState'in çok büyüdüğü anlarda karşılaşılan sorunlardan
biri de bazı firewall ve proxy'lerin bu olgunlaşmış ViewState'leri kabul
etmemesidir. Bu zorluğun atlatılması kolaydır. Tek yapmamız gereken web.config
dosyası içine şu satırı yazmaktır:
<configuration>
<system.web>
<pages maxPageStateFieldLength=""></pages> |
maxPageStateFieldLength özelliği, ViewState'in uzunluğuna
bir sınır koymamızı sağlar. Eğer atanacak değerin uzunluğu buradaki değerden
fazlaysa, ViewState bölünmeye başlar. Bu özelliğin default değeri '-1' olup,
bölünme olmayacağı anlamına gelir. Test etmek için maxPageStateFieldLength
özelliğine 100
değerini verip, bir DropDownList'e 1'dan 10'a kadar olan sayıları ekleyelim.
Kaynak kodumuzun görüntüsü şöyle olacaktır:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
Untitled Page
</title></head>
<body>
<form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden"
name="__VIEWSTATEFIELDCOUNT" id="__VIEWSTATEFIELDCOUNT"
value="3" />
<input type="hidden"
name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKMTYxMTc1NjI2MA9kFgICAw9kFgICAQ8QZA8WCmYCAQICAgMCBAIFAgYCBwIIAgkWChAFATEFATFnEAUBMgUBMmcQBQEz"
/>
<input type="hidden"
name="__VIEWSTATE1" id="__VIEWSTATE1"
value="BQEzZxAFATQFATRnEAUBNQUBNWcQBQE2BQE2ZxAFATcFATdnEAUBOAUBOGcQBQE5BQE5ZxAFAjEwBQIxMGdkZGT//mlq/vcPuLOi"
/>
<input type="hidden"
name="__VIEWSTATE2" id="__VIEWSTATE2" value="A2O9kXAuaxuGhw==" />
</div>
<div>
<select name="DropDownList1" id="DropDownList1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
</div>
... |
Toplam ViewState'e atanacak boyut 216 byte olmuş ve ASP.NET
bunu 100 byte'lık 3 parçaya bölmüştür. Ayrıca ViewState'lerin sayısını tutmak
için ise __VİEWSTATEFIELDCOUNT isimli farklı bir gizli input nesnesi de sayfayla
birlikte gönderilmiştir.
Bu makale umarım size çok faydalı olmuştur ve ViewState ile ilgili soru işaretlerini minimuma indirmiştir. Herkese bol ViewState’li siteler.
Serkan YAZICIOĞLU
[email protected]
Kaynaklar:
http://msdn2.microsoft.com/en-us/library/ms998288.aspx
http://weblogs.asp.net/ngur/archive/2004/03/08/85876.aspx
http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
Makale:
Her Yönüyle ViewState Kavramı ASP.NET Serkan Yazıcıoğlu
|
|
|
-
-
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
|
|
|