2. ASP.NET'e kısa bir giriş
Burada, belgenin ilerleyen bölümlerinde bize faydalı olacak ASP.NET kavramlarını birkaç örnek yardımıyla tanıtmayı amaçlıyoruz. Bu giriş, bir web uygulamasındaki istemci/sunucu iletişiminin inceliklerini anlamaya yetmez. Bunun için şu kaynakları okuyabilirsiniz:
- ASP.NET Programlama [ASP.NET 1.1 ile Web Geliştirme (2004)]
Bu giriş bölümü, ilk etapta önemli olabilecek bazı noktaları bir kenara bırakmayı kabul ederek hızlı bir şekilde ilerlemek isteyenler için hazırlanmıştır. Belgenin devamında bu konular daha ayrıntılı olarak ele alınacaktır. ASP.NET'i bilenler doğrudan 3. paragrafa geçebilirler.
2.1. Örnek bir proje
2.1.1. Projenin oluşturulması
![]() |
- [1]'te, Visual Web Developer ile yeni bir proje oluşturulur
- [2]'te, Visual C# ile bir web projesi seçiyoruz
- [3]'te, bir web uygulaması oluşturmak istediğimizi belirtiriz ASP.NET
- [4]'te, uygulamaya bir ad verilir. Bu adla proje için bir klasör oluşturulur.
- [5] adımında, projenin [4] klasörünün üst klasörünü belirtin
![]() |
- [6] adımında, proje oluşturulur
- [Default.aspx], varsayılan olarak oluşturulan bir web sayfasıdır. Bu sayfa, HTML etiketlerini ve ASP.NET etiketlerini içerir
- [Default.aspx.cs], tarayıcısında görüntülenen [Defaul.aspx] sayfasında kullanıcı tarafından tetiklenen olayların yönetim kodunu içerir
- [Default.aspx.designer.cs], [Default.aspx] sayfasındaki ASP.NET bileşenlerinin listesini içerir. [Default.aspx] sayfasına yerleştirilen her bir ASP.NET bileşeni, [Default.aspx.designer.cs] dosyasında bu bileşenin tanımlanmasına yol açar.
- [Web.config], ASP.NET projesinin yapılandırma dosyasıdır.
- [References], web projesi tarafından kullanılan DLL dosyalarının listesidir. Bu DLL dosyaları, projenin kullanacağı sınıf kütüphaneleridir. [7] dosyasında ise proje referanslarına varsayılan olarak eklenen DLL dosyalarının listesi bulunur. Bunların çoğu gereksizdir. Projenin [7]'te listelenmeyen bir DLL'i kullanması gerekiyorsa, bu kütüphane [8] ile eklenebilir.
2.1.2. [Default.aspx] sayfası
Proje [Ctrl-F5] ile çalıştırıldığında, [Default.aspx] sayfası bir tarayıcıda görüntülenir:
![]() |
- [1]'te, web projesinin URL sayfası görüntülenir. Visual Web Developer, bir projenin çalıştırılması istendiğinde başlatılan yerleşik bir web sunucusuna sahiptir. Bu sunucu rastgele bir bağlantı noktasında dinleme yapar; burada 1490 numaralı bağlantı noktasıdır. Dinleme bağlantı noktası genellikle 80'dir. [1] adresinde herhangi bir sayfa talep edilmez. Bu durumda, [Default.aspx] sayfası görüntülenir; bu nedenle bu sayfaya "varsayılan sayfa" adı verilmiştir.
- [2]'te, [Default.aspx] sayfası boştur.
- Visual Web Developer'da, [Default.aspx] sayfası, [3] sayfası görsel olarak ([Design] sekmesi) veya etiketler kullanılarak ([Source] sekmesi) oluşturulabilir
- [4]'te, [Defaul.aspx] sayfası [Design] modunda oluşturulur. Bu sayfa, [5] araç kutusunda bulunan bileşenleri sayfanın üzerine sürükleyip bırakarak oluşturulur.
![]() |
[Source] [6] modu, sayfanın kaynak koduna erişim sağlar:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Intro._Default" %>
<!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 runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
- 1. satır, sayfanın belirli özelliklerini listeleyen bir ASP.NET yönergesidir
- Page yönergesi bir web sayfasına uygulanır. Application, WebService gibi diğer nesnelere uygulanan başka yönergeler de vardır ASP.NET
- CodeBehind özniteliği, sayfanın olaylarını yöneten dosyayı belirtir
- Language özniteliği, CodeBehind dosyası tarafından kullanılan .NET dilini belirtir
- Inherits özniteliği, CodeBehind dosyası içinde tanımlanan sınıfın adını belirtir
- AutoEventWireUp="true" özniteliği, [Default.aspx]'teki bir olay ile [Defaul.aspx.cs]'teki işleyicisi arasındaki bağlantının olay adına göre yapıldığını belirtir. Böylece[Default.aspx] sayfasındaki Load olayı, Inherits özniteliği ile tanımlanan Intro._Default sınıfının Page_Load yöntemi tarafından işlenecektir.
- 4-14. satırlar, [Defaul.aspx] sayfasını etiketler kullanarak tanımlamaktadır:
- <body> veya <div> gibi klasik HTML etiketleri
- ASP.NET. Bunlar, runat="server" özniteliğine sahip etiketlerdir. ASP.NET etiketleri, sayfa istemciye gönderilmeden önce web sunucusu tarafından işlenir. Bu etiketler, HTML etiketlerine dönüştürülür. Dolayısıyla, istemci tarayıcısı artık ASP.NET etiketleri içermeyen standart bir HTML sayfası alır.
[Default.aspx] sayfası, kaynak kodundan doğrudan değiştirilebilir. Bu, bazen [Design] modunu kullanmaktan daha kolay olabilir. Kaynak kodu şu şekilde değiştiriyoruz:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Intro._Default" %>
<!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 runat="server">
<title>Introduction ASP.NET</title>
</head>
<body>
<h3>Introduction à ASP.NET</h3>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
- satırda, HTML <title> etiketini kullanarak sayfaya bir başlık veriyoruz. 9. satırda, sayfanın gövdesine (<body>) bir metin ekliyoruz. Projeyi çalıştırırsak (Ctrl-F5), tarayıcıda şu sonucu elde ederiz:
![]() |
2.1.3. [Default.aspx.designer.cs] ve [Default.aspx.cs] dosyaları
[Default.aspx.designer.cs] dosyası, [Defaul.aspx] sayfasının bileşenlerini tanımlar:
//------------------------------------------------------------------------------
// <otomatik olarak oluşturuldu>
// Bu kod bir araç tarafından oluşturulmuştur.
// Çalışma zamanı sürümü: 2.0.50727.3603
//
// Bu dosyada yapılan değişiklikler hatalı çalışmaya neden olabilir ve
// kod yeniden oluşturulursa kaybolacaktır.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Intro {
public partial class _Default {
/// <summary>
/// form1 kontrolü.
/// </summary>
/// <remarks>
/// Otomatik olarak oluşturulan alan.
/// Değiştirmek için, tasarımcı dosyasındaki alan bildirimini kod arkası dosyasına taşıyın.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
}
}
Bu dosyada, [Default.aspx] sayfasının bir tanımlayıcıya sahip ASP.NET bileşenlerinin listesi bulunur. Bunlar, [Default.aspx] etiketlerinden runat="server" ve id özniteliklerine sahip olanlara karşılık gelir. Dolayısıyla, yukarıdaki 23. satırdaki bileşen şu etikete karşılık gelir:
<form id="form1" runat="server">
etiketine karşılık gelir.
Geliştirici, [Default.aspx.designer.cs] dosyasıyla pek etkileşime girmez. Bununla birlikte, bu dosya belirli bir bileşenin sınıfını öğrenmek için yararlıdır. Aşağıda görüldüğü gibi, form1 bileşeni HtmlForm türündedir. Geliştirici, bu sınıfı inceleyerek özelliklerini ve yöntemlerini öğrenebilir. [Default.aspx] sayfasındaki bileşenler, [Default.aspx.cs] dosyasındaki sınıf tarafından kullanılır:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Intro
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
[Default.aspx.cs] ve [Default.aspx.designer.cs] dosyalarında tanımlanan sınıfın aynı olduğu (10. satır) dikkat çekmektedir: Intro._Default. Bir sınıf tanımının birden fazla dosyaya (burada iki dosyaya) yayılmasını mümkün kılan, partial anahtar sözcüğüdür.
Yukarıdaki 10. satırda, [_Default] sınıfının [Page] sınıfını genişlettiği ve onun olaylarını miras aldığı görülmektedir. Bunlardan biri, sayfa web sunucusu tarafından yüklendiğinde gerçekleşen Load olaydır. 12. satırda, sayfanın Load olayını yöneten Page_Load yöntemi yer almaktadır. Genellikle sayfa, istemcinin tarayıcısında görüntülenmeden önce burada başlatılır. Burada, Page_Load yöntemi hiçbir işlem yapmaz.
Bir web sayfasına ilişkin sınıf, burada Intro._Default sınıfı, istemcinin isteğinin başlangıcında oluşturulur ve istemciye yanıt gönderildiğinde yok edilir. Dolayısıyla, iki istek arasında bilgi depolamak için kullanılamaz. Bunun için kullanıcı oturumu kavramını kullanmak gerekir.
2.2. ASP.NET web sayfasındaki olaylar
Aşağıdaki [Default.aspx] sayfasını oluşturuyoruz:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Intro._Default" %>
<!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 runat="server">
<title>Introduction ASP.NET</title>
</head>
<body>
<h3>Introduction à ASP.NET</h3>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
Nom</td>
<td>
<asp:TextBox ID="TextBoxNom" runat="server"></asp:TextBox>
</td>
<td>
</td>
</tr>
<tr>
<td>
Age</td>
<td>
<asp:TextBox ID="TextBoxAge" runat="server"></asp:TextBox>
</td>
<td>
</td>
</tr>
</table>
</div>
<asp:Button ID="ButtonValider" runat="server" Text="Valider" />
<hr />
<p>
Evénements traités par le serveur</p>
<p>
<asp:ListBox ID="ListBoxEvts" runat="server"></asp:ListBox>
</p>
</form>
</body>
</html>
Sayfanın [Design] modu şu şekildedir:
![]() |
[Default.aspx.designer.cs] dosyası şu şekildedir:
namespace Intro {
public partial class _Default {
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
protected global::System.Web.UI.WebControls.TextBox TextBoxNom;
protected global::System.Web.UI.WebControls.TextBox TextBoxAge;
protected global::System.Web.UI.WebControls.Button ButtonValider;
protected global::System.Web.UI.WebControls.ListBox ListBoxEvts;
}
}
Burada, [Default.aspx] sayfasındaki tüm ASP.NET bileşenleri, bir tanımlayıcıyla birlikte yer almaktadır.
[Default.aspx.cs] dosyasını şu şekilde güncelliyoruz:
using System;
namespace Intro
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
// olay kaydedilir
ListBoxEvts.Items.Insert(0, string.Format("{0}: Page_Init", DateTime.Now.ToString("hh:mm:ss")));
}
protected void Page_Load(object sender, EventArgs e)
{
// olay kaydedilir
ListBoxEvts.Items.Insert(0, string.Format("{0}: Page_Load", DateTime.Now.ToString("hh:mm:ss")));
}
protected void ButtonValider_Click(object sender, EventArgs e)
{
// olay kaydedilir
ListBoxEvts.Items.Insert(0, string.Format("{0}: ButtonValider_Click", DateTime.Now.ToString("hh:mm:ss")));
}
}
}
[_Default] sınıfı (5. satır) üç olayı işler:
- sayfa başlatıldığında gerçekleşen Init olayı (7. satır)
- sayfa web sunucusu tarafından yüklendiğinde gerçekleşen Load olayı (satır 13). Init olayı, Load olayından önce gerçekleşir.
- Kullanıcı [Valider] düğmesine tıkladığında gerçekleşen ButtonValider düğmesi üzerindeki Click olayı (satır 19)
Bu üç olayın her birinin yönetimi, Listbox bileşenine ListBoxEvts adlı bir mesaj eklemekten ibarettir. Bu mesaj, olayın saatini ve adını gösterir. Her mesaj listenin başına yerleştirilir. Dolayısıyla listenin en üstünde yer alan mesajlar en yeni olanlardır.
Proje çalıştırıldığında aşağıdaki sayfa görüntülenir:
![]() |
[1]'te, Page_Init ve Page_Load olaylarının bu sırayla gerçekleştiği görülmektedir. En son olayın listenin en üstünde yer aldığı unutulmamalıdır. Tarayıcı, [Default.aspx] sayfasını doğrudan [2] URL’si üzerinden talep ettiğinde, bunu HTTP (HyperText Aktarım Protokolü) adlı GET komutunu kullanır. Sayfa tarayıcıya yüklendikten sonra, kullanıcı sayfada olaylar tetikleyecektir. Örneğin, [Valider] [3] düğmesine tıklayacaktır. Sayfa tarayıcıya yüklendikten sonra kullanıcı tarafından tetiklenen olaylar, [Default.aspx] sayfasına bir istek gönderir; ancak bu sefer HTTP komutu, POST olarak adlandırılır. Özetle:
- P sayfasının tarayıcıya ilk yüklenmesi, HTTP ve GET işlemleriyle gerçekleştirilir
- ardından sayfada meydana gelen olaylar, her seferinde aynı P sayfasına yeni bir istek oluşturur, ancak bu sefer HTTP POST komutuyla. Bir P sayfasının, kendisine GET komutuyla mı yoksa POST komutuyla mı çağrıldığını bilmesi mümkündür; bu da gerekirse farklı davranmasına olanak tanır ki çoğu zaman durum böyledir.
ASPX sayfasının ilk isteği: GET
![]() |
- [1]'e dönüştürüldüğünde, tarayıcı ASPX sayfasını, parametre içermeyen bir HTTP GET komutu aracılığıyla ister.
- [2] adresinde, web sunucusu yanıt olarak istenen ASPX sayfasının çevirisi olan HTML akışını gönderir.
Tarayıcı tarafından görüntülenen sayfada meydana gelen bir olayın işlenmesi: POST
![]() |
- [1]'e dönüştürülür; HTML sayfasında bir olay meydana geldiğinde, tarayıcı, daha önce GET işlemiyle alınmış olan ASPX sayfasını, bu sefer HTTP POST komutuyla ve parametreler eşliğinde talep eder. Bu parametreler, tarayıcı tarafından görüntülenen HTML sayfasındaki <form> etiketinin içinde bulunan bileşenlerin değerleridir. Bu değerlere, istemci tarafından gönderilen değerler denir. Bu değerler, istemcinin talebini işlemek üzere ASPX sayfası tarafından kullanılacaktır.
- [2] sayfasında, web sunucusu, yanıt olarak HTML akışını gönderir; bu akış, başlangıçta POST tarafından talep edilen ASPX sayfasının çevirisi ya da sayfa aktarımı veya yönlendirmesi durumunda başka bir sayfanın çevirisidir.
Örnek sayfamıza geri dönelim:
![]() |
- [2]'e dönüştürüldü; bu sayfa, bir GET aracılığıyla elde edildi.
- [1]'te, bu GET sırasında meydana gelen iki olay görülmektedir
Yukarıda, kullanıcı [Valider] [3] düğmesine tıklarsa, [Default.aspx] sayfası bir POST ile istenecektir. Bu POST isteği, [Default.aspx] sayfasındaki <form> etiketinde yer alan tüm bileşenlerin değerlerini içeren parametrelerle birlikte gönderilecektir: iki TextBox, [TextBoxNom, TextBoxAge], [ButtonValider] düğmesi ve [ListBoxEvts] listesi. Bileşenler için gönderilen değerler şunlardır:
- TextBox: girilen değer
- Button: Düğmenin metni; burada "Onayla" metni
- Listbox: ListBox'te seçilen mesaj metni
POST'e yanıt olarak [4] sayfası elde edilir. Bu, yine [Default.aspx] sayfasıdır. Sayfanın olay yöneticileri tarafından bir sayfa aktarımı veya yönlendirmesi olmadığı sürece bu normal bir davranıştır. İki yeni olayın meydana geldiği görülebilir:
- sayfa yüklenirken meydana gelen Page_Load olayı
- [Valider] düğmesine tıklanması sonucu oluşan ButtonValider_Click olayı
Şu hususlara dikkat edilebilir:
- Page_Init olayı, HTTP ve POST işlemlerinde gerçekleşmemiştir; oysaHTTP ve GET olaylarında gerçekleşmişti
- Page_Load olayı, ister GET ister POST olsun, her zaman gerçekleşir. Genellikle bu yöntemde, karşımızda bir GET mi yoksa bir POST mi olduğunu bilmemiz gerekir.
- POST'in işlenmesi tamamlandıktan sonra, olay yöneticileri tarafından yapılan değişikliklerle birlikte [Default.aspx] sayfası müşteriye geri gönderildi. Bu her zaman böyledir. Bir P sayfasındaki olaylar işlendikten sonra, aynı P sayfası müşteriye geri gönderilir. Bu kuraldan kaçınmanın iki yolu vardır. Yürütülen son olay işleyicisi,
- yürütme akışını başka bir P2 sayfasına aktarabilir.
- istemci tarayıcısını başka bir sayfaya (P2) yönlendirebilir.
Her iki durumda da tarayıcıya P2 sayfası gönderilir. Bu iki yöntem arasında bazı farklılıklar vardır; bunlara daha sonra değineceğiz.
- ButtonValider_Click olayı, Page_Load olayından sonra meydana geldi. Dolayısıyla, P2 sayfasına aktarım veya yönlendirme kararını bu işleyici verebilir.
- [4] olay listesi, [Default.aspx] sayfasının ilk yüklemesi sırasında (GET) görüntülenen iki olayı da muhafaza etmiştir. [Default.aspx] sayfasının POST sırasında yeniden oluşturulduğu bilindiğinde bu durum şaşırtıcıdır. Tasarım değerleriyle birlikte [Default.aspx] sayfasının bulunması ve dolayısıyla ListBox'in boş olması beklenirdi. Page_Load ve ButtonValider_Click işleyicilerinin çalıştırılmasıyla buraya iki mesaj eklenmesi gerekirdi. Oysa burada dört mesaj bulunuyor. Bunu açıklayan, VIEWSTATE işleyicisinin çalışma mekanizmasıdır. İlk GET işlemi sırasında, web sunucusu [Default.aspx] sayfasını, gizli alan olarak adlandırılan HTML <input type="hidden" ...> etiketiyle birlikte gönderir (aşağıdaki 10. satır).
"__VIEWSTATE" kimlik alanında, web sunucusu sayfanın tüm bileşenlerinin değerlerini kodlanmış biçime dönüştürür. Bunu hem başlangıçtaki GET hem de onu izleyen POST'ler için yapar. P sayfasında bir POST oluştuğunda:
- tarayıcı, isteğinde <form> etiketinin içindeki tüm bileşenlerin değerlerini göndererek P sayfasını ister. Yukarıda, "__VIEWSTATE" bileşeninin <form> etiketinin içinde olduğu görülebilir. Dolayısıyla, bir POST olayı sırasında bu bileşenin değeri sunucuya gönderilir.
- P sayfası, oluşturma değerleriyle örneklenir ve başlatılır
- "__VIEWSTATE" bileşeni, bileşenlere P sayfası daha önce gönderildiğinde sahip oldukları değerleri geri vermek için kullanılır. Örneğin, [4] olay listesi, tarayıcının ilk GET isteğine yanıt olarak gönderildiğinde sahip olduğu ilk iki mesajı bu şekilde geri alır.
- P sayfasının bileşenleri daha sonra tarayıcı tarafından gönderilen değerleri alır. Bu noktada, P sayfasındaki form, kullanıcının gönderdiği durumdadır.
- Page_Load olayı işlenir. Burada, [4] olay listesine bir mesaj eklenir.
- POST olayını tetikleyen olay işlenir. Burada ButtonValider_Click, [4] olay listesine bir mesaj ekler.
- P sayfası geri gönderilir. Bileşenlerin değerleri şunlardır:
- ya gönderilen değer, c.a.d. ya da bileşenin, sunucuya gönderildiğinde formda sahip olduğu değer
- ya da olay yöneticilerinden biri tarafından verilen bir değer.
Örneğimizde,
- iki bileşen de (TextBox) gönderildikleri değerlerine geri döner, çünkü olay yöneticileri bu bileşenlere müdahale etmez
- [4] olay listesi, gönderilen değerine, yani c.a.d'e geri döner. Listeye önceden eklenmiş tüm olaylar ile Page_Load ve ButtonValider_Click yöntemleriyle oluşturulan iki yeni olay.
VIEWSTATE mekanizması her bir bileşen düzeyinde etkinleştirilebilir veya devre dışı bırakılabilir. [ListBoxEvts] bileşeni için bunu devre dışı bırakalım:
![]() |
- [1]'te, [ListBoxEvts] bileşenine ait VIEWSTATE devre dışı bırakılmıştır. TextBox ve [2] bileşenlerine ait olanlar ise varsayılan olarak etkindir.
- [3]'te, ilk GET'ten sonra döndürülen iki olay
![]() |
- [4]'te, form dolduruldu ve [Valider] düğmesine tıklandı. POST'ten [Default.aspx] sayfasına bir yönlendirme yapılacaktır.
- [6]'te, [Valider] düğmesine tıklandıktan sonra geri gönderilen sonuç
- VIEWSTATE mekanizmasının etkinleştirilmesi, TextBox ve [7]'in [4]'te kaydedilen değerlerini korumasını açıklar
- VIEWSTATE mekanizmasının devre dışı bırakılması, [ListBoxEvts] ve [8] bileşenlerinin [5] içeriğini korumamış olmasını açıklar.
2.3. Gönderilen değerlerin yönetimi
Burada, kullanıcı [Valider] düğmesine tıkladığında iki TextBox tarafından gönderilen değerlere odaklanacağız. [Design] modundaki [Default.aspx] sayfası şu şekilde değişir:
![]() |
[1]'e eklenen öğenin kaynak kodu şöyledir:
<p>
Eléments postés au serveur :
<asp:Label ID="LabelPost" runat="server"></asp:Label>
</p>
[LabelPost] bileşenini, TextBox ve [2]'te girilen değerleri görüntülemek için kullanacağız. [Default.aspx.cs] olay işleyicisinin kodu şu şekilde değişir:
using System;
namespace Intro
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
// olay not edilir
ListBoxEvts.Items.Insert(0, string.Format("{0}: Page_Init", DateTime.Now.ToString("hh:mm:ss")));
}
protected void Page_Load(object sender, EventArgs e)
{
// etkinlik kaydedildi
ListBoxEvts.Items.Insert(0, string.Format("{0}: Page_Load", DateTime.Now.ToString("hh:mm:ss")));
}
protected void ButtonValider_Click(object sender, EventArgs e)
{
// etkinlik not edilir
ListBoxEvts.Items.Insert(0, string.Format("{0}: ButtonValider_Click", DateTime.Now.ToString("hh:mm:ss")));
// ad ve yaş görüntüleniyor
LabelPost.Text = string.Format("nom={0}, age={1}", TextBoxNom.Text.Trim(), TextBoxAge.Text.Trim());
}
}
}
- satırda, LabelPost bileşeni güncellenir:
- LabelPost, [System.Web.UI.WebControls.Label] türündedir (bkz. Default.aspx.designer.cs). Text özelliği, bileşen tarafından görüntülenen metni temsil eder.
- TextBoxNom ve TextBoxAge, [System.Web.UI.WebControls.TextBox] türündedir. TextBox bileşeninin Text özelliği, giriş alanında görüntülenen metindir.
- Trim() yöntemi, bir karakter dizisinin başında veya sonunda bulunabilecek boşlukları kaldırır
Daha önce açıklandığı gibi, ButtonValider_Click yöntemi çalıştırıldığında, sayfanın bileşenleri, sayfa kullanıcı tarafından gönderildiğinde sahip oldukları değere sahip olur. Dolayısıyla, her iki TextBox yönteminin Text özelliklerinin değeri, kullanıcının tarayıcıya girdiği metinlerdir.
İşte bir örnek:
![]() |
- [1]'te gönderilen değerler
- [2]'te, sunucunun yanıtı.
- [3]'te, TextBox'ler, etkinleştirilen VIEWSTATE mekanizması sayesinde gönderilen değerlerine geri döndü
- [4]'te, ListBoxEvts bileşeninin mesajları Page_Init, Page_Load, ButtonValider_Click yöntemlerinden ve devre dışı bırakılmış bir VIEWSTATE'ten kaynaklanmaktadır
- [5]'te, LabelPost bileşeni değerini ButtonValider_Click yöntemi aracılığıyla almıştır. Kullanıcı tarafından TextBox ve [1] bileşenlerine girilen iki değer de başarıyla alınmıştır.
Yukarıda görüldüğü gibi, yaş için gönderilen değer "yy" dizesidir; bu, geçersiz bir değerdir. Sayfaya "doğrulayıcı" adı verilen bileşenler ekleyeceğiz. Bunlar, gönderilen verilerin geçerliliğini kontrol etmek için kullanılır. Bu geçerlilik iki yerde kontrol edilebilir:
- istemci tarafında. Doğrulayıcının bir yapılandırma seçeneği, testlerin tarayıcıda yapılıp yapılmayacağını belirler. Bu durumda testler, HTML sayfasına gömülü olan JavaScript kodu tarafından gerçekleştirilir. Kullanıcı formda girilen değerleri POST ile gönderdiğinde, bu değerler öncelikle JavaScript kodu tarafından doğrulanır. Testlerden biri başarısız olursa, POST işlemi gerçekleştirilmez. Böylelikle sunucuyla gidip gelme işlemi önlenir ve sayfa daha hızlı yanıt verir.
- sunucuda. İstemci tarafındaki kontroller isteğe bağlı olabilse de, sunucu tarafında bu kontroller, istemci tarafında kontrol yapılmış olsun ya da olmasın zorunludur. Nitekim, bir sayfa gönderilen değerleri aldığında, bunların gönderilmeden önce istemci tarafından kontrol edilip edilmediğini bilemez. Bu nedenle sunucu tarafında, geliştirici gönderilen verilerin geçerliliğini her zaman kontrol etmelidir.
[Default.aspx] sayfası şu şekilde değişir:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Intro._Default" %>
<!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 runat="server">
<title>Introduction ASP.NET</title>
</head>
<body>
<h3>Introduction à ASP.NET</h3>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
Nom</td>
<td>
<asp:TextBox ID="TextBoxNom" runat="server"></asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorNom" runat="server"
ControlToValidate="TextBoxNom" Display="Dynamic"
ErrorMessage="Donnée obligatoire !"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
Age</td>
<td>
<asp:TextBox ID="TextBoxAge" runat="server"></asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorAge" runat="server"
ControlToValidate="TextBoxAge" Display="Dynamic"
ErrorMessage="Donnée obligatoire !"></asp:RequiredFieldValidator>
<asp:RangeValidator ID="RangeValidatorAge" runat="server"
ControlToValidate="TextBoxAge" Display="Dynamic"
ErrorMessage="Tapez un nombre entre 1 et 150 !" MaximumValue="150"
MinimumValue="1" Type="Integer"></asp:RangeValidator>
</td>
</tr>
</table>
</div>
<asp:Button ID="ButtonValider" runat="server" onclick="ButtonValider_Click"
Text="Valider" CausesValidation="False"/>
<hr />
<p>
Evénements traités par le serveur</p>
<p>
<asp:ListBox ID="ListBoxEvts" runat="server" EnableViewState="False">
</asp:ListBox>
</p>
<p>
Eléments postés au serveur :
<asp:Label ID="LabelPost" runat="server"></asp:Label>
</p>
<p>
Eléments validés par le serveur :
<asp:Label ID="LabelValidation" runat="server"></asp:Label>
</p>
<asp:Label ID="LabelErreursSaisie" runat="server" ForeColor="Red"></asp:Label>
</form>
</body>
</html>
20, 32 ve 35. satırlara doğrulama kodları eklenmiştir. 58. satırda, geçerli gönderilen değerleri görüntülemek için bir Label bileşeni kullanılmaktadır. 60. satırda, giriş hataları olması durumunda bir hata mesajı görüntülemek için Label bileşeni kullanılmaktadır.
[Design] modundaki [Default.aspx] sayfası aşağıdaki gibidir:
![]() |
- [1] ve [2] bileşenleri, RequiredFieldValidator türündedir. Bu doğrulayıcı, bir giriş alanının boş olup olmadığını kontrol eder.
- [3] bileşeni, RangeValidator türündedir. Bu doğrulayıcı, bir giriş alanının iki sınır değeri arasında bir değer içerip içermediğini kontrol eder.
- [4]'te, [1] doğrulayıcısının özellikleri yer almaktadır.
[Default.aspx] sayfasının kodundaki etiketleri aracılığıyla bu iki doğrulayıcı türünü tanıtacağız:
<asp:RequiredFieldValidator ID="RequiredFieldValidatorNom" runat="server"
ControlToValidate="TextBoxNom" Display="Dynamic"
ErrorMessage="Donnée obligatoire !"></asp:RequiredFieldValidator>
- ID: bileşenin kimliği
- ControlToValidate: değeri doğrulanacak bileşenin adı. Burada, TextBoxNom bileşeninin değerinin boş olmaması (boş dize veya boşluk dizisi) istenmektedir
- ErrorMessage: Geçersiz veri durumunda doğrulayıcıda görüntülenecek hata mesajı.
- EnableClientScript: Doğrulayıcının istemci tarafında da çalıştırılması gerekip gerekmediğini belirten boole değeri. Bu öznitelik, yukarıda açıkça belirtilmediği sürece varsayılan olarak True değerine sahiptir.
- Display: Doğrulayıcının görüntülenme modu. İki mod vardır:
- static (varsayılan): Doğrulayıcı, hata mesajı göstermese bile sayfada yer kaplar
- dynamic: Hata mesajı gösterilmediğinde, doğrulayıcı sayfada yer kaplamaz.
<asp:RangeValidator ID="RangeValidatorAge" runat="server"
ControlToValidate="TextBoxAge" Display="Dynamic"
ErrorMessage="Tapez un nombre entre 1 et 150 !" MaximumValue="150"
MinimumValue="1" Type="Integer"></asp:RangeValidator>
- Tür: Doğrulanmış verinin türü. Burada yaş bir tamsayıdır.
- MinimumValue, MaximumValue: Doğrulanacak değerin içinde bulunması gereken sınırlar
POST'i tetikleyen bileşenin yapılandırması, doğrulama yönteminde rol oynar. Burada bu bileşen, [Valider] düğmesidir:
<asp:Button ID="ButtonValider" runat="server" onclick="ButtonValider_Click" Text="Valider" CausesValidation="True" />
- CausesValidation: sunucu tarafındaki doğrulamaların otomatik modunu veya adını belirler. Bu öznitelik, açıkça belirtilmediği takdirde varsayılan olarak "True" değerine sahiptir. Bu durumda,
- istemci tarafında, EnableClientScript ile True arasındaki doğrulayıcılar çalıştırılır. POST, yalnızca tüm istemci tarafı doğrulayıcıları başarılı olursa gerçekleşir.
- sunucu tarafında, sayfada bulunan tüm doğrulayıcılar, POST'i tetikleyen olayın işlenmesinden önce otomatik olarak çalıştırılır. Burada, bunlar ButtonValider_Click yönteminin çalıştırılmasından önce çalıştırılır. Bu yöntemde, tüm doğrulamaların başarılı olup olmadığını öğrenmek mümkündür. Page.IsValid, tüm doğrulamalar başarılı olursa "True", aksi takdirde "False" değerini alır. İkinci durumda, POST'i tetikleyen olayın işlenmesi durdurulabilir. Gönderilen sayfa, girildiği haliyle geri döndürülür. Geçerlilik denetimlerinde başarısız olanlar, hata mesajlarını görüntüler (ErrorMessage özniteliği).
CausesValidation'in değeri False ise,
- istemci tarafında hiçbir doğrulayıcı çalıştırılmaz
- Sunucu tarafında, sayfanın doğrulayıcılarının çalıştırılmasını talep etmek geliştiricinin sorumluluğundadır. Bunu Page.Validate() yöntemi ile gerçekleştirir. Doğrulama sonuçlarına göre, bu yöntem Page.IsValid özelliğini "True" veya "False" olarak ayarlar.
[Default.aspx.cs]'te, ButtonValider_Click'in işleme kodu şu şekilde değişir:
protected void ButtonValider_Click(object sender, EventArgs e)
{
// olay kaydediliyor
ListBoxEvts.Items.Insert(0, string.Format("{0}: ButtonValider_Click", DateTime.Now.ToString("hh:mm:ss")));
// ad ve yaş görüntüleniyor
LabelPost.Text = string.Format("nom={0}, age={1}", TextBoxNom.Text.Trim(), TextBoxAge.Text.Trim());
// sayfa geçerli mi?
Page.Validate();
if (!Page.IsValid)
{
// genel hata mesajı
LabelErreursSaisie.Text = "Veuillez corriger les erreurs de saisie...";
LabelErreursSaisie.Visible = true;
return;
}
// hata mesajı gizlenir
LabelErreursSaisie.Visible = false;
// doğrulanmış isim ve yaş görüntülenir
LabelValidation.Text = string.Format("nom={0}, age={1}", TextBoxNom.Text.Trim(), TextBoxAge.Text.Trim());
}
[Valider] düğmesinin CausesValidation özniteliği True olarak ve doğrulayıcıların EnableClientScript özniteliği True olarak ayarlandığı durumda, ButtonValider_Click yöntemi yalnızca gönderilen değerler geçerli olduğunda yürütülür. O halde, 8. satırdan itibaren görülen kodun anlamı ne olabilir? [Default.aspx] sayfasına doğrulanmamış değerler gönderen bir istemci programı yazmanın her zaman mümkün olduğunu unutmamak gerekir. Dolayısıyla bu sayfa, geçerlilik testlerini her zaman yeniden yapmalıdır.
- 8. satır: Sayfadaki tüm geçerlilik denetleyicilerinin çalıştırılmasını başlatır. [Valider] düğmesinin CausesValidation özniteliği True olarak ayarlanmışsa, bu işlem otomatik olarak gerçekleştirilir ve yeniden yapılmasına gerek yoktur. Burada bir tekrar söz konusudur.
- 9-15. satırlar: Doğrulayıcılardan birinin başarısız olduğu durum
- 16-19. satırlar: tüm doğrulayıcıların başarılı olduğu durum
İşte iki yürütme örneği:
![]() |
- [1]'te, şu durumdaki bir yürütme örneği:
- [Valider] düğmesinin CausesValidation özelliğinin True olarak değiştirilmesi
- doğrulayıcıların EnableClientScript özelliği, True olarak değiştirildi
[2] hata mesajları, sayfanın JavaScript kodu tarafından istemci tarafında çalıştırılan doğrulayıcılar tarafından görüntülenmiştir. Gönderilen öğelerin etiketinde [3] olarak gösterildiği gibi, sunucuya POST gönderilmemiştir.
- [4]'te, şu durumdaki bir yürütme örneği:
- [Valider] düğmesinin CausesValidation özelliği False olarak ayarlanmışsa
- doğrulayıcıların EnableClientScript özelliği False olarak ayarlanmış
[5] hata mesajları, sunucu tarafında çalıştırılan doğrulayıcılar tarafından görüntülenmiştir. [6]'te de görüldüğü gibi, sunucuya bir POST gönderilmiştir. [7]'te, giriş hataları durumunda [ButtonValider_Click] yöntemi tarafından görüntülenen hata mesajı yer almaktadır.
![]() |
- [8]'te geçerli verilerle elde edilen bir örnek. [9,10], gönderilen öğelerin onaylandığını gösterir. Tekrarlı testler yapılırken, her yürütme sırasında onay mesajının ekranda kalmaması için [LabelValidation] etiketinin EnableViewState özelliğini False olarak ayarlamak gerekir.
2.4. Uygulama Kapsamındaki Verilerin Yönetimi
ASPX sayfasının yürütme mimarisine tekrar göz atalım:
![]() |
ASPX sayfasının sınıfı, istemcinin isteğinin başında örneklenir ve isteğin sonunda yok edilir. Dolayısıyla, iki istek arasında veri depolamak için kullanılamaz. İki tür veriyi depolamak istenebilir:
- web uygulamasının tüm kullanıcıları tarafından paylaşılan veriler. Bunlar genellikle salt okunur verilerdir. Bu veri paylaşımını gerçekleştirmek için üç dosya kullanılır:
- [Web.Config]: uygulamanın yapılandırma dosyası
- [Global.asax, Global.asax.cs]: Uygulamanın ömrü boyunca var olan ve "küresel uygulama sınıfı" olarak adlandırılan bir sınıfın yanı sıra, aynı uygulamanın belirli olayları için işleyicilerin tanımlanmasına olanak tanır.
Küresel uygulama sınıfı, tüm kullanıcıların tüm istekleri için kullanılabilir olacak verileri tanımlamaya olanak tanır.
- Aynı müşterinin istekleri arasında paylaşılan veriler. Bu veriler, Oturum adı verilen bir nesnede saklanır. Müşterinin belleği ifade etmek için müşteri oturumu terimi kullanılır. Bir müşterinin tüm istekleri bu oturuma erişebilir. Bu oturumda bilgi depolayabilir ve okuyabilirler
![]() |
Yukarıda, bir sayfanın erişebildiği bellek türlerini göstermekteyiz ASPX:
- Çoğunlukla salt okunur veriler içeren ve tüm kullanıcılar tarafından erişilebilen uygulama belleği.
- okuma/yazma verileri içeren ve aynı kullanıcının ardışık istekleri tarafından erişilebilen belirli bir kullanıcıya ait bellek veya oturum.
- Yukarıda gösterilmese de, bir istek belleği veya istek bağlamı mevcuttur. Bir kullanıcının isteği, birbirini izleyen birden fazla ASPX sayfası tarafından işlenebilir. İstek bağlamı, 1 numaralı sayfanın 2 numaralı sayfaya bilgi aktarmasını sağlar.
Burada, tüm kullanıcılar tarafından paylaşılan Application kapsamındaki verilerle ilgileniyoruz. Uygulamanın global sınıfı şu şekilde oluşturulabilir:
![]() |
- [1]'te, projeye yeni bir öğe eklenir
- [2]'te, genel uygulama sınıfı eklenir
- [3]'te, yeni öğe için varsayılan ad olan [Global.asax] korunur
![]() |
- [4]'te, projeye iki yeni dosya eklendi
- [5]'te, [Global.asax]'in etiket yapısı görüntülenir
<%@ Application Codebehind="Global.asax.cs" Inherits="Intro.Global" Language="C#" %>
- Application etiketi, daha önce [Default.aspx] için kullandığımız Page etiketinin yerini almaktadır. Bu etiket, genel uygulama sınıfını tanımlar
- Codebehind: genel uygulama sınıfının tanımlandığı dosyayı belirtir
- Inherits: Bu sınıfın adını belirtir
Oluşturulan Intro.Global sınıfı şöyledir:
using System;
namespace Intro
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
- 5. satır: genel uygulama sınıfı, HttpApplication sınıfından türetilmiştir
Sınıf, uygulama olay işleyicilerinin iskeletleriyle birlikte oluşturulur:
- 8. ve 38. satırlar: Application_Start (uygulamanın başlatılması) ve Application_End (web sunucusu durduğunda veya yönetici uygulamayı kapattığında uygulamanın sonlandırılması) olaylarını yönetir
- 13. ve 33. satırlar: Session_Start (yeni bir müşterinin gelmesi veya mevcut oturumun süresinin dolmasıyla yeni bir müşteri oturumunun başlatılması) ve Session_End (bir müşteri oturumunun ya programlama yoluyla açıkça ya da oturum için izin verilen sürenin aşılmasıyla dolaylı olarak sona ermesi) olaylarını yönetir.
- 28. satır: Application_Error olayını yönetir (uygulama kodu tarafından yönetilmeyen ve sunucuya iletilen bir istisnanın ortaya çıkması)
- 18. satır: Application_BeginRequest olayını yönetir (yeni bir isteğin gelmesi).
- 23. satır: Application_AuhenticateRequest olayını yönetir (bir kullanıcı kimlik doğrulaması yaptığında gerçekleşir).
[Application_Start] yöntemi, genellikle [Web.Config]'te bulunan bilgilerden yola çıkarak uygulamayı başlatmak için kullanılır. Bir projenin ilk oluşturulmasında üretilen yöntem şu şekildedir:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
...
</configSections>
<appSettings/>
<connectionStrings/>
<system.web>
...
</system.web>
<system.codedom>
....
</system.codedom>
<!--
La section system.webServer est requise pour exécuter ASP.NET AJAX sur Internet
Information Services 7.0. Elle n'est pas nécessaire pour les versions précédentes d'IIS.
-->
<system.webServer>
...
</system.webServer>
<runtime>
....
</runtime>
</configuration>
Mevcut uygulamamız için bu dosya gereksizdir. Bu dosyayı silsek veya adını değiştirsek bile uygulama normal şekilde çalışmaya devam eder. Şimdi 8. ve 9. satırlardaki etiketlere odaklanalım:
- <appsettings>, bir bilgi sözlüğü tanımlamaya olanak tanır
- <connectionStrings> veritabanlarına bağlantı dizelerini tanımlamaya yarar
Aşağıdaki [Web.config] dosyasını ele alalım:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
...
</configSections>
<appSettings>
<add key="cle1" value="valeur1"/>
<add key="cle2" value="valeur2"/>
</appSettings>
<connectionStrings>
<add connectionString="connectionString1" name="conn1"/>
</connectionStrings>
<system.web>
...
Bu dosya, aşağıdaki global uygulama sınıfı tarafından kullanılabilir:
using System;
using System.Configuration;
namespace Intro
{
public class Global : System.Web.HttpApplication
{
public static string Param1 { get; set; }
public static string Param2 { get; set; }
public static string ConnString1 { get; set; }
public static string Erreur { get; set; }
protected void Application_Start(object sender, EventArgs e)
{
try
{
Param1 = ConfigurationManager.AppSettings["cle1"];
Param2 = ConfigurationManager.AppSettings["cle2"];
ConnString1 = ConfigurationManager.ConnectionStrings["conn1"].ConnectionString;
}
catch (Exception ex)
{
Erreur = string.Format("Erreur de configuration : {0}", ex.Message);
}
}
protected void Session_Start(object sender, EventArgs e)
{
}
}
}
- 8-11. satırlar: dört statik P özelliği. Global sınıfının ömrü uygulamanın ömrü ile aynı olduğundan, uygulamaya yapılan her sorgu Global.P sözdizimi aracılığıyla bu P özelliklerine erişebilir.
- 17-19. satırlar: [Web.config] dosyasına [System.Configuration.ConfigurationManager] sınıfı aracılığıyla erişilebilir
- 17-18. satırlar: appSettings etiketinin öğelerini, [Web.config] dosyasından key özniteliği aracılığıyla alır.
- 19. satır: [Web.config] dosyasındaki <connectionStrings> etiketinin öğelerini name özniteliği aracılığıyla alır.
8-11. satırlardaki statik özniteliklere, yüklenen ASPX sayfalarının herhangi bir olay işleyicisinden erişilebilir. Bunları, [Default.aspx] sayfasının [Page_Load] olay işleyicisinde kullanıyoruz:
protected void Page_Load(object sender, EventArgs e)
{
// olay kaydediliyor
ListBoxEvts.Items.Insert(0, string.Format("{0}: Page_Load", DateTime.Now.ToString("hh:mm:ss")));
// genel uygulama sınıfından bilgiler alınır
LabelGlobal.Text = string.Format("Param1={0},Param2={1},ConnString1={2},Erreur={3}", Global.Param1, Global.Param2, Global.ConnString1, Global.Erreur);
}
- 6. satır: Uygulamanın genel sınıfının dört statik özniteliği, [Default.aspx] sayfasındaki yeni bir etiketi doldurmak için kullanılır
![]() |
Çalıştırıldığında şu sonuç elde edilir:
![]() |
Yukarıda, [web.config] parametrelerinin doğru bir şekilde alındığını görüyoruz. Tüm kullanıcılar tarafından paylaşılan bilgileri depolamak için en uygun yer, genel uygulama sınıfıdır.
2.5. Oturum Kapsamındaki Verilerin Yönetimi
Burada, belirli bir kullanıcının istekleri boyunca bilgilerin nasıl saklanacağına odaklanacağız:
![]() |
Her kullanıcının, oturum olarak adlandırılan kendine ait bir belleği vardır.
Küresel uygulama sınıfının olayları yönetmek için iki yöneticiye sahip olduğunu görmüştük:
- Session_Start: oturumun başlangıcı
- Session_end: oturumun sonu
Oturum mekanizması şu şekilde çalışır:
- Bir kullanıcının ilk isteği sırasında, web sunucusu bir oturum jetonu oluşturur ve bunu kullanıcıya atar. Bu jeton, her kullanıcı için benzersiz bir karakter dizisidir. Sunucu tarafından, kullanıcının ilk isteğine verilen yanıtta gönderilir.
- Sonraki isteklerde kullanıcı (web tarayıcısı), kendisine atanan oturum jetonunu isteğine ekler. Böylece web sunucusu kullanıcıyı tanıyabilir.
- Bir oturumun geçerlilik süresi vardır. Web sunucusu bir kullanıcıdan istek aldığında, bir önceki istekten bu yana geçen süreyi hesaplar. Bu süre oturumun geçerlilik süresini aşarsa, kullanıcı için yeni bir oturum oluşturulur. Önceki oturumun verileri kaybolur. Microsoft’un IIS (Internet Information Server) web sunucusunda, oturumların varsayılan ömrü 20 dakikadır. Bu değer, web sunucusu yöneticisi tarafından değiştirilebilir.
- Web sunucusu, bu isteğin oturum jetonu içermediği için bir kullanıcının ilk isteğiyle karşı karşıya olduğunu bilir. Bu, tek istektir.
Herhangi bir ASP.NET sayfası, [System.Web.SessionState.HttpSessionState] türündeki Session özelliği aracılığıyla kullanıcının oturumuna erişebilir. HttpSessionState sınıfının aşağıdaki P özelliklerini ve M yöntemlerini kullanacağız:
Ad | Tür | Rol |
Item[String clé] | P | Oturum, bir sözlük gibi oluşturulabilir. Item[clé], clé ile tanımlanan oturum öğesidir. [HttpSessionState].Item[clé] yazmak yerine, [HttpSessionState].[clé] da yazılabilir. |
Temizle | M | oturum sözlüğünü boşaltır |
İptal | M | oturumu sonlandırır. Oturum artık geçerli değildir. Kullanıcının bir sonraki isteği ile yeni bir oturum başlayacaktır. |
Kullanıcı belleği örneği olarak, bir kullanıcının [Valider] düğmesine kaç kez tıkladığını sayacağız. Bu sonucu elde etmek için, kullanıcı oturumunda bir sayaç tutulması gerekir.
[Default.aspx] sayfası şu şekilde gelişir:
![]() |
[Global.asax.cs] genel uygulama sınıfı şu şekilde gelişir:
using System;
using System.Configuration;
namespace Intro
{
public class Global : System.Web.HttpApplication
{
public static string Param1 { get; set; }
...
protected void Application_Start(object sender, EventArgs e)
{
...
}
protected void Session_Start(object sender, EventArgs e)
{
// istek sayacı
Session["nbRequêtes"] = 0;
}
}
}
- satırda, "nbRequêtes" anahtarıyla tanımlanan istek sayacını depolamak için kullanıcı oturumu kullanılır. Bu sayaç, [Default.aspx] sayfasındaki [ButtonValider_Click] yöneticisi tarafından güncellenir:
using System;
namespace Intro
{
public partial class _Default : System.Web.UI.Page
{
....
protected void ButtonValider_Click(object sender, EventArgs e)
{
// olay kaydedilir
ListBoxEvts.Items.Insert(0, string.Format("{0}: ButtonValider_Click", DateTime.Now.ToString("hh:mm:ss")));
// gönderilen isim ve yaş görüntüleniyor
LabelPost.Text = string.Format("nom={0}, age={1}", TextBoxNom.Text.Trim(), TextBoxAge.Text.Trim());
// istek sayısı
Session["nbRequêtes"] = (int)Session["nbRequêtes"] + 1;
LabelNbRequetes.Text = Session["nbRequêtes"].ToString();
// sayfa geçerli mi?
Page.Validate();
if (!Page.IsValid)
{
...
}
...
}
}
}
- 16. satır: istek sayacı artırılır
- 17. satır: Sayaç sayfada görüntülenir
İşte bir yürütme örneği:
![]() |
2.6. Bir sayfanın yüklenmesi sırasında GET / POST yönetimi
ASPX sayfasına iki tür istek olduğunu belirtmiştik:
- tarayıcının HTTP veya GET komutuyla yaptığı ilk istek. Sunucu, istenen sayfayı göndererek yanıt verir. Bu sayfanın bir form olduğunu varsayalım: c.a.d. Gönderilen ASPX sayfasında bir <form runat="server"...> etiketi bulunmaktadır.
- Tarayıcı, kullanıcının form üzerindeki belirli eylemlerine tepki olarak aşağıdaki istekleri gönderir. Tarayıcı daha sonra HTTP ve POST isteklerini gönderir.
İster GET isteği ister POST isteği olsun, [Page_Load] yöntemi yürütülür. GET sırasında bu yöntem genellikle istemci tarayıcısına gönderilen sayfayı başlatmak için kullanılır. Ardından, VIEWSTATE mekanizması sayesinde sayfa başlatılmış halde kalır ve yalnızca POST'leri tetikleyen olay işleyicileri tarafından değiştirilir. Page_Load'te sayfayı yeniden başlatmaya gerek yoktur. Bu nedenle, bu yöntemin istemcinin isteğinin bir GET mi yoksa bir POST mi olduğunu bilmesi gerekir.
Aşağıdaki örneği inceleyelim. [Default.aspx] sayfasına bir açılır liste ekleniyor. Bu listenin içeriği, GET isteğinin Page_Load yöneticisinde tanımlanacaktır:
![]() |
Açılır liste, [Default.aspx.designer.cs]'te şu şekilde tanımlanmıştır:
protected global::System.Web.UI.WebControls.DropDownList DropDownListNoms;
[DropDownList] sınıfının aşağıdaki M yöntemlerini ve P özelliklerini kullanacağız:
Ad | Tür | Rol |
Öğeler | P | açılır listedeki ListItem türündeki öğelerin ListItemCollection türündeki koleksiyonu |
SelectedIndex | P | Form gönderildiğinde açılır listeden seçilen öğenin 0'dan başlayan indeksi |
SelectedItem | P | form gönderildiğinde açılır listeden seçilen ListItem türündeki öğe |
SelectedValue | P | form gönderildiğinde açılır listeden seçilen ListItem türündeki öğenin string türündeki değeri. Bu değer kavramını birazdan tanımlayacağız. |
Açılır listedeki öğelerin ListItem sınıfı, HTML etiketinin <option> etiketlerini oluşturmak için kullanılır:
<option> etiketinde
- textei, açılır listede görüntülenen metindir
- vali, açılır listeden textei seçildiğinde tarayıcı tarafından gönderilen değerdir
Her seçenek, LisItem oluşturucu (ListItem(string metin, string değer)) kullanılarak oluşturulan bir LisItem nesnesi ile oluşturulabilir.
[Default.aspx.cs]'te, [Page_Load] işleyicisinin kodu şu şekilde değişir:
protected void Page_Load(object sender, EventArgs e)
{
// olayı kaydedilir
...
// genel uygulama sınıfından bilgiler alınır
...
// adlar listesi yalnızca GET ilk çalıştırıldığında başlatılır
if (!IsPostBack)
{
for (int i = 0; i < 3; i++)
{
DropDownListNoms.Items.Add(new ListItem("nom"+i,i.ToString()));
}
}
}
- 8. satır: Page sınıfı, boole türünde bir IsPostBack özniteliğine sahiptir. Aslında bu, kullanıcının isteğinin bir POST olduğu anlamına gelir. Dolayısıyla 10-13. satırlar yalnızca müşterinin başlangıçtaki GET değeri üzerinde yürütülür.
- 12. satır: [DropDownListNoms] listesine, ListItem (string texte, string value) türünde bir öğe eklenir. (i+1)'inci öğe için görüntülenen metin nomi olacak ve bu öğe seçildiğinde gönderilen değer i olacaktır.
Açılır menüden gönderilen değeri görüntülemek için [ButtonValider_Click] işleyicisi değiştirilir:
protected void ButtonValider_Click(object sender, EventArgs e)
{
// olay kaydediliyor
...
// gönderilen değerler görüntülenir
LabelPost.Text = string.Format("nom={0}, age={1}, combo={2}", TextBoxNom.Text.Trim(), TextBoxAge.Text.Trim(), DropDownListNoms.SelectedValue);
// istek sayısı
...
}
- satırda, [DropDownListNoms] listesi için gönderilen değer, listenin SelectedValue özelliği kullanılarak elde edilir. İşte bir yürütme örneği:
![]() |
- [1]'te, açılır listenin içeriği, ilk GET'ten sonra ve ilk POST'ten hemen önce yer alır
- [2]'te, ilk POST'ten sonraki sayfa.
- [3]'te, açılır liste için gönderilen değer. Listeden seçilen ListItem'in value özniteliğine karşılık gelir.
- [4]'te, açılır liste. Bu liste, ilk GET'ten sonraki listeyle aynı öğeleri içerir. Bunu açıklayan, VIEWSTATE'in işleyişidir.
DropDownListNoms listesindeki VIEWSTATE ile Page_Load yöneticisinin (! IsPostBack) ifadesi arasındaki etkileşimi anlamak için, okuyucunun önceki testi aşağıdaki yapılandırmalarla tekrarlaması önerilir:
Durum | DropDownListNoms.EnableViewState | [Default.aspx]'in Page_Load'indeki if(! IsPostBack) testi |
Çeşitli testler şu sonuçları vermektedir:
- Bu, yukarıda sunulan durumdur
- liste, ilk GET sırasında doldurulur, ancak bunu izleyen POST'lerde doldurulmaz. EnableViewState yanlış olduğu için, her POST'ten sonra liste boştur
- Liste, hem ilk GET işleminden sonra hem de onu izleyen POST işlemlerinde doldurulur. EnableViewState, vrai'e eşit olduğundan, ilk GET'ten sonra 3 isim, 1. POST'ten sonra 6 isim, 2. POST'ten sonra 9 isim vardır, ...
- Liste, hem ilk GET’ten sonra hem de onu izleyen POST’lerde doldurulur. EnableViewState, faux'e eşit olduğundan, liste her istekte yalnızca 3 adla doldurulur; bu istek ister ilk GET olsun, ister onu izleyen POST'ler olsun. Burada 1. durumdaki davranışla karşılaşıyoruz. Dolayısıyla, aynı sonuca ulaşmanın iki yolu vardır.
2.7. VIEWSTATE sayfasındaki öğelerin yönetimi
Varsayılan olarak, bir ASPX sayfasındaki tüm öğelerin EnableViewState özelliğinin değeri True'tir. ASPX sayfası istemci tarayıcısına her gönderildiğinde, sayfa, __VIEWSTATE adlı gizli alanı içerir; bu alanın değeri, EnableViewState ile True arasında değişen özellik değerlerine sahip bileşenlerin tüm değerlerini kodlayan bir karakter dizisidir. Bu dizenin boyutunu en aza indirmek için, EnableViewState ile True arasındaki özellik değerlerine sahip bileşenlerin sayısını azaltmaya çalışılabilir.
ASPX sayfasındaki bileşenlerin, bir POST işleminin tamamlanmasının ardından değerlerini nasıl aldığını hatırlayalım:
- ASPX sayfası örneklenir. Bileşenler tasarım değerleriyle başlatılır.
- Tarayıcı tarafından gönderilen __VIEWSTATE değeri, bileşenlere ASPX sayfasının tarayıcıya bir önceki sefer gönderildiğinde sahip oldukları değeri vermek için kullanılır.
- Tarayıcı tarafından gönderilen değerler bileşenlere atanır
- Olay işleyicileri çalıştırılır. Bunlar, bazı bileşenlerin değerlerini değiştirebilir.
Bu akıştan, aşağıdaki bileşenlerin:
- değerleri gönderilen
- değerleri bir olay işleyicisi tarafından değiştirilen bileşenler
EnableViewState ile Faux arasındaki bir değere sahip olabilirler; çünkü VIEWSTATE değerleri (2. adım), 3. veya 4. adımlardan biri tarafından değiştirilecektir.
Sayfamızın bileşenlerinin listesi [Default.aspx.designer.cs]'te mevcuttur:
namespace Intro {
public partial class _Default {
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
protected global::System.Web.UI.WebControls.TextBox TextBoxNom;
protected global::System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidatorNom;
protected global::System.Web.UI.WebControls.TextBox TextBoxAge;
protected global::System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidatorAge;
protected global::System.Web.UI.WebControls.RangeValidator RangeValidatorAge;
protected global::System.Web.UI.WebControls.DropDownList DropDownListNoms;
protected global::System.Web.UI.WebControls.Button ButtonValider;
protected global::System.Web.UI.WebControls.ListBox ListBoxEvts;
protected global::System.Web.UI.WebControls.Label LabelPost;
protected global::System.Web.UI.WebControls.Label LabelValidation;
protected global::System.Web.UI.WebControls.Label LabelErreursSaisie;
protected global::System.Web.UI.WebControls.Label LabelGlobal;
protected global::System.Web.UI.WebControls.Label LabelNbRequetes;
}
}
Bu bileşenlerin EnableViewState özelliğinin değeri şu şekilde olabilir:
Composant | Gönderilen değer | EnableViewState | Pourquoi |
TextBoxNom | TextBox'te girilen değer | False | bileşenin değeri kaydedildi |
TextBoxAge | aynı | ||
RequiredFieldValidatorNom | yok | False | bileşen değer kavramı yok |
RequiredFieldValidatorAge | aynı | ||
RangeValidatorAge | aynı | ||
LabelPost | yok | False | değerini bir olay işleyicisinden alır |
LabelValidation | aynı | ||
LabelErreursSaisie | aynı | ||
LabelGlobal | aynı | ||
LabelNbRequetes | aynı | ||
DropDownListNoms | Seçilen öğenin "değeri" | True | istekler boyunca listeyi yeniden oluşturmaya gerek kalmadan içeriğini korumak istiyoruz |
ListBoxEvts | Seçilen öğenin "value" değeri | False | Listenin içeriği bir olay işleyicisi tarafından oluşturulur |
ButtonValider | düğmenin etiketi | False | bileşen tasarım değerini korur |
2.8. Bir sayfadan diğerine yönlendirme
Şimdiye kadar, GET ve POST işlemleri her zaman aynı [Default.aspx] sayfasını döndürüyordu. Bir isteğin, birbirini izleyen iki ASPX sayfası, yani [Default.aspx] ve [Page1.aspx] tarafından işlendiği ve sonuncusunun müşteriye döndürüldüğü durumu ele alacağız. Ayrıca, [Default.aspx] sayfasının, “istek belleği” olarak adlandıracağımız bir bellek aracılığıyla [Page1.aspx] sayfasına nasıl bilgi aktarabileceğini de göreceğiz.
![]() |
[Page1.aspx] sayfasını oluşturuyoruz:
![]() |
- [1]'te, projeye yeni bir öğe ekliyoruz
- [2]'te, [Web Form] adlı bir öğe ekliyoruz [Page1.aspx] [3]
![]() |
- [4]'te, eklenen sayfa
- [5] olarak, sayfa oluşturulduktan sonra
[Page1.aspx]'in kaynak kodu şöyledir:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Page1.aspx.cs" Inherits="Intro.Page1" %>
<!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 id="Head1" runat="server">
<title>Page1</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
Page 1</h1>
<asp:Label ID="Label1" runat="server"></asp:Label>
<br />
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Default.aspx">Retour
vers page [Default]</asp:HyperLink>
</div>
</form>
</body>
</html>
- 13. satır: [Default.aspx] sayfası tarafından iletilen bir bilgiyi görüntülemek için kullanılacak bir etiket
- 15. satır: HTML sayfasından [Default.aspx] sayfasına giden bir bağlantı. Kullanıcı bu bağlantıya tıkladığında, tarayıcı GET işlemiyle [Default.aspx] sayfasını ister. Böylece [Default.aspx] sayfası, kullanıcı URL'yi tarayıcısına doğrudan yazmış gibi yüklenir.
[Default.aspx] sayfası, LinkButton türünde yeni bir bileşenle zenginleştirilir:
![]() |
Bu yeni bileşenin kaynak kodu şöyledir:
<asp:LinkButton ID="LinkButtonToPage1" runat="server" CausesValidation="False"
EnableViewState="False" onclick="LinkButtonToPage1_Click">Forward vers Page1</asp:LinkButton>
- CausesValidation="False": Bağlantıya tıklandığında POST'ten [Defaul.aspx]'e yönlendirme gerçekleşir. [LinkButton] bileşeni, [Button] bileşeni gibi davranır. Burada, bağlantıya tıklandığında doğrulayıcıların çalıştırılmasını istemiyoruz.
- EnableViewState="False": İstekler arasında bağlantının durumunun korunmasına gerek yoktur. Tasarım değerlerini korur.
- onclick="LinkButtonToPage1_Click": [Defaul.aspx.cs] içinde, LinkButtonToPage1 bileşenindeki Click olayını yöneten yöntemin adı.
LinkButtonToPage1_Click işleyicisinin kodu şöyledir:
// Page1'e
protected void LinkButtonToPage1_Click(object sender, EventArgs e)
{
// bilgileri bağlama ekleniyor
Context.Items["msg1"] = "Message de Default.aspx pour Page1";
// isteği Sayfa1'e aktarılır
Server.Transfer("Page1.aspx",true);
}
- satırda, istek [Server.Transfer] yöntemi aracılığıyla [Page1.aspx] sayfasına aktarılır. true'teki yöntemin ikinci parametresi, POST sırasında [Default.aspx]'e gönderilen tüm bilgilerin [Page1.aspx]'e aktarılması gerektiğini belirtir. Bu sayede, örneğin [Page1.aspx], Request.Form adlı bir koleksiyon aracılığıyla gönderilen değerlere erişebilir. 5. satırda, "istek bağlamı" olarak adlandırılan kavram kullanılmaktadır. Buna, Page sınıfının Context özelliği aracılığıyla erişilebilir. Bu bağlam, aynı isteği işleyen farklı sayfalar arasında (burada [Default.aspx] ve [Page1.aspx]) bir bellek görevi görebilir. Bunun için Items sözlüğü kullanılır.
[Page1.aspx], Server.Transfer("Page1.aspx",true) işlemi tarafından yüklendiğinde, her şey sanki [Page1.aspx], bir tarayıcının GET işlevi tarafından çağrılmış gibi gerçekleşir. [Page1.aspx]'in Page_Load işleyicisi normal şekilde yürütülür. Bunu, [Default.aspx] tarafından istek bağlamında yerleştirilen mesajı görüntülemek için kullanacağız:
using System;
namespace Intro
{
public partial class Page1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = Context.Items["msg1"] as string;
}
}
}
- satırda, [Default.aspx] tarafından istek bağlamında yerleştirilen mesaj, Label1'te görüntülenir.
İşte bir yürütme örneği:
![]() |
- [Default.aspx] sayfasında, [1]'te, bizi Page1 sayfasına yönlendiren [2] bağlantısına tıklandığında
- [3] sayfasında, Page1 sayfası görüntülenir
- [4]'te, [Default.aspx]'te oluşturulan ve [Page1.aspx] tarafından görüntülenen mesaj
- [5]'te, tarayıcıda görüntülenen URL, [Default.aspx] sayfasıdır
2.9. Bir sayfadan başka bir sayfaya yönlendirme
Burada, önceki tekniğe işlevsel olarak benzer başka bir teknik sunuyoruz: kullanıcı POST üzerinden [Default.aspx] sayfasını talep ettiğinde, yanıt olarak [Page2.aspx] sayfasını alır. Önceki yöntemde, kullanıcının isteği sırasıyla iki sayfa tarafından işleniyordu: [Default.aspx] ve [Page1.aspx]. Şimdi tanıtacağımız sayfa yönlendirme yönteminde ise tarayıcıdan gelen iki ayrı istek vardır:
![]() |
- [1] adresine geldiğinde, tarayıcı [Default.aspx] sayfasına POST isteği gönderir. Bu sayfa isteği işler ve tarayıcıya bir yönlendirme yanıtı gönderir. Bu yanıt, tarayıcıdan [Page2.aspx] adresine yönlendirilmesini isteyen basit bir HTTP akışıdır (metin satırları). [Default.aspx], bu ilk yanıtta HTML akışını göndermez.
- [2]'te, tarayıcı GET sayfasına bir istek gönderir. Bu istek, yanıt olarak tarayıcıya gönderilir.
- [Default.aspx] sayfası, [Page2.aspx] sayfasına bilgi aktarmak isterse, bunu kullanıcının oturumu aracılığıyla yapabilir. Önceki yöntemin aksine, burada istek bağlamı kullanılamaz; çünkü burada iki ayrı istek ve dolayısıyla iki ayrı bağlam vardır. Bu durumda, sayfaların birbiriyle iletişim kurması için kullanıcı oturumu kullanılmalıdır.
[Page1.aspx] sayfasında yapıldığı gibi, projeye [Page2.aspx] sayfasını ekliyoruz:
![]() |
- [1]'te, [Page2.aspx] projeye eklendi
- [2]'te, [Page2.aspx]'in görsel görünümü
- [3]'te, [Default.aspx] sayfasına, kullanıcıyı [Page2.aspx] sayfasına yönlendirecek bir LinkButton [4] bileşeni ekliyoruz.
[Page2.aspx]'in kaynak kodu, [Page1.aspx]'inkine benzerdir:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Page2.aspx.cs" Inherits="Intro.Page2" %>
<!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 id="Head1" runat="server">
<title>Page2</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
Page 2</h1>
<asp:Label ID="Label1" runat="server"></asp:Label>
<br />
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Default.aspx">Retour
vers page [Default]</asp:HyperLink>
</div>
</form>
</body>
</html>
[Default.aspx]'te, LinkButton bileşeninin eklenmesi şu kaynak kodu oluşturdu:
<asp:LinkButton ID="LinkButtonToPage2" runat="server"
onclick="LinkButtonToPage2_Click">Redirection vers Page2</asp:LinkButton>
[LinkButtonToPage2_Click] yöneticisi, [Page2.aspx]'e yönlendirmeyi sağlar. [Defaul.aspx.cs]'teki kodu şöyledir:
protected void LinkButtonToPage2_Click(object sender, EventArgs e)
{
// oturuma bir mesaj ekleniyor
Session["msg2"] = "Message de [Default.aspx] pour [Page2.aspx]";
// istemciyi [Page2.aspx]'e yönlendiriyoruz
Response.Redirect("Page2.aspx");
}
- 4. satır: kullanıcının oturumuna bir mesaj eklenir
- 5. satır: Response nesnesi, her ASPX sayfasının bir özelliğidir. Bu nesne, müşteriye verilen yanıtı temsil eder. İçerdiği Redirect yöntemi sayesinde, müşteriye verilen yanıt bir HTTP yönlendirme emri haline gelir.
Tarayıcı, [Page2.aspx] adresine yönlendirme komutunu aldığında, bu sayfada bir GET işlemi gerçekleştirecektir. Bu sayfada, [Page_Load] yöntemi çalıştırılacaktır. Bu yöntemi, [Default.aspx] tarafından oturuma kaydedilen mesajı almak ve görüntülemek için kullanacağız. [Page2.aspx.cs] kodu şu şekildedir:
using System;
namespace Intro
{
public partial class Page2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// [Default.aspx] tarafından oturuma eklenen mesaj görüntülenir
Label1.Text = Session["msg2"] as string;
}
}
}
Çalıştırıldığında şu sonuçlar elde edilir:
![]() |
- [1] adresindeyken, [Default.aspx] adresindeki yönlendirme bağlantısına tıklanır. POST adresinden [Default.aspx] sayfasına yönlendirme yapılır
- [2] adresinde, tarayıcı [Page2.aspx] adresine yönlendirilmiştir. Bu durum, tarayıcıda görüntülenen URL adresinden anlaşılabilir. Önceki yöntemde, tarayıcı tarafından yapılan tek istek bu URL'ye yönelik olduğu için bu URL, [Default.aspx] idi. Burada önce POST adresinden [Default.aspx] adresine bir yönlendirme, ardından kullanıcının haberi olmadan GET adresinden [Page2.aspx] adresine ikinci bir yönlendirme gerçekleşir.
- [3]'te, [Page2.aspx]'in, [Default.aspx] tarafından oturuma yerleştirilen mesajı doğru bir şekilde aldığını görüyoruz.
2.10. Conclusion
Birkaç örnek yardımıyla, bu belgenin ilerleyen bölümlerinde bize faydalı olacak ASP.NET kavramlarını tanıttık. Bu giriş, bir web uygulamasındaki istemci/sunucu iletişiminin inceliklerini anlamaya yetmez. Bunun için şu kaynağı okuyabilirsiniz:
- ASP.NET [Développement WEB avec ASP.NET 1.1 ] Programlama



































