8. ASP sunucu bileşenleri - 2
8.1. Introduction
Kullanıcı arayüzü üzerindeki çalışmalarımıza devam ederek şunları inceliyoruz:
- veri doğrulama bileşenleri
- verileri sunucu bileşenlerine bağlama yöntemi
- HTML sunucu bileşenleri
8.2. Veri doğrulama bileşenleri
8.2.1. Giriş
Form tabanlı uygulamalarda, formlara girilen verilerin geçerliliğini kontrol etmek son derece önemlidir. Vergi hesaplama örneğinde, aşağıdaki form vardı:

Bu formdan gelen değerleri aldığımızda, girilen verilerin geçerliliğini kontrol etmemiz gerekir: çocuk sayısı ve maaş, pozitif tamsayılar veya sıfır olmalıdır. Aksi takdirde, form, hataları belirten mesajlarla birlikte girildiği haliyle müşteriye geri gönderilir. Bu durumu iki görünümle ele almıştık; biri yukarıdaki form için, diğeri ise hatalar içindi:

ASP.NET, aşağıdaki durumları doğrulamaya olanak tanıyan "doğrulama bileşenleri" adı verilen bileşenler sunar:
Bileşen | Rol |
bir alanın boş olup olmadığını doğrular | |
iki değeri birbiriyle karşılaştırır | |
bir değerin iki sınır arasında olup olmadığını kontrol eder | |
bir alanın düzenli ifadeyi karşılayıp karşılamadığını kontrol eder | |
geliştiricinin kendi doğrulama kurallarını belirlemesine olanak tanır - bu bileşen diğer tüm bileşenlerin yerini alabilir | |
önceki denetimler tarafından üretilen hata mesajlarını sayfanın tek bir yerinde toplar |
Şimdi bu bileşenlerin her birini tek tek tanıtacağız.
8.2.2. RequiredFieldValidator
Aşağıdaki [requiredfieldvalidator1.aspx] sayfasını oluşturuyoruz:
![]() |
no | ad | tür | özellikler | rol |
1 | TextBox | EnableViewState=true | giriş alanı | |
2 | RequiredFieldValidator | EnableViewState=false EnableClientScript=true ErrorMessage=[ad] alanı zorunludur | doğrulama bileşeni | |
3 | Düğme | EnableViewState=false Doğrulama Nedenleri=true | [submit] düğmesi |
[RequiredFieldValidator1] alanı, [txtNom] alanı boşsa veya bir dizi boşluk içeriyorsa bir hata mesajı görüntülemek için kullanılır. Özellikleri şunlardır:
değeri bileşen tarafından kontrol edilmesi gereken alan. Bir bileşenin değeri ne anlama gelir? Bu, ilgili HTML etiketinin [value] özniteliğinin değeridir. [TextBox] için bu, giriş alanının içeriği; [DropDownList] için ise seçilen öğenin değeri olacaktır. | |
boole - "true" değeri, önceki alanın içeriğinin istemci tarafında da kontrol edilmesi gerektiğini belirtir. Bu durumda, formda hata bulunmadığı takdirde form tarayıcı tarafından gönderilir. Bununla birlikte, örneğin istemcinin bir tarayıcı olmaması durumuna karşı, doğrulama testleri sunucu tarafında da yapılır. | |
Hata tespit edildiğinde bileşenin görüntülemesi gereken hata mesajı |
Doğrulama denetimleri aracılığıyla sayfadaki verilerin kontrolü, yalnızca sayfadaki [POST]'i tetikleyen düğme veya bağlantının [CausesValidation=true] özelliğine sahip olması durumunda yapılır. [true], bu özelliğin varsayılan değeridir.
Bu uygulamayı çalıştıralım. Öncelikle bir [Mozilla] tarayıcısı kullanıyoruz:

[Mozilla] tarafından alınan HTML kodu şöyledir:
<html>
<head>
</head>
<body>
<form name="_ctl0" method="post" action="requiredfieldvalidator1.aspx" id="_ctl0">
<input type="hidden" name="__VIEWSTATE" value="dDwxNDI1MDc1NTU1Ozs+SGtdZvVxefDCDxnsqbDnqCaROsk=" />
<p>
Demande du dossier de candidature au DESS
</p>
<fieldset>
<legend>[--Identité--]</legend>
<table>
<tbody>
<tr>
<td>
Nom*</td>
<td>
<input name="txtNom" type="text" id="txtNom" />
</td>
</tr>
</tbody>
</table>
</fieldset>
<p>
<input type="submit" name="btnEnvoyer" value="Envoyer" onclick="if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " language="javascript" id="btnEnvoyer" />
</p>
</form>
</body>
</html>
[btnEnvoyer] düğmesinin, [onclick] özniteliği aracılığıyla bir JavaScript işlevine bağlı olduğu görülmektedir. Ayrıca, sayfada [Javascript] kodunun bulunmadığı da fark edilebilir. [typeof(Page_ClientValidate) == 'function'] testi başarısız olacak ve JavaScript işlevi çağrılmayacaktır. Form daha sonra sunucuya gönderilecek ve geçerlilik kontrolleri sunucu tarafından yapılacaktır. [Envoyer] düğmesini isim girmeden kullanalım. Sunucudan gelen yanıt şöyledir:

Ne oldu? Form sunucuya gönderildi. Sunucu, sayfada bulunan tüm doğrulama bileşenlerinin kodunu çalıştırdı. Burada sadece bir tane var. En az bir doğrulama bileşeni bir hata tespit ederse, sunucu formu girildiği haliyle geri gönderir (aslında [EnableViewState=true] özniteliğine sahip bileşenler için, ayrıca hata tespit eden her doğrulama bileşeni için bir hata mesajı da ekler). Bu mesaj, doğrulama bileşeninin [ErrorMessage] özniteliğidir. Yukarıda iş başında gördüğümüz mekanizma budur. [nom] alanına bir şey girersek, formu gönderdiğimizde hata mesajı artık görünmez:

Şimdi Internet Explorer'ı kullanarak [http://localhost/requiredfieldvalidator1.aspx] URL'sini çağıralım. Aşağıdaki sayfayı görürüz:

IE tarafından alınan HTML kodu şöyledir:
<html>
<head>
</head>
<body>
<form name="_ctl0" method="post" action="requiredfieldvalidator1.aspx" language="javascript" onsubmit="ValidatorOnSubmit();" id="_ctl0">
<input type="hidden" name="__VIEWSTATE" value="dDwxNDI1MDc1NTU1Ozs+SGtdZvVxefDCDxnsqbDnqCaROsk=" />
<script language="javascript" src="/aspnet_client/system_web/1_1_4322/WebUIValidation.js"></script>
<p>
Demande du dossier de candidature au DESS
</p>
<fieldset>
<legend>[--Identité--]</legend>
<table>
<tbody>
<tr>
<td>
Nom*</td>
<td>
<input name="txtNom" type="text" id="txtNom" />
<span id="RequiredFieldValidator1" controltovalidate="txtNom" errormessage="Le champ [nom] est obligatoire" evaluationfunction="RequiredFieldValidatorEvaluateIsValid" initialvalue="" style="color:Red;visibility:hidden;">Le champ [nom] est obligatoire</span>
</td>
</tr>
</tbody>
</table>
</fieldset>
<p>
<input type="submit" name="btnEnvoyer" value="Envoyer" onclick="if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " language="javascript" id="btnEnvoyer" />
</p>
<script language="javascript">
<!--
var Page_Validators = new Array(document.all["RequiredFieldValidator1"]);
// -->
</script>
<script language="javascript">
<!--
var Page_ValidationActive = false;
if (typeof(clientInformation) != "undefined" && clientInformation.appName.indexOf("Explorer") != -1) {
if (typeof(Page_ValidationVer) == "undefined")
alert("Impossible de trouver la bibliothèque de scripts /aspnet_client/system_web/1_1_4322/WebUIValidation.js. Essayez de placer ce fichier manuellement ou effectuez une réinstallation en exécutant 'aspnet_regiis -c'.");
else if (Page_ValidationVer != "125")
alert("Cette page utilise une version incorrecte de WebUIValidation.js. La page requiert la version 125. La bibliothèque de scripts est " + Page_ValidationVer + ".");
else
ValidatorOnLoad();
}
function ValidatorOnSubmit() {
if (Page_ValidationActive) {
ValidatorCommonOnSubmit();
}
}
// -->
</script>
</form>
</body>
</html>
Bu kodun, [Mozilla] tarafından alınan koddan çok daha uzun olduğu görülüyor. Ayrıntılara girmeyeceğiz. Aradaki fark, sunucunun gönderilen HTML belgesine javascript işlevleri eklemesinden kaynaklanıyor. İki tarayıcı tarafından istenen URL aynı olmasına rağmen neden iki farklı HTML kodu var? Daha önce de belirttiğimiz gibi, ASP.NET teknolojisi, sunucunun müşteriye gönderdiği HTML belgesini o müşterinin gereksinimlerine göre uyarlamasını sağlıyordu. Piyasada, hepsi aynı yeteneklere sahip olmayan farklı tarayıcılar bulunmaktadır. Örneğin, Microsoft ve Netscape tarayıcıları, aldıkları belge için aynı nesne modellemesini kullanmazlar. Dolayısıyla, bu belgeyi tarayıcı tarafında işlemek için kullanılan JavaScript kodu, iki tarayıcı arasında farklılıklar gösterir. Benzer şekilde, yazılım geliştiriciler, tarayıcılarının yeteneklerini sürekli olarak geliştiren yeni sürümler oluşturmuşlardır. Bu nedenle, IE5 tarafından anlaşılan bir HTML belgesi, IE3 tarafından anlaşılamayabilir. Yukarıda, sunucunun istemci düzeyinde yaptığı bu uyarlamaya ilişkin bir örnek verilmiştir. Burada ayrıntılı olarak ele alınmayan bir nedenden ötürü, web sunucusu [Mozilla] istemcisinin doğrulama amaçlı JavaScript kodunu işleme kapasitesine sahip olmadığını değerlendirmiştir. Bu nedenle, bu kod kendisine gönderilen HTML belgesine eklenmemiş ve doğrulama işlemi sunucu tarafında gerçekleştirilmiştir. [IE6] için ise, gördüğümüz gibi bu JavaScript kodu gönderilen HTML belgesine dahil edilmiştir. Bunun nasıl çalıştığını görmek için şu deneyi yapalım:
- web sunucusunu durduralım
- [nom] alanını doldurmadan [Envoyer] düğmesini kullanalım
Şu yeni sayfayı elde ediyoruz:

Hata mesajını görüntüleyen gerçekten de tarayıcıdır. Nitekim sunucu durdurulmuştur. [nom] alanına bir şey girip göndererek bunu doğrulayabiliriz. Bu sefer yanıt şöyledir:

Ne oldu? Tarayıcı, doğrulama için JavaScript kodunu çalıştırdı. Bu kod, sayfanın geçerli olduğunu bildirdi. Bunun üzerine tarayıcı, formu kapalı olan web sunucusuna gönderdi. Tarayıcı bunu fark etti ve yukarıdaki sayfayı görüntüledi. Sunucuyu yeniden başlatırsak her şey normale döner.
Bu örnekten ne öğrenebiliriz?
- Yanlış doldurulmuş formları müşteriye geri göndermek için kullanılan "doğrulama bileşeni" kavramının önemi
- [VIEWSTATE]'in önemi; bu kod, formun girildiği haliyle geri gönderilmesini sağlar
- Sunucunun müşteriye uyum sağlama yeteneği. Müşteri, sunucuya gönderdiği HTTP [User-Agent:] başlığıyla tanımlanır. Dolayısıyla, kiminle karşı karşıya olduğunu "tahmin eden" sunucu değildir. Bu uyum yeteneği, uygulamasının istemci türünü dert etmesine gerek kalmayan geliştirici için büyük önem taşır.
8.2.3. CompareValidator
Aşağıdaki [comparevalidator1.aspx] sayfasını oluşturuyoruz:

no | ad | tür | özellikler | rol |
1 | DropDownList | EnableViewState=true | açılır liste | |
2 | DropDownList | EnableViewState=true | açılır liste | |
3 | CompareValidator | EnableViewState=false EnableClientScript=true ErrorMessage=Seçim 1 geçersiz KarşılaştırılacakDeğer=? Operatör=Eşit Değil Tür=dize | doğrulama bileşeni | |
4 | CompareValidator | EnableViewState=false EnableClientScript=true ErrorMessage=Seçim 2 geçersiz Karşılaştırılacak Kontrol=? Operatör=Eşit Değil Type=string | doğrulama bileşeni | |
5 | Düğme | EnableViewState=false Doğrulama Nedenleri=true | [submit] düğmesi |
[CompareValidator] bileşeni, iki değeri birbiriyle karşılaştırmak için kullanılır. Kullanılabilen operatörler [Equal, NotEqual, LessThan, LessThanEqual, GreaterThan, GreaterThanEqual]'tir. İlk değer [ControlToValidate] özelliği ile belirlenir; ikinci değer ise önceki değer bir sabitle karşılaştırılacaksa [ValueToCompare], başka bir bileşenin değeriyle karşılaştırılacaksa [ControlToCompare] ile belirlenir. [CompareValidator] bileşeninin önemli özellikleri şunlardır:
içeriği bileşen tarafından kontrol edilmesi gereken alan | |
boole değeri - "true" ise, önceki alanın içeriğinin istemci tarafında da kontrol edilmesi gerektiğini belirtir | |
hata tespit edildiğinde bileşenin görüntülemesi gereken hata mesajı | |
[ControlToValidate] alanının değeriyle karşılaştırılması gereken değer | |
[ControlToValidate] alanının değeriyle karşılaştırılması gereken bileşen | |
iki değer arasındaki karşılaştırma operatörü | |
karşılaştırılacak değerlerin türü |
Bu sayfanın sunum kodu şöyledir:
<html>
<head>
</head>
<body>
<form runat="server">
<p>
Demande du dossier de candidature au DESS
</p>
<fieldset>
<legend>[--Options du DESS pour lesquelles vous candidatez--]</legend>
<table>
<tbody>
<tr>
<td>
Option1*</td>
<td>
Option2</td>
</tr>
<tr>
<td>
<asp:DropDownList id="cmbChoix1" runat="server">
<asp:ListItem Value="?" Selected="True">?</asp:ListItem>
<asp:ListItem Value="Automatique">Automatique</asp:ListItem>
<asp:ListItem Value="Informatique">Informatique</asp:ListItem>
</asp:DropDownList>
</td>
<td>
<asp:DropDownList id="cmbChoix2" runat="server">
<asp:ListItem Value="?">?</asp:ListItem>
<asp:ListItem Value="Automatique">Automatique</asp:ListItem>
<asp:ListItem Value="Informatique">Informatique</asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr>
<td>
<asp:CompareValidator id="CompareValidator1" runat="server" ErrorMessage="Choix 1 invalide" ControlToValidate="cmbChoix1" ValueToCompare="?" Operator="NotEqual"></asp:CompareValidator>
</td>
<td>
<asp:CompareValidator id="CompareValidator2" runat="server" ErrorMessage="Choix 2 invalide" ControlToValidate="cmbChoix2" Operator="NotEqual" ControlToCompare="cmbChoix1"></asp:CompareValidator>
</td>
</tr>
</tbody>
</table>
</fieldset>
<p>
<asp:Button id="btnEnvoyer" runat="server" Text="Envoyer"></asp:Button>
</p>
</form>
</body>
</html>
Sayfanın doğrulama kısıtlamaları şunlardır:
- [cmbChoix1]'te seçilen değer, "?" dizesinden farklı olmalıdır. Bu, [CompareValidator1] bileşeni için aşağıdaki özellikleri gerektirir: Operator=NotEqual, ValueToCompare=?, Type=string
- [cmbChoix2]'te seçilen değer, [cmbChoix1]'te seçilen değerden farklı olmalıdır. Bu, [CompareValidator2] bileşeni için aşağıdaki özellikleri gerektirir: Operatör=NotEqual, ControlToCompare=cmbChoix1, Tür=dize
Bu uygulamayı çalıştırıyoruz. İşte istemci-sunucu iletişimi sırasında alınan bir sayfa örneği:

Aynı sayfa Internet Explorer 6 ile çağrıldığında, sayfaya eklenen JavaScript kodu sayesinde işleyiş biraz farklılaşır. Kullanıcı açılır listelerden birinde değeri değiştirdiğinde olası hatalar hemen bildirilir. Bu, kullanıcı deneyimini iyileştiren bir özelliktir.
8.2.4. CustomValidator, RangeValidator
Aşağıdaki [customvalidator1.aspx] sayfasını oluşturuyoruz:

no | ad | tür | özellikler | rol |
DropDownList | EnableViewState=true | açılır liste | ||
CompareValidator | EnableViewState=false EnableClientScript=true ErrorMessage=Geçersiz diploma Operatör=Eşit Değil Karşılaştırılacak Değer=? Type=String | [1] denetiminin doğrulama bileşeni | ||
TextBox | EnableViewState=false | giriş alanı | ||
CustomValidator | EnableViewState=false EnableClientScript=true ErrorMessage=Diploma doğruluğu geçersiz ClientValidationFunction=chkAutreDiplome | alan doğrulama bileşeni [3] | ||
TextBox | EnableViewState=false | giriş alanı | ||
RangeValidator | EnableViewState=false EnableClientScript=true ErrorMessage=Mezuniyet yılı [1990,2004] aralığında olmalıdır MinValue=1990 MaxValue=2004 Type=Tamsayı ControlToValidate=txtAnDiplome | [5] alanının doğrulama bileşeni | ||
RequiredFieldValidator | EnableViewState=false EnableClientScript=true ErrorMessage=Mezuniyet yılı gereklidir ControlToValidate=txtAnDiplome | alan doğrulama bileşeni [5] | ||
Düğme | EnableViewState=false CausesValidation=true | [submit] düğmesi |
[RangeValidator] alanı, bir denetim değerinin [MinValue] ve [MaxValue] sınırları arasında olup olmadığını doğrulamak için kullanılır. Özellikleri şunlardır:
değeri bileşen tarafından kontrol edilmesi gereken alan | |
boole değeri - "true" ise, önceki alanın içeriğinin istemci tarafında da kontrol edilmesi gerektiğini belirtir | |
hata tespit edildiğinde bileşenin görüntülemesi gereken hata mesajı | |
denetlenecek alanın değerinin minimum değeri | |
denetlenecek alanın değerinin maksimum değeri | |
denetlenecek alanın değer türü |
[CustomValidator] alanı, ASP.NET tarafından sunulan doğrulama bileşenlerinin yapamadığı doğrulamaları yapmanıza olanak tanır. Bu doğrulama, geliştirici tarafından yazılan bir işlevle gerçekleştirilir. Bu işlev sunucu tarafında çalıştırılır. Doğrulama işlemine istemci tarafında da yapılabileceğinden, geliştirici HTML belgesine ekleyeceği bir JavaScript işlevi geliştirebilir. Bu işlevin özellikleri şunlardır:
değeri bileşen tarafından kontrol edilmesi gereken alan | |
boole değeri – "true" ise, önceki alanın içeriğinin istemci tarafında da kontrol edilmesi gerektiğini belirtir | |
hata tespit edildiğinde bileşenin görüntülemesi gereken hata mesajı | |
istemci tarafında çalıştırılacak işlev |
Sayfanın görüntüleme kodu şöyledir:
<%@ Page Language="VB" %>
<script runat="server">
...
</script>
<html>
<head>
</head>
<body>
<form runat="server">
<p align="left">
Demande du dossier de candidature au DESS
</p>
<fieldset>
<legend>[--Votre dernier diplôme--]</legend>
<table>
<tbody>
<tr>
<td>
Diplôme*</td>
<td>
<asp:DropDownList id="cmbDiplomes" runat="server">
<asp:ListItem Value="?">?</asp:ListItem>
<asp:ListItem Value="[Autre]">[Autre]</asp:ListItem>
<asp:ListItem Value="Maîtrise">Maîtrise</asp:ListItem>
<asp:ListItem Value="DESS">DESS</asp:ListItem>
<asp:ListItem Value="DEA">DEA</asp:ListItem>
</asp:DropDownList>
</td>
<td>
Si [Autre], précisez</td>
<td>
<asp:TextBox id="txtAutreDiplome" runat="server" EnableViewState="False"></asp:TextBox>
</td>
</tr>
<tr>
<td>
</td>
<td>
<p>
<asp:CompareValidator id="CompareValidator2" runat="server" ErrorMessage="Diplôme invalide" ControlToValidate="cmbDiplomes" ValueToCompare="?" Operator="NotEqual" ></asp:CompareValidator>
</p>
</td>
<td>
</td>
<td>
<asp:CustomValidator id="CustomValidator1" runat="server" ErrorMessage="Précision diplôme invalide" OnServerValidate="CustomValidator1_ServerValidate_1" EnableViewState="False" ClientValidationFunction="chckAutreDiplome"></asp:CustomValidator>
</td>
</tr>
<tr>
<td>
Année d'obtention*</td>
<td colspan="3">
<asp:TextBox id="txtAnDiplome" runat="server" Columns="4"></asp:TextBox>
<asp:RangeValidator id="RangeValidator1" runat="server" ErrorMessage="Année diplôme doit être dans l'intervalle [1990,2004]" ControlToValidate="txtAnDiplome" MinimumValue="1990" MaximumValue="2004" Type="Integer"></asp:RangeValidator>
<asp:RequiredFieldValidator id="RequiredFieldValidator2" runat="server" ErrorMessage="Année diplôme requise" ControlToValidate="txtAnDiplome"></asp:RequiredFieldValidator>
</td>
</tr>
</tbody>
</table>
</fieldset>
<p>
<asp:Button id="btnEnvoyer" runat="server" Text="Envoyer"></asp:Button>
</p>
</form>
</body>
</html>
[CustomValidator] bileşeninin [OnServerValidate] özniteliği, sunucu tarafında doğrulama işleminden sorumlu işlevi belirtmeye yarar. Yukarıda, [CustomValidator1] bileşeni aşağıdaki [CustomValidator1_ServerValidate_1] yordamını çağırmaktadır:
<%@ Page Language="VB" %>
<script runat="server">
Sub CustomValidator1_ServerValidate_1(sender As Object, e As ServerValidateEventArgs)
' [txtAutreDiplome] alanı, [cmbDiplomes]=QZXW2HTMLBW2F1dHJlXQZQ ise boş olmamalıdırX
e.isvalid=not (cmbDiplomes.selecteditem.text="[Autre]" and txtAutreDiplome.text.trim="") _
and not (cmbDiplomes.selecteditem.text<>"[Autre]" and cmbDiplomes.selecteditem.text<>"?" and txtAutreDiplome.text.trim<>"")
End Sub
</script>
....
[CustomValidator] bileşenine bağlı bir doğrulama işlevi iki parametre alır:
- sender: olayı tetikleyen nesne
- e: olay. Prosedür, doğrulanmış veriler doğruysa [e.IsValid] özniteliğini true olarak, aksi takdirde false olarak ayarlamalıdır.
Burada yapılan doğrulamalar şunlardır:
- [cmbDiplomes] açılır listesinin değeri [?] olamaz. Bu, [CompareValidator2] bileşeni tarafından doğrulanır
- Kullanıcı, [cmbDiplomes] açılır listesinden bir diploma seçer. Seçtiği diploma listede mevcut değilse, listeden [Autre] seçeneğini seçme imkânı vardır. Ardından, [txtAutreDiplome] giriş alanına diplomasını girmelidir. [cmbDiplomes]'te [Autre] seçiliyse, [txtAutreDiplome] alanı boş olmamalıdır. [cmbDiplomes]'te ne [Autre] ne de [?] seçiliyse, [txtAutreDiplome] alanı boş olmalıdır. Bu durum, [CustomValidator1] bileşenine bağlı işlev tarafından kontrol edilir.
- Mezuniyet yılı, [1900-2004] aralığında olmalıdır. Bu durum, [RangeValidator1] tarafından kontrol edilir. Ancak kullanıcı alana hiçbir şey girmezse, [RangeValidator1]'in doğrulama işlevi kullanılmaz. Bu nedenle, bir içeriğin varlığını doğrulamak için [RequiredFieldValidator2] bileşeni eklenir. Bu genel bir kuraldır. Bir alan boşsa içeriği doğrulanmaz. Doğrulanmasının tek istisnası, alanın [RequiredFieldValidator] bileşeniyle ilişkili olması durumudur.
İşte [Mozilla] tarayıcısında bir yürütme örneği:

[IE6] tarayıcısını kullanırsak, [CustomValidator1] bileşeni için istemci tarafında bir doğrulama işlevi ekleyebiliriz. Bunun için bu bileşen aşağıdaki özelliklere sahiptir:
- EnableClientScript=true
- ClientValidationFunction=chkAutreDiplome
[chkAutreDiplome ] işlevi şöyledir:
<head>
<meta http-equiv="pragma" content="no-cache" />
<script language="javascript">
function chkAutreDiplome(source,args){
// txtAutreDiplome alanının geçerliliğini kontrol eder
with(document.frmCandidature){
diplome=cmbDiplomes.options[cmbDiplomes.selectedIndex].text;
args.IsValid= !(diplome=="[Autre]" && txtAutreDiplome.value=="")
&& ! (diplome!="[Autre]" && diplome!="?" && txtAutreDiplome.value!="");
}
}
</script>
</head>
[chkAutreDiplome] işlevi, [CustomValidator1_ServerValidate_1] sunucu işleviyle aynı iki parametreyi alır:
- kaynak: olayı tetikleyen nesne
- args: olay. Bu olayın [IsValid] özniteliği vardır; doğrulanmış veriler doğruysa bu öznitelik işlev tarafından true olarak ayarlanmalıdır. false değeri, doğrulama bileşeninin bulunduğu yerde ilgili hata mesajını görüntüler ve form sunucuya gönderilmez.
8.2.5. RegularExpressionValidator
Aşağıdaki [regularexpressionvalidator1.aspx] sayfasını oluşturuyoruz:

no | ad | tür | özellikler | rol |
TextBox | EnableViewState=true | giriş alanı | ||
RequiredFieldValidator | ControlToValidate=txtMel Display=Dynamic | kontrolün doğrulama bileşeni [1] | ||
RegularExpressionValidator | ControlToValidate=txtMel Görüntüleme=Dinamik | kontrolün doğrulama bileşeni [1] | ||
Düğme | EnableViewState=false CausesValidation=true | [submit] düğmesi |
Burada bir e-posta adresinin biçimini doğrulamak istiyoruz. Bunu, bir düzenli ifade kullanarak bir alanın geçerliliğini doğrulamaya olanak tanıyan [RegularExpressionValidator] bileşeni ile yapıyoruz. Burada, düzenli ifadenin bir karakter dizisi şablonu olduğunu hatırlatmak isteriz. Dolayısıyla, bir alanın içeriğini bir şablona göre doğrularız. Bir alan boş olduğunda içeriği doğrulanmadığından, e-posta adresinin boş olmadığını doğrulamak için [RequiredFieldValidator] bileşenine de ihtiyacımız var. [RegularExpressionValidator] sınıfı, daha önce incelediğimiz bileşen sınıflarına benzer özelliklere sahiptir:
değeri bileşen tarafından kontrol edilmesi gereken alan | |
boole değeri – "true" ise, önceki alanın içeriğinin istemci tarafında da kontrol edilmesi gerektiğini belirtir | |
hata tespit edildiğinde bileşenin görüntülemesi gereken hata mesajı | |
[ControlToValidate] alanının içeriğinin karşılaştırılacağı düzenli ifade | |
görüntüleme modu: Static: hata mesajı görüntülenmese bile alan her zaman mevcuttur; Dynamic: alan yalnızca hata mesajı varsa mevcuttur; None: hata mesajı görüntülenmez. Bu alan diğer bileşenler için de mevcuttur ancak şimdiye kadar kullanılmamıştı. |
Bir e-posta adresinin örnek düzenli ifadesi şu şekilde olabilir: \s*[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+\s*
Bir e-posta adresi [champ1.champ2....@champA.champB...] biçimindedir. @ işaretinden önce mutlaka en az bir alan ve sonrasında en az iki alan bulunmalıdır. Bu alanlar alfanümerik karakterlerden ve - işaretinden oluşur. Alfanümerik karakter, \w sembolüyle temsil edilir. [\w-] dizisi, \w karakterini veya - karakterini ifade eder. Bir S dizisinin arkasındaki + işareti, bu dizinin 1 veya daha fazla kez tekrarlanabileceğini; * işareti, 0 veya daha fazla kez tekrarlanabileceğini; ? işareti ise 0 veya 1 kez tekrarlanabileceğini belirtir.
Bir e-posta adresi alanı, [\w-]+ şablonuna karşılık gelir. @ işaretinden önce en az bir alanın ve @ işaretinden sonra nokta (.) ile ayrılmış en az iki alanın bulunması zorunluluğu, şu şablona karşılık gelir: [\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+. Kullanıcının adresin önüne ve arkasına boşluk eklemesine izin verilebilir. Bu boşluklar işleme sırasında kaldırılacaktır. Boşluk dizisi (boş da olabilir) \s* şablonuyla temsil edilir. Dolayısıyla e-posta adresi için düzenli ifade şöyledir: \s*[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+\s*.
Sayfanın sunum kodu ise şu şekildedir:
<html>
<head>
</head>
<body>
<form runat="server">
<p align="left">
Demande du dossier de candidature au DESS
</p>
<fieldset>
<legend>[--Votre adresse électronique où sera envoyé le dossier de candidature--]</legend>
<table>
<tbody>
<tr>
<td>
<asp:TextBox id="txtMel" runat="server" Columns="60"></asp:TextBox>
</td>
</tr>
<tr>
<td>
<p>
<asp:RequiredFieldValidator id="RequiredFieldValidator3" runat="server" Display="Dynamic" ControlToValidate="txtMel" ErrorMessage="Votre adresse électronique est requise"></asp:RequiredFieldValidator>
</p>
<p>
<asp:RegularExpressionValidator id="RegularExpressionValidator1" runat="server" Display="Dynamic" ControlToValidate="txtMel" ErrorMessage="Votre adresse électronique n'a pas un format valide" ValidationExpression="\s*[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+\s*"></asp:RegularExpressionValidator>
</p>
</td>
</tr>
</tbody>
</table>
</fieldset>
<p>
<asp:Button id="btnEnvoyer" runat="server" Text="Envoyer"></asp:Button>
</p>
</form>
</body>
</html>
8.2.6. ValidationSummary
Estetik nedenlerle, hata mesajlarını aşağıdaki örnekte olduğu gibi tek bir yerde toplamak isteyebilirsiniz: [summaryvalidator1.aspx]. Burada, önceki tüm örnekleri tek bir sayfada bir araya getirdik:

Tüm doğrulama denetimleri aşağıdaki özelliklere sahiptir:
- [Display=Dynamic]; bu sayede, hata mesajı boş olan denetimler sayfada yer kaplamaz
- [EnableClientScript=false], istemci tarafında herhangi bir doğrulama yapılmasını engeller
- [Text=*]. Hata durumunda görüntülenecek mesaj budur; [ErrorMessage] özniteliğinin içeriği ise aşağıda sunduğumuz [ValidationSummary] denetimi tarafından görüntülenir.
Bu denetim grubu, [vueFormulaire] adlı [Panel] bileşenine yerleştirilmiştir. [vueErreurs] adlı başka bir [Panel] bileşenine ise bir [ValidationSummary] denetimi yerleştiriyoruz:

no | ad | tür | özellikler | rol |
1 | ValidationSummary | HeaderText=Aşağıdaki hatalar oluştu, EnableClientScript=false, ShowSummary=true | sayfadaki tüm doğrulama denetimlerinin hatalarını gösterir | |
2 | LinkButton | CausesValidation=false | formuna geri dönüş bağlantısı |
[lnkErreursToFormulaire] bağlantısı için, bu bağlantı doğrulanacak herhangi bir değer göndermediğinden doğrulama etkinleştirilmesine gerek yoktur.
Tüm veriler geçerli olduğunda, kullanıcıya aşağıdaki [infos] görünümü sunulur:

1
no | ad | tür | özellikler | rol |
1 | Etiket | kullanıcıya yönelik bilgilendirme mesajı |
Bu sayfanın sunum kodu şöyledir:
<html>
<head>
</head>
<body>
<form runat="server">
<p align="left">
Demande du dossier de candidature au DESS
</p>
<p>
<hr />
<asp:panel id="vueErreurs" runat="server">
<p align="left">
<asp:ValidationSummary id="ValidationSummary1" runat="server" ShowMessageBox="True" BorderColor="#C04000" BorderWidth="1px" BackColor="#FFFFC0" HeaderText="Les erreurs suivantes se sont produites"></asp:ValidationSummary>
</p>
<p>
<asp:LinkButton id="lnkErreursToFormulaire" onclick="lnkErreursToFormulaire_Click" runat="server" CausesValidation="False">Retour au formulaire</asp:LinkButton>
</p>
</asp:panel>
<asp:panel id="vueFormulaire" runat="server">
....
<asp:Button id="btnEnvoyer" onclick="btnEnvoyer_Click" runat="server" Text="Envoyer"></asp:Button>
</p>
</asp:panel>
<asp:panel id="vueInfos" runat="server">
<asp:Label id="lblInfo" runat="server"></asp:Label>
</asp:panel>
</form>
</body>
</html>
İşte elde edilen sonuçlardan bazı örnekler. Herhangi bir değer girmeden [formulaire] görünümünü onaylıyoruz:

[Envoyer] düğmesi bize şu yanıtı veriyor:

Görüntülenen, [erreurs] görünümüdür. Forma geri dönme bağlantısını kullanırsak, formu şu durumda buluruz:

Bu, [formulaire] görünümüdür. Hatalı verilerin yanında [*] karakteri dikkat çekiyor. Burada, doğrulama denetimlerinin [Text] alanı görüntülenmiştir. Alanları doğru şekilde doldurursak, [infos] görünümünü elde ederiz:

Sayfanın kontrol kodu şöyledir:
<%@ Page Language="VB" %>
<script runat="server">
' sayfa yüklendiğinde yürütülen işlem
Sub page_Load(sender As Object, e As EventArgs)
' ilk istekte [formulaire] görünümü sunulur
if not ispostback then
afficheVues(true,false,false)
end if
end sub
sub afficheVues(byval formulaireVisible as boolean, _
erreursVisible as boolean, infosVisible as boolean)
' görünüm kümesi
vueFormulaire.visible=formulaireVisible
vueErreurs.visible=erreursVisible
vueInfos.visible=infosVisible
end sub
Sub CustomValidator1_ServerValidate(sender As Object, e As ServerValidateEventArgs)
...
End Sub
Sub CustomValidator2_ServerValidate(sender As Object, e As ServerValidateEventArgs)
...
End Sub
Sub CustomValidator1_ServerValidate_1(sender As Object, e As ServerValidateEventArgs)
...
End Sub
Sub lnkErreursToFormulaire_Click(sender As Object, e As EventArgs)
' form görünümünü görüntüler
afficheVues(true,false,false)
' geçerlilik denetimlerini yeniden yapar
Page.validate
End Sub
Sub btnEnvoyer_Click(sender As Object, e As EventArgs)
' sayfa geçerli mi?
if not Page.IsValid then
' [erreurs] görünümü görüntülenir
afficheVues(false,true,false)
else
' aksi takdirde [infos] görünümünü görüntüler
lblInfo.Text="Le dossier de candidature au DESS IAIE a été envoyé à l'adresse ["+ _
txtMel.Text + "]. Nous vous en souhaitons bonne réception.<br><br>Le secrétariat du DESS."
afficheVues(false,false,true)
end if
end sub
</script>
<html>
...
</html>
- Müşterinin her isteğinde yürütülen [Page_Load] prosedüründe, [formulaire] görünümünü görüntüleriz; diğerleri ise gizlenir. Bu işlem yalnızca ilk istekte gerçekleştirilir. Prosedür, üç görünümü görüntülemek veya gizlemek için üç boole değeri aktarıldığı [afficheVues] yardımcı prosedürünü çağırır.
- [btnEnvoyer_Click] yordamı çağrıldığında, veri doğrulamaları tamamlanmış olur. [btnEnvoyer] düğmesi, [CausesValidation=true] özelliğine sahiptir ve bu özellik veri doğrulamasını zorlar. Tüm doğrulama denetimleri yürütülmüş ve [IsValid] özelliği ayarlanmıştır. Bu özellik, denetim tarafından doğrulanan verinin geçerli olup olmadığını gösterir. Ayrıca, sayfanın kendisinin [IsValid] özelliği de ayarlanmıştır. Bu özellik, yalnızca sayfanın tüm doğrulama denetimlerinin [IsValid] özelliğinin değeri [vrai] ise [vrai] olarak ayarlanır. Böylece [btnEnvoyer_Click] prosedürü, sayfanın geçerli olup olmadığını kontrol ederek başlar. Sayfa geçersizse, [erreurs] görünümü görüntülenir. Bu görünüm, tüm denetimlerin [ErrorMessage] özniteliklerini alan [ValidationSummary] denetimini içerir (yukarıdaki ekran görüntüsüne bakınız). Sayfa geçerliyse, bir bilgi mesajıyla birlikte [infos] görünümü görüntülenir.
- [lnkErreursToFormulaire_Click] prosedürü, [formulaire] görünümünü onaylandığı haliyle görüntülemekle görevlidir. [EnableViewState=true] özelliğine sahip [formulaire] görünümündeki tüm giriş alanlarının durumu otomatik olarak yeniden oluşturulur. İlginç bir şekilde, doğrulama bileşenlerinin durumu ise geri yüklenmez. Aslında, [erreurs] görünümüne geri döndüğümüzde, hatalı denetimlerin [Text] alanını göstermesi beklenirdi. Ancak durum böyle değildir. Bu nedenle, sayfanın [Page.Validate] yöntemini kullanarak verilerin doğrulanmasını zorladık. Bu işlem, [vueFormulaire] paneli görünür hale getirildikten sonra yapılmalıdır. Dolayısıyla toplamda iki doğrulama işlemi söz konusudur. Pratikte bu durumdan kaçınılmalıdır. Bu örnekte ise sayfa doğrulamasıyla ilgili yeni kavramları tanıtma fırsatı bulduk.
8.3. ListControl bileşenleri ve veri bağlama
İncelenen sunucu bileşenlerinden bazıları, bir değer listesinin görüntülenmesini sağlar (DropDownList, ListBox). Henüz tanıtmadığımız diğer bileşenler ise HTML tablolarında birden fazla değer listesinin görüntülenmesini sağlar. Hepsi için, program yoluyla liste değerlerini ilgili bileşene tek tek eşleştirmek mümkündür. Ayrıca, [Array], [ArrayList], [DataSet], [HashTable] gibi daha karmaşık nesneleri bu bileşenlere eşleştirmek de mümkündür, ... gibi daha karmaşık nesneler de bu bileşenlere ilişkilendirilebilir; bu da verileri bileşene bağlayan kodu basitleştirir. Bu ilişkilendirmeye veri bağlantısı denir.
[ListControl] sınıfından türetilen tüm bileşenler bir veri listesiyle ilişkilendirilebilir. Bunlar, [DropDownList], [ListBox], [CheckButtonList] ve [RadioButtonList] bileşenleridir. Bu bileşenlerin her biri bir veri kaynağına bağlanabilir. Veri kaynağı çeşitli olabilir: [Array], [ArrayList], [DataTable], [DataSet], [HashTable],...., genel olarak IEnumerable, ICollection, IListSource arayüzlerinden birini uygulayan bir nesne. Bunlardan sadece birkaçını ele alacağız. [DataSet] nesnesi, ilişkisel bir veritabanının görüntü nesnesidir. Dolayısıyla, ilişkilerle birbirine bağlanmış bir dizi tablodan oluşur. [DataTable] nesnesi ise bu tür bir tabloyu temsil eder. Veri kaynağı, [ListControl] nesnesinin her bir [Item] elemanının [Text] ve [Value] özelliklerini belirler. T, [Text]'in değeri ve V, [Value]'in değeri ise, [ListControl]'in her bir elemanı için oluşturulan HTML etiketi şöyledir:
<option value="V">T</option> | |
<input type="checkbox" value="V">T | |
<input type="radio" value="V">T |
[ListControl] bileşeninin bir veri kaynağına bağlanması aşağıdaki özellikler aracılığıyla gerçekleştirilir:
bir veri kaynağı [Array], [ArrayList], [DataTable], [DataSet], [HashTable], ... | |
veri kaynağı bir [DataSet] ise, bu, veri kaynağı olarak kullanılacak tablonun adını temsil eder. Bu durumda gerçek veri kaynağı bir tablodur. | |
veri kaynağı bir tablo olduğunda ([DataTable], [DataSet]), [ListControl] öğelerinin [Text] alanına değerlerini sağlayacak tablodaki sütunun adını temsil eder | |
veri kaynağı bir tablo olduğunda ([DataTable],[DataSet]), [ListControl] öğelerinin [Value] alanına değerlerini sağlayacak tablonun sütun adını temsil eder |
Bir [ListControl] bileşeninin bir veri kaynağına eklenmesi, bileşeni veri kaynağının değerleriyle başlatmaz. Bunu gerçekleştiren işlem [ListControl].DataBind'tir.
Veri kaynağının türüne bağlı olarak, bu kaynağın bir [ListControl] bileşenine eklenmesi farklı şekillerde gerçekleşir:
[ListControl].DataSource=A [ListControl] öğelerinin [Text] ve [Value] alanlarının değerleri, A öğelerinin değerleri olacaktır | |
[ListControl].DataSource=AL [ListControl] öğelerinin [Text] ve [Value] alanlarının değerleri, AL öğelerinin değerleri olacaktır | |
[ListControl].DataSource=DT, [ListControl].DataTextField="col1", [ListControl]. DatavalueField ="col2" burada col1 ve col2, DT tablosundaki iki sütundur. [ListControl] öğelerinin [Text] ve [Value] alanlarının değerleri, DT tablosundaki col1 ve col2 sütunlarının değerleri olacaktır | |
[ListControl].DataSource=DS, [ListControl].DataSource="table", burada "table", DS'teki tablolardan birinin adıdır. [ListControl].DataTextField="col1", [ListControl]. DatavalueField ="col2"; burada col1 ve col2, "table" tablosundaki iki sütundur. [ListControl] öğelerinin [Text] ve [Value] alanlarının değerleri, "table" tablosundaki col1 ve col2 sütunlarının değerleri olacaktır | |
[ListControl].DataSource=HT, [ListControl].DataTextField="key", [ListControl]. DatavalueField ="value" burada [key] ve [value], sırasıyla HT'in anahtarları ve değerleridir. |
Bu bilgileri aşağıdaki [databind1.aspx] örneğinde uygulayalım:
![]() |
Burada, her biri [DropDownList], [ListBox], [CheckBoxList] ve [RadioButtonList] türünde dört denetim içeren beş veri bağlantısı bulunmaktadır. İncelenen bu beş bağlantı, veri kaynakları bakımından birbirinden farklıdır:
bağlantı | veri kaynağı |
Dizi | |
ArrayList | |
DataTable | |
DataSet | |
HashTable |
8.3.1. Bileşenlerin sunum kodu
Bağlantı 1'deki denetimlerin sunum kodu şöyledir:
<td>
<asp:DropDownList id="DropDownList1" runat="server"></asp:DropDownList>
</td>
<td>
<asp:ListBox id="ListBox1" runat="server" SelectionMode="Multiple"></asp:ListBox>
</td>
<td>
<asp:CheckBoxList id="CheckBoxList1" runat="server"></asp:CheckBoxList>
</td>
<td>
<asp:RadioButtonList id="RadioButtonList1" runat="server"></asp:RadioButtonList>
</td>
2 ile 5 arasındaki bağlantıların numarası, bağlantı numarası dışında aynıdır.
8.3.2. Dizi türündeki bir veri kaynağına bağlantı
Yukarıdaki dört [ListBox] kontrolünün bağlantısı, kontrol kodundaki [Page_Load] prosedüründe şu şekilde yapılır:
' genel veriler
dim textes() as string={"un","deux","trois","quatre"}
dim valeurs() as string={"1","2","3","4"}
dim myDataListe as new ArrayList
dim myDataTable as new DataTable("table1")
dim myDataSet as new DataSet
dim myHashTable as new HashTable
' sayfa yüklendiğinde yürütülen prosedür
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
' bileşenlere bağlanacak verilerin kaynakları oluşturulur
createDataSources
' bir tabloya bağlanma [Array]
bindToArray
' bir listeye bağlanma [ArrayList]
bindToArrayList
' bir tabloya bağlantı [DataTable]
bindToDataTable
' bir veri grubuna bağlantı [DataSet]
bindToDataSet
' bir sözlüğe bağlantı [HashTable]
bindToHashTable
end if
End Sub
sub createDataSources
' bileşenlere bağlanacak veri kaynaklarını oluşturur
' arraylist
dim i as integer
for i=0 to textes.length-1
myDataListe.add(textes(i))
next
' veri tablosu
' iki sütunu tanımlanır
myDataTable.Columns.Add("id",Type.GetType("System.Int32"))
myDataTable.Columns.Add("texte",Type.GetType("System.String"))
' tablo doldurulur
dim ligne as DataRow
for i=0 to textes.length-1
ligne=myDataTable.NewRow
ligne("id")=i
ligne("texte")=textes(i)
myDataTable.Rows.Add(ligne)
next
' veri kümesi - tek bir tablo
myDataSet.Tables.Add(myDataTable)
' hashtable
for i=0 to textes.length-1
myHashTable.add(valeurs(i),textes(i))
next
end sub
' tablo bağlantısı
sub bindToArray
' bileşenlerle ilişkilendirme
with DropDownList1
.DataSource=textes
.DataBind
end with
with ListBox1
.DataSource=textes
.DataBind
end with
with CheckBoxList1
.DataSource=textes
.DataBind
end with
with RadioButtonList1
.DataSource=textes
.DataBind
end with
' öğelerin seçimi
ListBox1.Items(1).Selected=true
ListBox1.Items(3).Selected=true
CheckBoxList1.Items(0).Selected=true
CheckBoxList1.Items(3).Selected=true
DropDownList1.SelectedIndex=2
RadioButtonList1.SelectedIndex=1
end sub
sub bindToArrayList
....
end sub
sub bindToDataTable
...
end sub
sub bindToDataSet
...
end sub
Kontrollerin verilere bağlanması burada yalnızca ilk istekte gerçekleştirilir. Daha sonra kontroller, [VIEWSTATE] mekanizması aracılığıyla öğelerini koruyacaktır. Bağlantı, [bindToArray] prosedüründe gerçekleştirilir. Veri kaynağı [Array] türü olduğundan, [ListControl] bileşenlerinin yalnızca [DataSource] alanı başlatılır. Kontrolün, ilişkili veri kaynağının değerleriyle doldurulması [ListControl].DataBind yöntemi ile gerçekleştirilir. Ancak bundan sonra [ListControl] nesneleri öğelere sahip olur. Bu noktada bunlardan bazıları seçilebilir.
8.3.3. ArrayList türündeki bir veri kaynağına bağlanma
[myDataListe] veri kaynağı, [createDataSources] yordamında başlatılır:
' genel veriler
dim textes() as string={"un","deux","trois","quatre"}
dim myDataListe as new ArrayList
..
' sayfa yüklendiğinde yürütülen prosedür
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
' bileşenlere bağlanacak veri kaynakları oluşturulur
createDataSources
...
end if
End Sub
sub createDataSources
' bileşenlere bağlanacak veri kaynakları oluşturulur
' arraylist
dim i as integer
for i=0 to textes.length-1
myDataListe.add(textes(i))
next
...
end sub
Bağlantı 2'deki dört [ListBox] kontrolünün, kontrol kodundaki [bindToArrayList] prosedüründe aşağıdaki şekilde bağlanması gerekir:
' arraylist bağlantısı
sub bindToArrayList
' bileşenlere ilişkilendirme
with DropDownList2
.DataSource=myDataListe
.DataBind
end with
with ListBox2
.DataSource=myDataListe
.DataBind
end with
with CheckBoxList2
.DataSource=myDataListe
.DataBind
end with
with RadioButtonList2
.DataSource=myDataListe
.DataBind
end with
' öğelerin seçimi
ListBox2.Items(1).Selected=true
ListBox2.Items(3).Selected=true
CheckBoxList2.Items(0).Selected=true
CheckBoxList2.Items(3).Selected=true
DropDownList2.SelectedIndex=2
RadioButtonList2.SelectedIndex=1
end sub
Veri kaynağı [ArrayList] türü olduğundan, yalnızca [ListControl] bileşenlerinin [DataSource] alanı başlatılır.
8.3.4. DataTable türündeki veri kaynağı
[myDataTable] veri kaynağı, [createDataSources] yordamında başlatılır:
' genel veriler
dim textes() as string={"un","deux","trois","quatre"}
dim myDataTable as new DataTable("table1")
...
' sayfa yüklendiğinde yürütülen prosedür
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
' bileşenlere bağlanacak veri kaynakları oluşturulur
createDataSources
...
end if
End Sub
sub createDataSources
' bileşenlere bağlanacak veri kaynakları oluşturulur
...
' veri tablosu
' iki sütunu tanımlanır
myDataTable.Columns.Add("id",Type.GetType("System.Int32"))
myDataTable.Columns.Add("texte",Type.GetType("System.String"))
' tabloyu dolduruyoruz
dim ligne as DataRow
for i=0 to textes.length-1
ligne=myDataTable.NewRow
ligne("id")=i
ligne("texte")=textes(i)
myDataTable.Rows.Add(ligne)
next
...
end sub
İlk olarak, [DataTable] adlı bir nesne oluşturuyoruz; bu nesne, [id] ve [texte] adlı iki sütundan oluşuyor. [id] sütunu, [ListControl] öğelerinin [Value] alanını dolduracak ve [texte] sütunu ise [Text] alanlarını dolduracaktır. İki sütunlu [DataTable]'in oluşturulması şu şekilde yapılır:
myDataTable.Columns.Add("id",Type.GetType("System.Int32"))
myDataTable.Columns.Add("texte",Type.GetType("System.String"))
Böylece iki sütunlu bir tablo oluşturulur:
- "id" adlı ilk sütun tamsayı türündedir
- ikincisi "metin" olarak adlandırılır ve karakter dizisi türündedir
Tablonun yapısı oluşturulduktan sonra, aşağıdaki kodla doldurabiliriz:
dim ligne as DataRow
for i=0 to textes.length-1
ligne=myDataTable.NewRow
ligne("id")=i
ligne("texte")=textes(i)
myDataTable.Rows.Add(ligne)
next
[id] sütunu [0,1,..,n] tamsayılarını içerecekken, [texte] sütunu [data] tablosundaki değerleri içerecektir. Bu işlem tamamlandığında, [dataListe] tablosu doldurulur. Bağlantı 3’teki dört [ListBox] kontrolünün birbirine bağlanması, kontrol kodundaki [bindToDataTable] prosedüründe şu şekilde gerçekleştirilir:
sub bindToDataTable
' bileşenlerle ilişkilendirme
with DropDownList3
.DataSource=myDataTable
.DataValueField="id"
.DataTextField="texte"
.DataBind
end with
with ListBox3
.DataSource=myDataTable
.DataValueField="id"
.DataTextField="texte"
.DataBind
end with
with CheckBoxList3
.DataSource=myDataTable
.DataValueField="id"
.DataTextField="texte"
.DataBind
end with
with RadioButtonList3
.DataSource=myDataTable
.DataValueField="id"
.DataTextField="texte"
.DataBind
end with
' öğelerin seçilmesi
ListBox3.Items(1).Selected=true
ListBox3.Items(3).Selected=true
CheckBoxList3.Items(0).Selected=true
CheckBoxList3.Items(3).Selected=true
DropDownList3.SelectedIndex=2
RadioButtonList3.SelectedIndex=1
end sub
Her bir [ListControl] bileşeni, her birine aşağıdakiler atanarak [myDataTable] kaynağına bağlanır:
[myDataTable] tablosu veri kaynağıdır. Bu tablonun [id] sütunu, bileşen öğelerinin [Value] alanlarını doldururken, [texte] sütunu ise [Text] alanlarını dolduracaktır.
8.3.5. DataSet türündeki veri kaynağı
[myDataSet] veri kaynağı, [createDataSources] yordamında başlatılır:
' genel veriler
dim myDataTable as new DataTable("table1")
dim myDataSet as new DataSet
...
' sayfa yüklendiğinde yürütülen prosedür
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
' bileşenlere bağlanacak veri kaynakları oluşturulur
createDataSources
...
end if
End Sub
sub createDataSources
' bileşenlere bağlanacak veri kaynakları oluşturulur
' veri kümesi - tek bir tablo
myDataSet.Tables.Add(myDataTable)
...
end sub
Bir [DataSet] nesnesi, [DataTable] türündeki bir dizi tabloyu temsil eder. Daha önce oluşturulan [myDataTable] tablosu, [DataSet]'e eklenir. Bağlantı 4'teki dört [ListBox] kontrolünün birbirine bağlanması, kontrol kodundaki [bindToDataSet] yordamında şu şekilde gerçekleştirilir:
sub bindToDataSet
' bileşenlerle ilişkilendirme
with DropDownList4
.DataSource=myDataSet
.DataMember="table1"
.DataValueField="id"
.DataTextField="texte"
.DataBind
end with
with ListBox4
.DataSource=myDataSet
.DataMember="table1"
.DataValueField="id"
.DataTextField="texte"
.DataBind
end with
with CheckBoxList4
.DataSource=myDataSet
.DataMember="table1"
.DataValueField="id"
.DataTextField="texte"
.DataBind
end with
with RadioButtonList4
.DataSource=myDataSet
.DataMember="table1"
.DataValueField="id"
.DataTextField="texte"
.DataBind
end with
' öğelerin seçimi
ListBox4.Items(1).Selected=true
ListBox4.Items(3).Selected=true
CheckBoxList4.Items(0).Selected=true
CheckBoxList4.Items(3).Selected=true
DropDownList4.SelectedIndex=2
RadioButtonList4.SelectedIndex=1
end sub
Her bir [ListControl] bileşeni, veri kaynağına şu şekilde bağlanmıştır:
[myDataSet] veri grubu, veri kaynağıdır. Bu veri grubu birden fazla tablo içerebileceğinden, [DataMember]'te kullanılacak tablonun adı belirtilir. Bu tablonun [id] sütunu, bileşen öğelerinin [Value] alanlarını doldururken, [texte] sütunu ise [Text] alanlarını dolduracaktır.
8.3.6. HashTable türündeki veri kaynağı
[myHashTable] veri kaynağı, [createDataSources] yordamında başlatılır:
' genel veriler
dim textes() as string={"un","deux","trois","quatre"}
dim valeurs() as string={"1","2","3","4"}
dim myHashTable as new HashTable
...
' sayfa yüklendiğinde yürütülen prosedür
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
' bileşenlere bağlanacak veri kaynakları oluşturulur
createDataSources
...
end if
End Sub
sub createDataSources
' bileşenlere bağlanacak veri kaynakları oluşturulur
...
' hash tablosu
for i=0 to textes.length-1
myHashTable.add(valeurs(i),textes(i))
next
end sub
[myHashTable] sözlüğü, "anahtar" ve "değer" adlı iki sütundan oluşan bir tablo olarak görülebilir. [key] sütunu sözlüğün anahtarlarını, [value] sütunu ise bunlara ilişkin değerleri temsil eder. [key] sütunu, [valeurs] tablosunun içeriğinden, [value] sütunu ise [textes] tablosunun içeriğinden oluşur. Bu kaynağın denetimlerle ilişkilendirilmesi, [bindToHashTable] yordamında gerçekleştirilir:
sub bindToHashTable
' bileşenlerle ilişkilendirme
with DropDownList5
.DataSource=myHashTable
.DataValueField="key"
.DataTextField="value"
.DataBind
end with
with ListBox5
.DataSource=myHashTable
.DataValueField="key"
.DataTextField="value"
.DataBind
end with
with CheckBoxList5
.DataSource=myHashTable
.DataValueField="key"
.DataTextField="value"
.DataBind
end with
with RadioButtonList5
.DataSource=myHashTable
.DataValueField="key"
.DataTextField="value"
.DataBind
end with
' öğelerin seçilmesi
ListBox5.Items(1).Selected=true
ListBox5.Items(3).Selected=true
CheckBoxList5.Items(0).Selected=true
CheckBoxList5.Items(3).Selected=true
DropDownList5.SelectedIndex=2
RadioButtonList5.SelectedIndex=1
end sub
Her bir bileşen için bağlantı şu komutlarla yapılır:
Veri kaynağı, [myHashTable] sözlüğüdür. Kontrol değerleri, sözlüğün [key] sütunundan, metinler ise [value] sütunundan sağlanır. Sözlük öğelerinin kontrollere eklenmesi, öncelikle rastgele olan anahtar sırasına göre yapılır.
8.3.7. Ad alanlarını içe aktarma yönergeleri
Bir dizi ad alanı, ASP.NET sayfasına otomatik olarak içe aktarılır. Ancak, [DataTable] ve [DataSet] sınıflarının bulunduğu "System.Data" için durum böyle değildir. Bu nedenle bu sınıfın da içe aktarılması gerekir. Bu işlem şu şekilde yapılır:
<%@ Page Language="VB" %>
<%@ import Namespace="System.Data" %>
<script runat="server">
...
</script>
<html>
...
</html>
8.4. DataGrid bileşeni ve veri bağlantısı
[DataGrid] bileşeni, verileri tablo şeklinde görüntülemeye olanak tanır, ancak bu basit görüntülemenin çok ötesine geçer:
- tablonun "görsel sunumunu" hassas bir şekilde ayarlama imkanı sunar
- veri kaynağının güncellenmesine olanak tanır
[DataGrid] bileşeni, hem güçlü hem de karmaşık bir bileşendir. Bu bileşeni adım adım tanıtacağız.
8.4.1. Bir Array veri kaynağının görüntülenmesi, ArrayList, DataTable, DataSet
[DataGrid] bileşeni, HTML tablosunda [Array], [ArrayList], [DataTable] ve [DataSet] türündeki veri kaynaklarını görüntülemenizi sağlar. Bu dört veri türü için, kaynağı [DataGrid] bileşeninin [DataSource] özelliğine atamanız yeterlidir:
bir veri kaynağı [Array], [ArrayList], [DataTable], [DataSet], ... | |
Veri kaynağı bir [DataSet] ise, bu alan veri kaynağı olarak kullanılacak tablonun adını temsil eder. Bu durumda gerçek veri kaynağı bir tablodur. Bu alan doldurulmazsa, [DataSet]'teki tüm tablolar görüntülenir. |
Şimdi, bir [DataGrid]'in dört farklı veri kaynağıyla ilişkilendirildiğini gösteren [datagrid1.aspx] sayfasını sunuyoruz:

Sayfa, [WebMatrix] kullanılarak aşağıdaki şekilde oluşturulmuş dört adet [DataGrid] bileşeni içerir. Bileşen, [Design] sekmesindeki yerine yerleştirilir:

Ardından genel bir HTML tablosu çizilir. Bir [DataGrid]'in özellikleri tasarım aşamasında tanımlanabilir. Burada, biçimlendirme özelliklerini bu şekilde tanımlıyoruz. Bunun için, yapılandırılacak [DataGrid]'i seçiyoruz. Özellikleri sağ alt köşedeki bir pencerede görüntülenir:

Yukarıdaki iki bağlantıyı da kullanacağız. [Générateur de propriétés] bağlantısı, [DataGrid]'in temel özelliklerine erişim sağlar:

Dört bileşen olan [DataGrid] için [Afficher l'en-tête] seçeneğinin işaretini kaldırıp sayfayı onaylıyoruz. Diğer bağlantı olan [Mise en forme automatique] ise görüntülenecek HTML tablosu için çeşitli stiller arasından seçim yapmamızı sağlar:

i numaralı [DataGrid] için [couleur i]'i seçiyoruz. Bu tasarım seçimleri, sayfanın sunum koduna yansıtılır:
<html>
<head>
</head>
<body>
<form runat="server">
<p>
Liaison de données avec un DataGrid
</p>
<hr />
<p>
<table>
<tbody>
</tbody>
</table>
<table border="1">
<tbody>
<tr>
<td>
Array</td>
<td>
ArrayList</td>
<td>
DataTable</td>
<td>
DataSet</td>
</tr>
<tr>
<td>
<asp:DataGrid id="DataGrid1" runat="server" ShowHeader="False" CellPadding="4" BackColor="White" BorderColor="#CC9966" BorderWidth="1px" BorderStyle="None">
<FooterStyle forecolor="#330099" backcolor="#FFFFCC"></FooterStyle>
<HeaderStyle font-bold="True" forecolor="#FFFFCC" backcolor="#990000"></HeaderStyle>
<PagerStyle horizontalalign="Center" forecolor="#330099" backcolor="#FFFFCC"></PagerStyle>
<SelectedItemStyle font-bold="True" forecolor="#663399" backcolor="#FFCC66"></SelectedItemStyle>
<ItemStyle forecolor="#330099" backcolor="White"></ItemStyle>
</asp:DataGrid>
</td>
<td>
<asp:DataGrid id="DataGrid2" runat="server" ShowHeader="False" CellPadding="4" BackColor="White" BorderColor="#3366CC" BorderWidth="1px" BorderStyle="None">
<FooterStyle forecolor="#003399" backcolor="#99CCCC"></FooterStyle>
<HeaderStyle font-bold="True" forecolor="#CCCCFF" backcolor="#003399"></HeaderStyle>
<PagerStyle horizontalalign="Left" forecolor="#003399" backcolor="#99CCCC" mode="NumericPages"></PagerStyle>
<SelectedItemStyle font-bold="True" forecolor="#CCFF99" backcolor="#009999"></SelectedItemStyle>
<ItemStyle forecolor="#003399" backcolor="White"></ItemStyle>
</asp:DataGrid>
</td>
<td>
<asp:DataGrid id="DataGrid3" runat="server" ShowHeader="False" CellPadding="3" BackColor="#DEBA84" BorderColor="#DEBA84" BorderWidth="1px" BorderStyle="None" CellSpacing="2">
<FooterStyle forecolor="#8C4510" backcolor="#F7DFB5"></FooterStyle>
<HeaderStyle font-bold="True" forecolor="White" backcolor="#A55129"></HeaderStyle>
<PagerStyle horizontalalign="Center" forecolor="#8C4510" mode="NumericPages"></PagerStyle>
<SelectedItemStyle font-bold="True" forecolor="White" backcolor="#738A9C"></SelectedItemStyle>
<ItemStyle forecolor="#8C4510" backcolor="#FFF7E7"></ItemStyle>
</asp:DataGrid>
</td>
<td>
<asp:DataGrid id="DataGrid4" runat="server" ShowHeader="False" CellPadding="3" BackColor="White" BorderColor="#E7E7FF" BorderWidth="1px" BorderStyle="None" GridLines="Horizontal">
<FooterStyle forecolor="#4A3C8C" backcolor="#B5C7DE"></FooterStyle>
<HeaderStyle font-bold="True" forecolor="#F7F7F7" backcolor="#4A3C8C"></HeaderStyle>
<PagerStyle horizontalalign="Right" forecolor="#4A3C8C" backcolor="#E7E7FF" mode="NumericPages"></PagerStyle>
<SelectedItemStyle font-bold="True" forecolor="#F7F7F7" backcolor="#738A9C"></SelectedItemStyle>
<AlternatingItemStyle backcolor="#F7F7F7"></AlternatingItemStyle>
<ItemStyle forecolor="#4A3C8C" backcolor="#E7E7FF"></ItemStyle>
</asp:DataGrid>
</td>
</tr>
</tbody>
</table>
</p>
<asp:Button id="Button1" runat="server" Text="Envoyer"></asp:Button>
</form>
</body>
</html>
Tasarım modunda yalnızca biçimlendirme özelliklerini belirledik. Dört bileşene verileri atadığımız yer kontrol kodudur:
<%@ Page Language="VB" %>
<%@ import Namespace="system.data" %>
<script runat="server">
' genel veriler
dim textes1() as string={"un","deux","trois","quatre"}
dim textes2() as string={"one","two","three","for"}
dim valeurs() as string={"1","2","3","4"}
dim myDataListe as new ArrayList
dim myDataTable as new DataTable("table1")
dim myDataSet as new DataSet
' sayfa yüklendiğinde yürütülen prosedür
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
' bileşenlere bağlanacak veri kaynakları oluşturulur
createDataSources
' bir tabloya bağlanma [Array]
bindToArray
' bir listeye bağlanma [ArrayList]
bindToArrayList
' bir tabloya bağlantı [DataTable]
bindToDataTable
' bir veri grubuna bağlantı [DataSet]
bindToDataSet
end if
End Sub
sub createDataSources
' bileşenlere bağlanacak veri kaynaklarını oluşturur
' arraylist
dim i as integer
for i=0 to textes1.length-1
myDataListe.add(textes1(i))
next
' datatable
' iki sütunu tanımlanır
myDataTable.Columns.Add("id",Type.GetType("System.Int32"))
myDataTable.Columns.Add("texte1",Type.GetType("System.String"))
myDataTable.Columns.Add("texte2",Type.GetType("System.String"))
' tablo doldurulur
dim ligne as DataRow
for i=0 to textes1.length-1
ligne=myDataTable.NewRow
ligne("id")=valeurs(i)
ligne("texte1")=textes1(i)
ligne("texte2")=textes2(i)
myDataTable.Rows.Add(ligne)
next
' veri kümesi - tek bir tablo
myDataSet.Tables.Add(myDataTable)
end sub
' dizi bağlantısı
sub bindToArray
with DataGrid1
.DataSource=textes1
.DataBind
end with
end sub
' dizi listesi bağlantısı
sub bindToArrayList
with DataGrid2
.DataSource=myDataListe
.DataBind
end with
end sub
' veri tablosu bağlantısı
sub bindToDataTable
with DataGrid3
.DataSource=myDataTable
.DataBind
end with
end sub
' veri kümesi bağlantısı
sub bindToDataSet
with DataGrid4
.DataSource=myDataSet
.DataBind
end with
end sub
</script>
<html>
...
</html>
Kod, önceki örnektekine oldukça benziyor, bu nedenle bu konuda özel bir açıklama yapmayacağız. Ancak, veri bağlamanın nasıl yapıldığına dikkat edelim. Dört kontrolün her biri için aşağıdaki dizi yeterlidir:
burada [source de données], [Array], [ArrayList], [DataTable] veya [DataSet] türündedir. Görüldüğü gibi, burada tablolar halinde veri görüntülemek için güçlü bir araç söz konusudur:
- biçimlendirme, tasarım aşamasında [WebMatrix] veya herhangi bir IDE ile yapılır
- veri bağlantısı ise kodda yapılır. [WebMatrix] ile, veri kaynağı bir SQL sunucu veritabanı veya bir ACCESS veritabanı ise, bu bağlantı tasarım aşamasında da yapılabilir. Bu durumda, sayfaya [SqlDataSource] veya [AccessDataSource] türünde bir bileşen yerleştirilir. Bu bileşen, tasarım aşamasında duruma göre bir SQL sunucu veritabanına veya bir ACCESS veritabanına bağlanabilir. Bir [DataGrid] bileşeninin [DataSource] özelliğine, fiziksel bir kaynağa bağlı bir [SqlDataSource] veya [AccessDataSource] nesnesi atanırsa, tasarım modunda [DataGrid] bileşeninde gerçek veriler görünür.
8.5. ViewState veri listesi bileşenleri
Burada, veri listesi bileşenleri için [VIEWSATE] mekanizmasını ele alacağız. Bir veri listesi bileşeninin durumunu iki istemci isteği arasında korumak için iki yöntem arasında tereddüt edilebilir:
- [VIEWSTATE] özniteliğini "true" olarak ayarlamak
- [VIEWSTATE] özniteliğini "false" olarak ayarlamak ve bir sonraki istek sırasında bileşeni bu kaynağa bağlayabilmek için veri kaynağını oturumda saklamak.
Aşağıdaki örnek, veri kapsayıcılarının [VIEWSTATE] mekanizmasının bazı yönlerini göstermektedir. Müşterinin ilk isteğinde, uygulama aşağıdaki görünümü sunar:
![]() |
no | ad | tür | özellikler | rol |
1 | DataGrid | EnableViewState=true | bir S veri kaynağını görüntüler | |
2 | DataGrid | EnableViewState=true | [DataGrid1] ile aynı S kaynağını görüntüler | |
3 | Düğme | EnableViewState=false | [submit] düğmesi |
[DataGrid1] bileşeni, [VIEWSTATE] mekanizması tarafından yönetilir. Her istekte [DataGrid1]'in görüntüsünü yeniden oluşturan bu mekanizmanın, veri kaynağını da yeniden oluşturup oluşturmadığını araştırıyoruz. Bunun için veri kaynağı, [DataGrid2] bileşenine bağlanmıştır. Bu bileşenin her istekte oluşturulması, [DataGrid1] veri kaynağına açık bir bağlantı aracılığıyla gerçekleştirilir. Ayrıca, [EnableViewState] özniteliği de [vrai]'e aittir.
Uygulamanın [main.aspx] sunum kodu şöyledir:
<%@ page src="main.aspx.vb" inherits="main" autoeventwireup="false" %>
<HTML>
<HEAD>
<title></title>
</HEAD>
<body>
<form runat="server">
<table>
<tr>
<td align="center">DataGrid 1</td>
<td align="center">
DataGrid 2</td>
</tr>
<tr>
<td>
<asp:DataGrid id="DataGrid1" runat="server" ...>
<SelectedItemStyle ...></SelectedItemStyle>
....
</asp:DataGrid></td>
<td>
<asp:DataGrid id="Datagrid2" runat="server" ...>
....
</asp:DataGrid></td>
</tr>
</table>
<asp:Button id="Button1" runat="server" Text="Envoyer"></asp:Button>
</form>
</body>
</HTML>
[main.aspx.vb] denetleyicisi ise şöyledir:
Imports System.Data
Public Class main
Inherits System.Web.UI.Page
Protected WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid
Protected WithEvents Datagrid2 As System.Web.UI.WebControls.DataGrid
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' İlk sorguda veri kaynağı tanımlanır ve ilk veri tablosuna bağlanır
If Not IsPostBack Then
'veri kaynağını tanımla
With DataGrid1
.DataSource = createDataSource()
.DataBind()
End With
End If
' her sorguda, datagrid2'yi ilk datagrid'in kaynağıyla bağlar
With Datagrid2
.DataSource = DataGrid1.DataSource
.DataBind()
End With
End Sub
Private Function createDataSource() As DataTable
' veri kaynağı başlatılır
Dim thèmes As New DataTable
' sütunlar
With thèmes.Columns
.Add("id", GetType(System.Int32))
.Add("thème", GetType(System.String))
.Add("description", GetType(System.String))
End With
' id sütunu birincil anahtar olacaktır
thèmes.Constraints.Add("cléprimaire", thèmes.Columns("id"), True)
' satırlar
Dim ligne As DataRow
For i As Integer = 0 To 4
ligne = thèmes.NewRow
ligne.Item("id") = i.ToString
ligne.Item("thème") = "thème" + i.ToString
ligne.Item("description") = "description du thème " + i.ToString
thèmes.Rows.Add(ligne)
Next
Return thèmes
End Function
Private Sub InitializeComponent()
End Sub
End Class
[createDataSource] yöntemi, [DataTable] türünde bir S kaynağı oluşturur. Bu kod, örneğimizin konusu olmadığı için üzerinde durmayacağız. Bizi ilgilendiren, iki [DataGrid] bileşenini oluşturmak için kullanılan yöntemdir:
- [DataGrid1] bileşeni, ilk sorgu sırasında S tablosuna bir kez bağlanır. Daha sonra bu bağlantı kesilir.
- [DataGrid2] bileşeni, her yeni sorguda [DataGrid1.DataSource] kaynağına bağlanır.
İlk sorguda şu görünüm elde edilir:

Mantıklı bir şekilde, her iki bileşen de kendilerine bağlandıkları veri kaynağını görüntüler. [Envoyer] düğmesini kullanarak sunucuya bir [PostBack] isteği göndeririz. Elde ettiğimiz görünüm şöyledir:

[DataGrid1] bileşeninin değerini koruduğunu, ancak [DataGrid2] bileşeninin değerini korumadığını görüyoruz. Açıklama:
- [Page_Load] prosedürü başlamadan önce bile, [DataGrid1] ve [DataGrid2] nesneleri, [viewstate] mekanizması nedeniyle önceki sorguda sahip oldukları değeri geri almışlardır. Nitekim her ikisinin de [EnableViewState] özelliği, [vrai] olarak ayarlanmıştır.
- [Page_Load] prosedürü yürütülür. Burada bir [PostBack] işlemiyle karşı karşıya olduğumuzdan, [DataGrid1] bileşeni [Page_Load] tarafından değiştirilmez (koduna bakınız). Bu nedenle, [viewstate] sayesinde alınan değeri korur. Yukarıdaki ekran görüntüsü bunu göstermektedir.
- [DataGrid2] bileşeni ise [DataBind] aracılığıyla [DataGrid1.DataSource] veri kaynağına bağlıdır. Dolayısıyla yeniden oluşturulur ve [viewstate] sayesinde az önce aldığı değer kaybolur. Bu durumda, durumunun gereksiz yere yönetilmesini önlemek için bu bileşenin [EnableViewState] özelliğinin [faux]'e ayarlanması daha uygun olurdu. Yukarıdaki ekran görüntüsü, [DataGrid2]'in boş bir kaynağa bağlandığını göstermektedir. Bu kaynak [DataGrid1.DataSource] olduğundan, bundan şu sonuç çıkarılabilir: [viewstate] mekanizması, [DataGrid1] bileşeninin görüntüsünü düzgün bir şekilde geri yüklesede, [DataSource] gibi özelliklerini geri yüklemez.
Bu örnekten ne sonuç çıkarılabilir? Bir veri konteynerinin [EnableViewState] özelliğini [vrai] olarak ayarlamaktan kaçınılmalıdır; çünkü bu konteyner her sorguda bir veri kaynağına (DataBind) bağlanmalıdır. Ancak, bu durumda bile veri konteynerinin [EnableViewState] özelliğinin [vrai] olarak tutulması gereken bazı durumlar vardır; aksi takdirde yönetilmek istenen olaylar tetiklenmez. Bununla ilgili bir örnekle karşılaşacağız.
Çoğu zaman, bir veri konteynerinin veri kaynağı istekler ilerledikçe değişir. Bu nedenle, her istekte konteyneri veri kaynağına bağlamak gerekir. İsteklerin bu kaynağa erişebilmesi için kaynağın oturumda tutulması yaygın bir uygulamadır. İkinci örneğimiz bu mekanizmayı göstermektedir. Uygulama yalnızca tek bir görünüm sunar:
![]() |
No. | ad | tür | özellikler | rol |
1 | DataGrid | EnableViewState=true | bir S veri kaynağını görüntüler | |
2 | DataGrid | EnableViewState=false | [DataGrid1] ile aynı S kaynağını görüntüler | |
3 | Düğme | EnableViewState=false | düğme [submit] | |
4 | Etiket | EnableViewState=false | bilgilendirici metinler |
[DataGrid1] bileşeni, yalnızca ilk sorguda verilerle ilişkilendirilir. [viewstate] mekanizması sayesinde, sonraki sorgularda da değerini korur. [DataGrid2] bileşeni, her yeni istekte bir öğe eklenen bir veri kaynağına her istekte bağlanır. Bu nedenle, [DataGrid2] bileşenini her isteğe (DataBind) bağlamak gerekir. Bu nedenle, daha önce önerildiği gibi, [EnableViewState] özniteliğini [faux] olarak ayarladık. Böylece, ikinci sorguda ([Envoyer] düğmesinin kullanılmasıyla), şu yanıtı alıyoruz:

[DataGrid1] bileşeni başlangıç değerini korumuştur. [DataGrid2] bileşeninde bir öğe daha bulunmaktadır. [1,2,2]'teki üç bilgi, istek numarasını temsil etmektedir. Bu bilgilerden birinin hatalı olduğu görülüyor. Bunun nedenini anlamaya çalışacağız.
Uygulamanın [main.aspx] sunum kodu şu şekildedir:
<%@ Page src="main.aspx.vb" inherits="main" autoeventwireup="false" Language="vb" %>
<HTML>
<HEAD>
<title></title>
</HEAD>
<body>
<form runat="server">
<table>
<tr>
<td align="center" bgColor="#ccffcc">DataGrid 1</td>
<td align="center" bgColor="#ffff99">DataGrid 2</td>
</tr>
<tr>
<td vAlign="top">
<asp:DataGrid id="DataGrid1" runat="server" ...>
...
</asp:DataGrid>
</td>
<td vAlign="top">
<asp:DataGrid id="Datagrid2" runat="server" ... EnableViewState="False">
....
</asp:DataGrid>
</td>
</tr>
</table>
<P>Numéro de requête :
<asp:Label id="lblInfo1" runat="server" EnableViewState="False"></asp:Label>,
<asp:Label id="lblInfo2" runat="server" EnableViewState="False"></asp:Label>,
<asp:Label id="lblInfo3" runat="server" EnableViewState="False"></asp:Label></P>
<P>
<asp:Button id="Button1" runat="server" Text="Envoyer" EnableViewState="False"></asp:Button></P>
</form>
</body>
</HTML>
[main.aspx.vb] denetleyicisinin kodu şöyledir:
Imports System.Data
Imports System
Public Class main
Inherits System.Web.UI.Page
Protected WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid
Protected WithEvents Datagrid2 As System.Web.UI.WebControls.DataGrid
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents lblInfo1 As System.Web.UI.WebControls.Label
Protected WithEvents lblInfo2 As System.Web.UI.WebControls.Label
Protected WithEvents lblInfo3 As System.Web.UI.WebControls.Label
Dim dtThèmes As DataTable
Dim numRequête1 As Integer
Dim numRequête2 As Integer
Dim numRequête3 As New entier
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' İlk sorguda veri kaynağı tanımlanır ve 1. veri tablosuna bağlanır
If Not IsPostBack Then
'veri kaynağını tanımla
dtThèmes = createDataSource()
With DataGrid1
.DataSource = dtThèmes
.DataBind()
End With
' bilgileri oturumda saklayın
Session("source") = dtThèmes
numRequête1 = 0 : Session("numRequête1") = numRequête1
numRequête2 = 0 : Session("numRequête2") = numRequête2
numRequête3.valeur = 0 : Session("numRequête3") = numRequête3
End If
' her sorguda yeni bir tema eklenir
dtThèmes = CType(Session("source"), DataTable)
Dim nbThèmes = dtThèmes.Rows.Count
Dim ligne As DataRow = dtThèmes.NewRow
With ligne
.Item("id") = nbThèmes.ToString
.Item("thème") = "thème" + nbThèmes.ToString
.Item("description") = "description du thème " + nbThèmes.ToString
End With
dtThèmes.Rows.Add(ligne)
'veri tablosu 2'yi veri kaynağıyla ilişkilendir
With Datagrid2
.DataSource = dtThèmes
.DataBind()
End With
' istek sayısı bilgileri
numRequête1 = CType(Session("numRequête1"), Integer)
numRequête1 += 1
lblInfo1.Text = numRequête1.ToString
numRequête2 = CType(Session("numRequête2"), Integer)
numRequête2 += 1
lblInfo2.Text = numRequête2.ToString
numRequête3 = CType(Session("numRequête3"), entier)
numRequête3.valeur += 1
lblInfo3.Text = numRequête3.valeur.ToString
' oturumda bazı bilgiler saklanır
Session("numRequête2") = numRequête2
End Sub
Private Function createDataSource() As DataTable
....
End Function
End Class
Public Class entier
Private _valeur As Integer
Public Property valeur() As Integer
Get
Return _valeur
End Get
Set(ByVal Value As Integer)
_valeur = Value
End Set
End Property
End Class
[createDataSource] yönteminin kodunu buraya aktarmadık. Bu kod, önceki uygulamadakiyle aynıdır; tek fark, kaynak kodda sadece üç satır yer almasıdır. Öncelikle veri kaynağının ve iki konteynerin yönetimine bakalım:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' İlk istekte veri kaynağı tanımlanır ve ilk datagrid'e bağlanır
If Not IsPostBack Then
'veri kaynağını tanımla
dtThèmes = createDataSource()
With DataGrid1
.DataSource = dtThèmes
.DataBind()
End With
' bilgileri oturumda saklama
Session("source") = dtThèmes
...
End If
' her istekte yeni bir tema eklenir
dtThèmes = CType(Session("source"), DataTable)
Dim nbThèmes = dtThèmes.Rows.Count
Dim ligne As DataRow = dtThèmes.NewRow
With ligne
.Item("id") = nbThèmes.ToString
.Item("thème") = "thème" + nbThèmes.ToString
.Item("description") = "description du thème " + nbThèmes.ToString
End With
dtThèmes.Rows.Add(ligne)
'veri tablosu 2'yi veri kaynağıyla ilişkilendir
With Datagrid2
.DataSource = dtThèmes
.DataBind()
End With
...
End Sub
[DataGrid1] bileşeni, yalnızca ilk sorguda S veri kaynağına bağlanır (IsPostBack değil). Bu bileşen daha sonra oturuma yerleştirilir. Daha sonraki sorgularda oturuma yerleştirilmez. Oturuma yerleştirilen S veri kaynağı her sorguda alınır ve ona yeni bir satır eklenir. [DataGrid2] bileşeni ise her sorguda S veri kaynağına açıkça bağlanır. Bu nedenle içeriği her sorguda bir satır artar. S veri kaynağının içeriği değiştirildikten sonra, bu kaynağın bir işlemle oturuma açıkça yeniden eklenmediği görülür:
Neden? Bir istek başladığında, oturumun içinde [DataTable] türünde bir Session("source") nesnesi bulunur; bu nesne, son istek sırasındaki haliyle veri kaynağını temsil eder. Bu Session("source") nesnesine S diyelim. Şu kodunu yazdığımızda:
dtThèmes = CType(Session("source"), DataTable)
[dtThèmes] ve [S], aynı [DataTable] nesnesine ait iki referanstır. Dolayısıyla, [Page_Load] kodunda [dtThèmes] tarafından referans verilen tabloya bir öğe eklendiğinde, bu öğe aynı anda [S] tarafından referans verilen tabloya da eklenir. Sayfanın yürütülmesi tamamlandığında, oturumda bulunan tüm nesneler kaydedilecektir; dolayısıyla Session("source") nesnesi, c.a.d. S, c.a.d ve [dtThèmes] nesneleri de kaydedilecektir. Dolayısıyla, veri kaynağının yeni içeriği kaydedilmiş olur. Aşağıdaki kodun yazılmasına gerek kalmamıştır:
Bu kaydı yapmak için, çünkü Session("source") zaten [dtThèmes] değerine eşittir. Oturuma aktarılan veriler, [Integer, Float, ...] yapıları gibi nesneler olmadığında bu durum geçerli değildir. İstek sayaçlarının yönetimi de bunu göstermektedir:
Dim numRequête1 As Integer
Dim numRequête2 As Integer
Dim numRequête3 As New entier
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' İlk istekte veri kaynağı tanımlanır ve ilk datagrid'e bağlanır
....
' bilgileri oturumda saklamak
Session("source") = dtThèmes
numRequête1 = 0 : Session("numRequête1") = numRequête1
numRequête2 = 0 : Session("numRequête2") = numRequête2
numRequête3.valeur = 0 : Session("numRequête3") = numRequête3
End If
' her sorguda yeni bir tema eklenir
....
' istek sayısı bilgileri
numRequête1 = CType(Session("numRequête1"), Integer)
numRequête1 += 1
lblInfo1.Text = numRequête1.ToString
numRequête2 = CType(Session("numRequête2"), Integer)
numRequête2 += 1
lblInfo2.Text = numRequête2.ToString
numRequête3 = CType(Session("numRequête3"), entier)
numRequête3.valeur += 1
lblInfo3.Text = numRequête3.valeur.ToString
' oturumda bazı bilgiler saklanır
Session("numRequête2") = numRequête2
End Sub
Private Function createDataSource() As DataTable
....
End Function
Private Sub InitializeComponent()
End Sub
End Class
Public Class entier
Private _valeur As Integer
Public Property valeur() As Integer
Get
Return _valeur
End Get
Set(ByVal Value As Integer)
_valeur = Value
End Set
End Property
İstek sayaçları üç öğede saklanır:
- numRequête1 ve numRequête2 ([Integer] türünde) - [Integer] bir sınıf değil, bir yapıdır
- numRequête3, [entier] türündedir - [entier] ise bu amaçla tanımlanmış bir sınıftır
Şu kod yazıldığında:
numRequête1 = CType(Session("numRequête1"), Integer)
..
numRequête2 = CType(Session("numRequête2"), Integer)
..
numRequête3 = CType(Session("numRequête3"), entier)
..
- [Session("numRequête1")] yapısı, [numRequête1]'e kopyalanır. Dolayısıyla, [numRequête1] öğesi değiştirildiğinde, [Session("numRequête1")] öğesi değiştirilmez
- Aynı durum [Session("numRequête2")] ve [numRequête2] için de geçerlidir
- [Session("numRequête3")] ve [numRequête3] öğeleri ise, her ikisi de [entier] türündeki aynı nesneye referans vermektedir. Referans verilen nesne, bu referanslardan herhangi biri aracılığıyla değiştirilebilir.
Bundan, şunu yazmanın gereksiz olduğu sonucuna varılır:
yazmanın gereksiz olduğu sonucuna varılır. Bunun yerine şunu yazmak gerekir:
yazmak gerekir. Bunu yalnızca [numRequête2] için yapıyoruz; bu da ikinci sorgunun sonucunda elde edilen ekran görüntüsünde [numRequête1] sayacının hatalı olmasının nedenini açıklıyor.
Dolayısıyla şunu unutmamak gerekir: Bir veri, oturuma bir kez eklendikten sonra, bir nesne ile temsil ediliyorsa tekrar tekrar eklenmesine gerek yoktur. Diğer durumlarda ise, veri değiştirilmişse bu işlem yapılmalıdır.
8.6. Sayfalandırılmış ve sıralanmış bir DataGrid kullanarak veri listesinin görüntülenmesi
[DataGrid] bileşeni, bir [DataSet]'in içeriğini görüntülemeye olanak tanır. Şu ana kadar [DataSet]'lerimizi her zaman "elle" oluşturduk. Bu sefer, bir veritabanından alınan bir [DataSet] kullanıyoruz. Aşağıdaki MVC uygulamasını oluşturuyoruz:
![]() |
Üç görünüm, [main.aspx] denetleyicisinin sunum koduna konteynerler şeklinde eklenecek. Dolayısıyla bu uygulamanın tek bir sayfası var: [main.aspx].
8.6.1. İşlev sınıfları
[produits] sınıfı, aşağıdaki ACCESS veritabanına erişim sağlar:

[produits] sınıfının kodu şöyledir:
Imports System
Imports System.Data
Imports System.Data.OleDb
Imports System.Xml
Namespace st.istia.univangers.fr
Public Class produits
Private chaineConnexionOLEDB As String
Public Sub New(ByVal chaineConnexionOLEDB As String)
' bağlantı dizesi saklanır
Me.chaineConnexionOLEDB = chaineConnexionOLEDB
End Sub
Public Function getDataSet(ByVal commande As String) As DataSet
' DataAdapter nesnesi oluşturulur ve OLEDB kaynağındaki veriler okunur
Dim adaptateur As New OleDbDataAdapter(commande, chaineConnexionOLEDB)
' SELECT sorgusunun sonucunun bellekteki görüntüsü oluşturulur
Dim contenu As New DataSet
Try
adaptateur.Fill(contenu)
Catch e As Exception
Throw New Exception("Erreur d'accès à la base de données (" + e.Message + ")")
End Try
' sonuç döndürülür
Return contenu
End Function
End Class
End Namespace
ACCESS veritabanı, OLEDB sürücüsü aracılığıyla yönetilecektir. [produits] sınıfının oluşturucusuna, kimlik bilgilerini içeren bağlantı dizesi, OLEDB sürücüsü ve yönetilmesi gereken veritabanı verilir. [produits] sınıfı,metodunun içinde metin parametre olarak geçirilir. Metodun işleyişi sırasında birkaç işlem gerçekleşir: veritabanına bağlantı kurulması, [select]'in çalıştırılması, bağlantının kapatılması. Tüm bunlar bir istisna oluşturabilir ve bu istisna burada yönetilir. Bir test programı şu şekilde olabilir:
Option Explicit On
Option Strict On
' ad alanları
Imports System
Imports System.Data
Imports Microsoft.VisualBasic
Namespace st.istia.univangers.fr
' test sayfası
Module testproduits
Sub Main(ByVal arguments() As String)
' ürün tablosunun içeriğini görüntüler
' tablo, pg'nin dosya adını aldığı ACCESS veritabanında bulunuyor
Const syntaxe1 As String = "pg bdACCESS"
' program parametrelerinin doğrulanması
If arguments.Length <> 1 Then
' hata mesajı
Console.Error.WriteLine(syntaxe1)
' son
Environment.Exit(1)
End If
' bağlantı dizesi hazırlanıyor
Dim chaineConnexion As String = "Provider=Microsoft.Jet.OLEDB.4.0; Ole DB Services=-4; Data Source=" + arguments(0)
' ürün nesnesinin oluşturulması
Dim objProduits As produits = New produits(chaineConnexion)
' ürün tablosu bir veri kümesine alınıyor
Dim contenu As DataSet
Try
contenu = objProduits.getDataSet("select id,nom,prix from liste")
Catch ex As Exception
Console.Error.WriteLine(("L'erreur suivante s'est produite : " + ex.Message))
Environment.Exit(2)
End Try
' içeriği görüntüleniyor
Dim lignes As DataRowCollection = contenu.Tables(0).Rows
For i As Integer = 0 To lignes.Count - 1
' tablonun i. satırı
Console.Out.WriteLine(lignes(i).Item("id").ToString + "," + lignes(i).Item("nom").ToString + _
"," + lignes(i).Item("prix").ToString)
Next
End Sub
End Module
End Namespace
Bu uygulamanın çeşitli öğelerinin derlenmesi şu şekilde gerçekleştirilir:
dos>vbc /t:library /r:system.dll /r:system.data.dll /r:system.xml.dll produits.vb
dos>vbc /r:produits.dll /r:system.data.dll /r:system.xml.dll /r:system.dll testproduits.vb
dos>dir
06/05/2004 16:52 118 784 produits.mdb
07/05/2004 11:07 902 produits.vb
07/04/2004 07:01 1 532 testproduits.vb
07/05/2004 14:21 3 584 produits.dll
07/05/2004 14:22 4 608 testproduits.exe
dos>testproduits produits.mdb
1,produit1,10
2,produit2,20
3,produit3,30
8.6.2. Görünümler
Artık veri erişim sınıfımız olduğuna göre, bu web uygulamasının denetleyicilerini ve görünümlerini yazacağız. Öncelikle nasıl çalıştığına bir göz atalım. İlk görünüm şöyledir:
![]() |
no | ad | tür | özellikler | rol |
1 | TextBox | EnableViewState=true | select sorgusu giriş alanı | |
2 | RequiredFieldValidator | EnableViewState=false | 1'in varlığını kontrol eder | |
3 | TextBox | EnableViewState=true | giriş alanı - sonuç sayfası başına görüntülenecek veri satır sayısını belirtir | |
4 | RequiredFieldValidator | EnableViewState=false | 3'ün varlığını kontrol eder | |
5 | RangeValidator | EnableViewState=false | (3) değerinin [1,30] aralığında olup olmadığını kontrol eder | |
6 | Düğme | EnableViewState=false | [submit] düğmesi |
Bu görünüme [formulaire] adı vereceğiz. Bu görünüm, kullanıcının [produits.mdb] veritabanında bir SQL select sorgusu çalıştırmasına olanak tanır. Sorgunun çalıştırılması, yeni bir görünüm oluşturur:
![]() |
no | ad | tür | özellikler | rol |
1 | Etiket | EnableViewState=false | bilgi alanı | |
2 | RadioButton | EnableViewState=false GroupName=rdTri | sıralama yönünü seçmenizi sağlar | |
3 | DataGrid | EnableViewState=true AllowPaging=true AllowSorting=true | select sonucunu gösteren tablo | |
4 | LinkButton | EnableViewState=false | [submit] düğme bağlantısı |
Bu görünüme [résultats] adı vereceğiz. [DataGrid] öğesini içeren bu görünüm, SQL select komutunun sonucunu görüntüleyecektir. Kullanıcı sorgusunda hata yapabilir. Doğrulama denetimleri sayesinde, bazı hatalar [erreurs] görünümünde kullanıcıya bildirilecektir.

Diğer hatalar ise [erreurs] görünümü aracılığıyla kullanıcıya bildirilecektir:

[erreurs] görünümü görüntülenir:
![]() |
no | ad | tür | özellikler | rol |
1 | değişken | hataların görüntülenmesi için gerekli olan HTML kodu | ||
3 | LinkButton | EnableViewState=false | [submit] bağlantı düğmesi |
Uygulamanın üç görünümü, aynı sayfa içindeki üç farklı panel (konteyner)dir: [main.aspx]. Sunum kodu şu şekildedir:
<%@ Page src="main.aspx.vb" inherits="main" autoeventwireup="false" Language="vb" %>
<HTML>
<HEAD>
</HEAD>
<body>
<P>Liaison de données avec un DataGrid</P>
<HR width="100%" SIZE="1">
<form runat="server">
<asp:panel id="vueFormulaire" runat="server">
<P>Commande [select] à exécuter sur la table LISTE</P>
<P> Exemple : select id, nom, prix from LISTE
</P>
<P>
<asp:TextBox id="txtSelect" runat="server" Columns="60"></asp:TextBox></P>
<P>
<asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server" EnableViewState="False" EnableClientScript="False"
ErrorMessage="Indiquez la requête [select] à exécuter" ControlToValidate="txtSelect" Display="Dynamic"></asp:RequiredFieldValidator></P>
<P>Nombre de lignes par page :
<asp:TextBox id="txtPages" runat="server" Columns="3"></asp:TextBox></P>
<P>
<asp:RequiredFieldValidator id="RequiredFieldValidator2" runat="server" EnableViewState="False" EnableClientScript="False"
ErrorMessage="Indiquez le nombre de lignes par page désirées" ControlToValidate="txtPages" Display="Dynamic"></asp:RequiredFieldValidator>
<asp:RangeValidator id="RangeValidator1" runat="server" EnableViewState="False" EnableClientScript="False"
ErrorMessage="Vous devez indiquer un nombre entre 1 et 30" ControlToValidate="txtPages" Display="Dynamic"
Type="Integer" MinimumValue="1" MaximumValue="30"></asp:RangeValidator></P>
<P>
<asp:Button id="btnExécuter" runat="server" EnableViewState="False" Text="Exécuter"></asp:Button></P>
</asp:panel>
<asp:Panel id="vueRésultats" runat="server">
<P>Résultats de la requête
<asp:Label id="lblSelect" runat="server"></asp:Label></P>
<P>Tri
<asp:RadioButton id="rdCroissant" runat="server" Text="croissant" Checked="True" GroupName="rdTri"></asp:RadioButton>
<asp:RadioButton id="rdDécroissant" runat="server" Text="décroissant" GroupName="rdTri"></asp:RadioButton></P>
<P>
<asp:DataGrid id="DataGrid1" runat="server" BorderColor="#CC9966" BorderStyle="None" BorderWidth="1px"
BackColor="White" CellPadding="4" AllowPaging="True" PageSize="4" AllowSorting="True">
<SelectedItemStyle Font-Bold="True" ForeColor="#663399" BackColor="#FFCC66"></SelectedItemStyle>
<ItemStyle ForeColor="#330099" BackColor="White"></ItemStyle>
<HeaderStyle Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000"></HeaderStyle>
<FooterStyle ForeColor="#330099" BackColor="#FFFFCC"></FooterStyle>
<PagerStyle NextPageText="Suivant" PrevPageText="Précédent" HorizontalAlign="Center"
ForeColor="#330099" BackColor="#FFFFCC"></PagerStyle>
</asp:DataGrid></P>
<P>
<asp:LinkButton id="lnkRésultats" runat="server" EnableViewState="False">Retour au formulaire</asp:LinkButton></P>
</asp:Panel>
<asp:Panel id="vueErreurs" runat="server">
<P>Les erreurs suivantes se sont produites :</P>
<% =erreursHTML %>
<P>
<asp:LinkButton id="lnkErreurs" runat="server" EnableViewState="False">Retour vers le formulaire</asp:LinkButton></P>
</asp:Panel>
</form>
</body>
</HTML>
8.6.3. DataGrid'in yapılandırılması
İlk kez karşılaştığımız [DataGrid] bileşeninin sayfalandırma özelliğine biraz daha yakından bakalım. Yukarıdaki kodda, bu sayfalandırma aşağıdaki özniteliklerle kontrol edilmektedir:
<asp:DataGrid id="DataGrid1" runat="server" PageSize="4" AllowPaging="True" ...>
...
<PagerStyle NextPageText="Suivant" PrevPageText="Précédent" ...></PagerStyle>
</asp:DataGrid></P>
sayfa numaralandırmasına izin ver | |
sayfa başına dört satır veri | |
Veri kaynağının bir sonraki sayfasına gitmek için bağlantı metni | |
Veri kaynağının bir önceki sayfasına gitmek için kullanılan bağlantı metni |
Bu bilgiler doğrudan <asp:datagrid> etiketinin özniteliklerine girilebilir. Ayrıca [WebMatrix]'ten de yararlanılabilir. [DataGrid]'in özellikler penceresinde, [Générateur de propriétés] bağlantısını takip edin:

Aşağıdaki sihirbaz açılır:

[Pagination] seçeneğini seçin:

Yukarıda, sunum kodundaki [DataGrid]'in sayfalandırma özniteliklerinin değerlerini görüyoruz.
Ayrıca, [DataGrid]'in sütunlarından birine göre verilerin sıralanmasına izin veriyoruz. Bunu yapmanın çeşitli yolları vardır. Bunlardan biri, [DataGrid]'in özellikler penceresinde [AllowSorting=true] özelliğini tanımlamaktır. Özellik oluşturucu da kullanılabilir. Hangi yöntem kullanılırsa kullanılsın, sonuç olarak bileşenin <asp:DataGrid> etiketinde [AllowSorting=true] özniteliği bulunur:
<asp:DataGrid id="DataGrid1" runat="server" ... AllowPaging="True" PageSize="4" AllowSorting="True">
8.6.4. Denetleyiciler
[global.asax, global.asax.vb] denetleyicisi şu şekildedir:
[global.asax]
[global.asax.vb]
Imports st.istia.univangers.fr
Imports System.Configuration
Public Class Global
Inherits System.Web.HttpApplication
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' bir ürün nesnesi oluşturulur
Dim objProduits As produits
Try
objProduits = New produits(ConfigurationSettings.AppSettings("OLEDBStringConnection"))
' nesneyi uygulamaya eklenir
Application("objProduits") = objProduits
' hata yok
Application("erreur") = False
Catch ex As Exception
'hata oluştu, uygulamaya kaydediliyor
Application("erreur") = True
Application("message") = ex.Message
End Try
End Sub
End Class
Uygulama başlatıldığında (Application_Start), bir [produits] nesnesi oluşturur ve tüm istemcilerin tüm istekleri için kullanılabilir olması amacıyla bunu uygulamaya yerleştiririz. Bu oluşturma işlemi sırasında bir istisna meydana gelirse, bu durum uygulamada kaydedilir. [Application_Start] prosedürü yalnızca bir kez çalıştırılacaktır. Bundan sonra [global.asax] denetleyicisi devreye girmeyecektir. Bu noktada işi [main.aspx.vb] denetleyicisi üstlenecektir:
Imports System.Collections
Imports Microsoft.VisualBasic
Imports System.Data
Imports st.istia.univangers.fr
Imports System
Imports System.Xml
Public Class main
Inherits System.Web.UI.Page
' sayfa bileşenleri
Protected WithEvents txtSelect As System.Web.UI.WebControls.TextBox
Protected WithEvents RequiredFieldValidator1 As System.Web.UI.WebControls.RequiredFieldValidator
Protected WithEvents txtPages As System.Web.UI.WebControls.TextBox
Protected WithEvents RequiredFieldValidator2 As System.Web.UI.WebControls.RequiredFieldValidator
Protected WithEvents RangeValidator1 As System.Web.UI.WebControls.RangeValidator
Protected WithEvents btnExécuter As System.Web.UI.WebControls.Button
Protected WithEvents vueFormulaire As System.Web.UI.WebControls.Panel
Protected WithEvents lblSelect As System.Web.UI.WebControls.Label
Protected WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid
Protected WithEvents lnkRésultats As System.Web.UI.WebControls.LinkButton
Protected WithEvents vueRésultats As System.Web.UI.WebControls.Panel
Protected WithEvents lnkErreurs As System.Web.UI.WebControls.LinkButton
Protected WithEvents vueErreurs As System.Web.UI.WebControls.Panel
Protected WithEvents rdCroissant As System.Web.UI.WebControls.RadioButton
Protected WithEvents rdDécroissant As System.Web.UI.WebControls.RadioButton
' sayfa verileri
Protected erreursHTML As String
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' uygulamada hata olup olmadığına bakılıyor
If CType(Application("erreur"), Boolean) Then
' uygulama düzgün bir şekilde başlatılamadı
Dim erreurs As New ArrayList
erreurs.Add("Application momentanément indisponible (" + CType(Application("message"), String) + ")")
afficheErreurs(erreurs, False)
Exit Sub
End If
'1. istek
If Not IsPostBack Then
' boş form görüntüleniyor
afficheFormulaire()
End If
End Sub
Private Sub afficheErreurs(ByVal erreurs As ArrayList, ByVal afficheLien As Boolean)
' hata görünümünü görüntüler
erreursHTML = ""
For i As Integer = 0 To erreurs.Count - 1
erreursHTML += "<li>" + erreurs(i).ToString + "</li>" + ControlChars.CrLf
Next
lnkErreurs.Visible = afficheLien
' [erreurs] görünümü görüntüleniyor
vueErreurs.Visible = True
vueFormulaire.Visible = False
vueRésultats.Visible = False
End Sub
Private Sub afficheFormulaire()
' [formulaire] görünümü görüntülenir
vueFormulaire.Visible = True
vueErreurs.Visible = False
vueRésultats.Visible = False
End Sub
Private Sub afficheRésultats(ByVal sqlTexte As String, ByVal données As DataView)
' kontroller başlatılıyor
lblSelect.Text = sqlTexte
With DataGrid1
.DataSource = données
.PageSize = CType(txtPages.Text, Integer)
.CurrentPageIndex = 0
.DataBind()
End With
' [résultats] görünümü görüntülenir
vueRésultats.Visible = True
vueFormulaire.Visible = False
vueErreurs.Visible = False
End Sub
Private Sub btnExécuter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExécuter.Click
' sayfa geçerli mi?
If Not Page.IsValid Then
afficheFormulaire()
Exit Sub
End If
' SELECT istemci sorgusu yürütülüyor
Dim données As DataView
Try
données = CType(Application("objProduits"), produits).getDataSet(txtSelect.Text.Trim).Tables(0).DefaultView
Catch ex As Exception
Dim erreurs As New ArrayList
erreurs.Add("erreur d'accès à la base de données (" + ex.Message + ")")
afficheErreurs(erreurs, True)
Exit Sub
End Try
' her şey yolunda - sonuçlar görüntüleniyor
afficheRésultats(txtSelect.Text.Trim, données)
' veriler oturuma aktarılıyor
Session("données") = données
End Sub
Private Sub retourFormulaire(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lnkErreurs.Click, lnkRésultats.Click
' görünüm kümesi
vueErreurs.Visible = False
vueFormulaire.Visible = True
vueRésultats.Visible = False
End Sub
Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles DataGrid1.PageIndexChanged
' sayfa değişimi
With DataGrid1
.CurrentPageIndex = e.NewPageIndex
.DataSource = CType(Session("données"), DataView)
.DataBind()
End With
End Sub
Private Sub DataGrid1_SortCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridSortCommandEventArgs) Handles DataGrid1.SortCommand
' veri görünümü sıralanıyor
Dim données As DataView = CType(Session("données"), DataView)
données.Sort = e.SortExpression + " " + CType(IIf(rdCroissant.Checked, "asc", "desc"), String)
' görüntüleniyor
With DataGrid1
.CurrentPageIndex = 0
.DataSource = données
.DataBind()
End With
End Sub
End Class
[Page_Load] sayfası yüklendiğinde, öncelikle uygulamanın düzgün bir şekilde başlatılıp başlatılmadığını kontrol ederiz. Başlatılamamışsa, [erreurs] görünümü, forma geri dönme bağlantısı olmadan görüntülenir; çünkü bu bağlantı bu durumda gereksizdir. Aslında, uygulama düzgün bir şekilde başlatılamamışsa yalnızca [erreurs] görünümü görüntülenebilir. Aksi takdirde, istemciden gelen ilk istek söz konusuysa [formulaire] görünümü görüntülenir. Geri kalan kısım için ise kodu anlamayı okuyucuya bırakıyoruz. Sadece üç prosedür üzerinde duracağız: kullanıcı, [formulaire] görünümüne girilen SQL isteğinin yürütülmesini talep ettiğinde çalıştırılan [btnExécuter_Click] prosedürü, kullanıcı,kullanıcı [DataGrid]'teki [Suivant] ve [Précédent] bağlantılarını kullandığında çalıştırılan [DataGrid1_PageIndexChanged] prosedürü ve kullanıcının verileri sıralama amacıyla bir sütun başlığına tıkladığındasırasına göre sıralamak istediğinde çalıştırılır. Sıralamanın artan veya azalan yönü, iki sıralama radyo düğmesi ile belirlenir.
Dolayısıyla, [btnExécuter_Click] prosedüründe ilk olarak sayfanın geçerli olup olmadığı kontrol edilir. [btnExécuter_Click] prosedürü yürütüldüğünde, sayfanın çeşitli geçerlilik denetimleriyle ilgili kontroller yapılmış olur. Her bir geçerlilik denetimi için iki öznitelik ayarlanmıştır:
doğrulanmış veri geçerliyse "true", değilse "false" olarak ayarlanır | |
doğrulanmış verinin geçersiz olduğu tespit edildiğinde hata mesajı |
Sayfanın kendisi için ise bir [IsValid] özniteliği ayarlanmıştır. Bu öznitelik, yalnızca tüm doğrulama denetimlerinin [IsValid] özniteliği "true" ise "true" olur. Aksi takdirde, [formulaire] görünümü görüntülenmelidir. Bu görünüm, [errorMessage] özniteliğini görüntüleyecek doğrulama denetimlerini içerir. Sayfa geçerliyse, [Application_Start] tarafından oluşturulan [produits] türündeki nesne kullanılarak, SQL select sorgusunun yürütülmesine karşılık gelen [DataSet] elde edilir. Bunu [DataView] nesnesine dönüştürürüz:
Dim données As DataView
Try
données = CType(Application("objProduits"), produits).getDataSet(txtSelect.Text.Trim).Tables(0).DefaultView
...
[DataSet] ile çalışıp şunu yazabilirdik:
Dim données As DataSet
Try
données = CType(Application("objProduits"), produits).getDataSet(txtSelect.Text.Trim)
...
Bir [DataSet] nesnesi, temelde ilişkilerle birbirine bağlanmış bir dizi tablodan oluşur. Özel uygulamamızda, [produits] sınıfından elde edilen [DataSet], yalnızca [select] komutunun sonucundan elde edilen tek bir tablo içerir. Bir tablo sıralanabilirken bir [DataSet] sıralanamaz; ancak elde edilen verileri sıralamak istiyoruz. [select] komutunun sonuç tablosuyla çalışmak için şunu yazabilirdik:
Dim données As DataTable
Try
données = CType(Application("objProduits"), produits).getDataSet(txtSelect.Text.Trim).Tables(0)
...
[DataTable] nesnesi, bir veritabanı tablosunu temsil etmesine rağmen sıralama yöntemine sahip değildir. Bunun için tablonun bir görünümüne sahip olmak gerekir. Bir görünüm, [DataView] türünde bir nesnedir. Filtreler yardımıyla aynı tablo üzerinde farklı görünümler elde edilebilir. Bir tablonun, üzerinde herhangi bir filtre tanımlanmamış olan varsayılan bir görünümü vardır. Dolayısıyla bu görünüm, tablonun tamamını temsil eder. Bu varsayılan görünüm, [DataTable.DefaultView] ile elde edilir. Bir görünümü, daha sonra ele alacağımız [sort] özelliği kullanılarak sıralayabiliriz.
[produits] sınıfının [DataSet] değeri başarıyla elde edilirse, [résultats] görünümü görüntülenir; aksi takdirde [erreurs] görünümü görüntülenir. [résultats] görünümünün görüntülenmesi, iki parametre aktarılan [afficheRésultats] prosedürü ile gerçekleştirilir:
- [lblSelect] etiketine yerleştirilecek metin
- [DataGrid1] ile ilişkilendirilecek [DataView]
Bu örnek, [DataGrid] bileşeninin büyük esnekliğini göstermektedir. Bu bileşen, kendisine bağlanan [DataView]’in yapısını tanıyabilmekte ve buna uyum sağlayabilmektedir. Son olarak, [btnExécuter_Click] prosedürü, kullanıcının oturumunda az önce elde ettiği [DataView]'i, kullanıcı aynı [DataView]'e ait başka sayfalar talep ettiğinde kullanabilmek üzere saklar.
[DataGrid1_PageIndexChanged] prosedürü, kullanıcı [DataGrid]'teki [Suivant] ve [Précédent] bağlantılarını kullandığında çalıştırılır. Bu prosedür iki parametre alır:
Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.) Handles DataGrid1.PageIndexChanged
olayın kaynak nesnesi – bu durumda, [Suivant] veya [Précédent] bağlantılarından biri | |
olayla ilgili bilgiler. e.NewPageIndex özniteliği, müşterinin talebini karşılamak için görüntülenecek sayfa numarasıdır |
Olay işleyicisinin tam kodu şöyledir:
Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles DataGrid1.PageIndexChanged
' sayfa değişimi
With DataGrid1
.CurrentPageIndex = e.NewPageIndex
.DataSource = CType(Session("données"), DataView)
.DataBind()
End With
End Sub
[DataGrid] bileşeninin, görüntülediği veya görüntüleyeceği sayfanın numarasını belirten [CurrentPageIndex] adlı bir özniteliği vardır. Bu özniteliğe, [e] parametresinin değeri olan [NewPageIndex] atanır. Ardından [DataGrid], [btnExécuter_Click] prosedürü aracılığıyla oturumda saklanan [DataView] ile eşleştirilir.
[DataGrid]'in [EnableViewState=true] özniteliğine ihtiyacı olup olmadığı sorgulanabilir; zira içeriği, sayfanın her yeni çalıştırılışında kod tarafından hesaplanmaktadır. İhtiyacı olmadığı düşünülebilir. Ancak, [DataGrid]'in [EnableViewState=false] özniteliğine sahip olması durumunda, [DataGrid1.PageIndexChanged] olayının hiçbir zaman tetiklenmediği görülür. Bu nedenle [EnableViewState=true] bırakılmıştır. Bunun sonucunda, [DataGrid]'in içeriğinin sayfanın gizli [__VIEWSTATE] alanına yerleştirileceği bilinmektedir. [DataGrid] büyükse, bu durum sayfada önemli bir aşırı yüklenmeye neden olabilir. Bu durum sorun yaratıyorsa, [DataGrid]'in otomatik sayfalandırmasını kullanmadan sayfalandırmayı kendimiz yönetebiliriz.
Kullanıcı, [DataGrid] tarafından görüntülenen sütunlardan birinin başlığına tıklayarak verilerin o sütuna göre sıralanmasını istediğinde, [DataGrid1_SortCommand] prosedürü çalıştırılır. Bu prosedür iki parametre alır:
Private Sub DataGrid1_SortCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridSortCommandEventArgs) Handles DataGrid1.SortCommand
olayın kaynak nesnesi – burada, [Suivant] veya [Précédent] bağlantılarından biri | |
olayla ilgili bilgiler. [e.SortExpression] özniteliği, sıralama için tıklanan sütunun adıdır |
Olay işleyicisinin tam kodu şöyledir:
Private Sub DataGrid1_SortCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridSortCommandEventArgs) Handles DataGrid1.SortCommand
' veri görünümünü sıralama
Dim données As DataView = CType(Session("données"), DataView)
données.Sort = e.SortExpression + " " + CType(IIf(rdCroissant.Checked, "asc", "desc"), String)
' görüntüleniyor
With DataGrid1
.CurrentPageIndex = 0
.DataSource = données
.DataBind()
End With
End Sub
Geçerli oturumda [DataGrid] tarafından görüntülenen [DataView] alınır. Bunu buraya yerleştiren [btnExécuter_Click] prosedürüdür. [DataView] bileşeninin, sıralama ifadesinin atandığı bir [Sort] özelliği vardır. Bu ifade, [select ... order by expr1, expr2, ...] sözdizimine uyar; burada her bir [expri] öğesinin ardından, artan sıralama için [asc] anahtar sözcüğü veya azalan sıralama için [desc] anahtar sözcüğü gelebilir. Burada kullanılan [order by] ifadesi, [order by colonne asc/desc]'tir. [e.SortExpression] özelliği, sıralama için tıklanan [DataGrid] sütununun adını verir. [asc/desc] dizesi, [rdTri] grubundaki radyo düğmelerinin değerlerine göre belirlenir. [DataView]'in sıralama ifadesi belirlendikten sonra, [DataGrid] buna eşleştirilir. [DataGrid], ilk sayfasına yerleştirilir.
8.7. DataList bileşeni ve veri bağlantısı
Şimdi [DataList] bileşenine odaklanalım. Bu bileşen, [DataGrid]'e göre daha fazla biçimlendirme olanağı sunar, ancak daha az esnektir. Dolayısıyla, bağlı olduğu veri kaynağına otomatik olarak uyum sağlayamaz. İstenirse, bu uyumlaştırma kod yoluyla yapılmalıdır. Veri kaynağının yapısı önceden biliniyorsa, bu bileşen sunduğu biçimlendirme seçenekleri sayesinde [DataGrid] bileşenine tercih edilebilir.
8.7.1. Uygulama
[DataList] bileşeninin kullanımını örneklemek amacıyla, öncekine benzer bir MVC uygulaması oluşturuyoruz:
![]() |
Üç görünüm, [main.aspx] denetleyicisinin sunum koduna konteynerler şeklinde eklenecektir. Dolayısıyla bu uygulama, tek bir [main.aspx] sayfasına sahiptir.
8.7.2. İşlev sınıfları
[produits] sınıfı, öncekiyle aynıdır.
8.7.3. Görünümler
Kullanıcı uygulamaya ilk isteğini gönderdiğinde, aşağıdaki [résultats1] görünümünü alır:
![]() |
no | ad | tür | özellikler | rol |
1 | RadioButton | EnableViewState=false | iki seçenek arasından bir [DataList] stili seçmenizi sağlar | |
2 | Düğme | EnableViewState=false | [submit] düğmesi | |
3 | DataList | EnableViewState=true | veri listesi görüntüleme alanı |
Kullanıcı 2 numaralı stili seçerse, aşağıdaki [résultats2] görünümünü alır:
![]() |
no | ad | tür | özellikler | rol |
1 | DataList | EnableViewState=true | veri listesi görüntüleme alanı |
[erreurs] görünümü, veri kaynağına erişimde bir sorun olduğunu bildiriyor:
![]() |
numara | ad | tür | özellikler | rol |
1 | değişken | hataların görüntülenmesi için gerekli olan HTML kodu |
Uygulamanın üç görünümü, aynı [main.aspx] sayfası içindeki üç farklı konteynerdir (panel). Sunum kodu şöyledir:
<%@ Page src="main.aspx.vb" inherits="main" autoeventwireup="false" Language="vb" %>
<HTML>
<HEAD>
</HEAD>
<body>
<P>Liaison de données avec un DataList</P>
<HR width="100%" SIZE="1">
<form runat="server" ID="Form1">
<asp:Panel Runat="server" ID="bandeau">
<P>Choisissez votre style :
<asp:RadioButton id="RadioButton1" runat="server" EnableViewState="False" Text="1" GroupName="rdstyle"
Checked="True"></asp:RadioButton>
<asp:RadioButton id="RadioButton2" runat="server" EnableViewState="False" Text="2" GroupName="rdstyle"></asp:RadioButton>
<asp:Button id="btnChanger" runat="server" EnableViewState="False" Text="Changer"></asp:Button></P>
<HR width="100%" SIZE="1">
</asp:Panel>
<asp:Panel id="vueRésultats1" runat="server">
<P>
<asp:DataList id="DataList1" runat="server" BorderColor="Tan" BorderWidth="1px" BackColor="LightGoldenrodYellow"
CellPadding="2" RepeatDirection="Horizontal" RepeatColumns="4" ForeColor="Black">
<SelectedItemStyle ForeColor="GhostWhite" BackColor="DarkSlateBlue"></SelectedItemStyle>
<HeaderTemplate>
Contenu de la table [liste] de la base [produits]
</HeaderTemplate>
<AlternatingItemStyle BackColor="PaleGoldenrod"></AlternatingItemStyle>
<ItemTemplate>
nom :
<%# Container.DataItem("ad") %>
<br>
prix :
<%# databinder.eval(Container.DataItem,"fiyat","{0:C}") %>
<br>
</ItemTemplate>
<FooterStyle BackColor="Tan"></FooterStyle>
<HeaderStyle Font-Bold="True" BackColor="Tan"></HeaderStyle>
</asp:DataList></P>
</asp:Panel>
<asp:Panel id="vueRésultats2" runat="server">
<P>
<asp:DataList id="DataList2" runat="server">
<HeaderTemplate>
Contenu de la table [liste] de la base [produits]
<HR width="100%" SIZE="1">
</HeaderTemplate>
<AlternatingItemStyle BackColor="Teal"></AlternatingItemStyle>
<SeparatorStyle BackColor="LightSkyBlue"></SeparatorStyle>
<ItemStyle BackColor="#C0C000"></ItemStyle>
<ItemTemplate>
nom :
<%# Container.DataItem("ad") %>
, prix :
<%# databinder.eval(Container.DataItem,"fiyat","{0:C}") %>
<BR>
</ItemTemplate>
<SeparatorTemplate>
<HR width="100%" SIZE="1">
</SeparatorTemplate>
<HeaderStyle BackColor="#C0C0FF"></HeaderStyle>
</asp:DataList></P>
</asp:Panel>
<asp:Panel id="vueErreurs" runat="server">
<P>Les erreurs suivantes se sont produites :</P>
<%= erreursHTML %>
</asp:Panel>
</form>
</body>
</HTML>
8.7.4. [DataList] bileşenlerinin yapılandırılması
[DataList] bileşeninin çeşitli özelliklerine bir göz atalım. Bu özelliklerin sayısı oldukça fazladır ve burada sadece küçük bir kısmını sunuyoruz. Bir [DataList] içinde yedi adede kadar görüntüleme şablonu tanımlanabilir:
[DataList] başlık şablonu | |
İlişkili veri listesindeki öğeleri gösteren satırların şablonu. Yalnızca bu şablon zorunludur. | |
Görüntülenen ardışık öğeleri görsel olarak ayırt etmek için iki şablon kullanılabilir: n numaralı öğe için ItemTemplate, n+1 numaralı öğe için AlternatingItemTemplate | |
[DataList]'te seçilen öğenin şablonu | |
[DataList]'teki iki öğe arasındaki ayırıcı şablonu | |
[DataList], görüntülediği değerlerin değiştirilmesini mümkün kılar. [EditItemTemplate], "düzenleme" modunda olan [DataList]'teki bir öğenin şablonudur | |
[DataList]'in altbilgi şablonu |
[DataList1] bileşeni, [WebMatrix] kullanılarak oluşturulmuştur. Özellikler penceresinde [Mise en forme automatique] bağlantısı seçilmiştir:
![]() | 1234567 ![]() |
Yukarıdaki şemada, [Couleur 5] şablonu, aşağıdaki şablonlar için stiller içeren bir [DataList] şablonu oluşturacaktır: HeaderTemplate (1), ItemTemplate (2, 6), AlternatingTemplate (3, 5), SelectedItemTemplate (4), FooterTemplate (7). Oluşturulan kod şöyledir:
<asp:DataList id="DataList1" runat="server" BorderColor="Tan" BorderWidth="1px" BackColor="LightGoldenrodYellow"
CellPadding="2" ForeColor="Black">
<SelectedItemStyle ForeColor="GhostWhite" BackColor="DarkSlateBlue"></SelectedItemStyle>
<AlternatingItemStyle BackColor="PaleGoldenrod"></AlternatingItemStyle>
<FooterStyle BackColor="Tan"></FooterStyle>
<HeaderStyle Font-Bold="True" BackColor="Tan"></HeaderStyle>
</asp:DataList></P>
Hiçbir şablon tanımlanmamıştır. Bunu bizim yapmamız gerekiyor. Aşağıdaki şablonları tanımlıyoruz:
| |
|
[ItemTemplate] modelinin, [DataList] ile bağlantılı veri kaynağındaki öğeleri görüntüleyen model olduğunu hatırlatmak isteriz. Bu veri kaynağı, her biri bir veya daha fazla değer içeren bir dizi veri satırından oluşur. Veri kaynağının geçerli satırı, [Container.DataItem] nesnesi ile temsil edilir. Bu tür bir satırın sütunları vardır. [Container.DataItem("col1")], geçerli satırın "col1" sütunundaki değerdir. Bu değeri sunum koduna dahil etmek için <%# Container.DataItem("col") %> yazılır. Bazen, geçerli satırdaki bir öğeyi özel bir biçimde sunmak istenir. Burada, geçerli satırın "fiyat" sütununu euro cinsinden görüntülemek istiyoruz. Bunun için üç parametre kabul eden [DataBinder.Eval] işlevini kullanırız:
- geçerli satır [Container.DataItem]
- biçimlendirilecek sütunun adı
- {0:format} biçimindeki biçimlendirme dizesi; burada [format], [string.format] yöntemi tarafından kabul edilen biçimlerden biridir.
Böylece <%# DataBinder.Eval(Container.DataItem,"fiyat",{0:C}) %> kodu, geçerli satırdaki [prix] sütununu para birimi biçiminde (C=Currency formatı) görüntüleyecektir.
Böylece, şu şekilde görünecek bir [DataList] elde edeceğiz:

Yukarıda, veriler satır başına dört veri olacak şekilde yerleştirilmiştir. Bu, [DataList]'in aşağıdaki öznitelikleriyle elde edilir:
Yatay | |
istenen sütun sayısı |
Sonuç olarak, [DataList1] kodu, biraz yukarıda sunum kodunda gösterilen koddur. [DataList2]'in sunum kodunu incelemek okuyucuya bırakılmıştır. [DataGrid] bileşeninde olduğu gibi, [DataList]'in özelliklerinin çoğu, [WebMatrix]'in sihirbazı kullanılarak ayarlanabilir. Bunun için, [DataList]'in özellikler penceresindeki [Générateur de propriétés] bağlantısı kullanılır:
![]() | ![]() |
8.7.5. Denetleyiciler
[global.asax, global.asax.vb] denetleyicisi şöyledir:
[global.asax]
[global.asax.vb]
Imports System
Imports System.Web
Imports System.Web.SessionState
Imports st.istia.univangers.fr
Imports System.Configuration
Imports System.Data
Imports System.Collections
Public Class Global
Inherits System.Web.HttpApplication
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' bir ürün nesnesi oluşturulur
Try
Dim données As DataSet = New produits(ConfigurationSettings.AppSettings("OLEDBStringConnection")).getDataSet("select * from LISTE")
' nesne uygulamaya eklenir
Application("données") = données
' hata yok
Application("erreur") = False
Catch ex As Exception
'hata oluştu, uygulamaya kaydedilir
Application("erreur") = True
Application("message") = ex.Message
End Try
End Sub
End Class
Uygulama başlatıldığında (Application_Start), [produits] iş sınıfından bir [dataset] oluştururuz ve bunu uygulamaya yerleştiririz; böylece tüm istemcilerin tüm istekleri için kullanılabilir hale gelir. Bu oluşturma işlemi sırasında bir istisna oluşursa, bu durum uygulamada kaydedilir. [Application_Start] prosedürü yalnızca bir kez çalıştırılır. Bundan sonra [global.asax] denetleyicisi artık devreye girmeyecektir. Bu durumda işi [main.aspx.vb] denetleyicisi üstlenecektir:
Imports System.Collections
Imports Microsoft.VisualBasic
Imports System.Data
Imports st.istia.univangers.fr
Imports System
Imports System.Xml
Public Class main
Inherits System.Web.UI.Page
' sayfa bileşenleri
Protected WithEvents vueErreurs As System.Web.UI.WebControls.Panel
Protected WithEvents DataList1 As System.Web.UI.WebControls.DataList
Protected WithEvents DataList2 As System.Web.UI.WebControls.DataList
Protected WithEvents vueRésultats1 As System.Web.UI.WebControls.Panel
Protected WithEvents vueRésultats2 As System.Web.UI.WebControls.Panel
Protected WithEvents RadioButton1 As System.Web.UI.WebControls.RadioButton
Protected WithEvents RadioButton2 As System.Web.UI.WebControls.RadioButton
Protected WithEvents btnChanger As System.Web.UI.WebControls.Button
Protected WithEvents bandeau As System.Web.UI.WebControls.Panel
' sayfa verileri
Protected erreursHTML As String
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' uygulamada hata olup olmadığına bakılıyor
If CType(Application("erreur"), Boolean) Then
' uygulama düzgün bir şekilde başlatılamadı
Dim erreurs As New ArrayList
erreurs.Add("Application momentanément indisponible (" + CType(Application("message"), String) + ")")
afficheErreurs(erreurs, False)
Exit Sub
End If
'ilk istek
If Not IsPostBack Then
' kontroller başlatılıyor
With DataList1
.DataSource = CType(Application("données"), DataSet)
.DataBind()
End With
With DataList2
.DataSource = CType(Application("données"), DataSet)
.DataBind()
End With
' boş form görüntüleniyor
afficheRésultats(True, False)
End If
End Sub
Private Sub afficheErreurs(ByVal erreurs As ArrayList, ByVal afficheLien As Boolean)
' hata görünümünü görüntülüyor
erreursHTML = ""
For i As Integer = 0 To erreurs.Count - 1
erreursHTML += "<li>" + erreurs(i).ToString + "</li>" + ControlChars.CrLf
Next
' [erreurs] görünümü görüntüleniyor
vueErreurs.Visible = True
vueRésultats1.Visible = False
vueRésultats2.Visible = False
bandeau.Visible = False
End Sub
Private Sub afficheRésultats(ByVal visible1 As Boolean, ByVal visible2 As Boolean)
' [résultats] görünümünü görüntüler
vueRésultats1.Visible = visible1
vueRésultats2.Visible = visible2
vueErreurs.Visible = False
End Sub
Private Sub btnChanger_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnChanger.Click
' stil değiştiriliyor
afficheRésultats(RadioButton1.Checked, RadioButton2.Checked)
End Sub
End Class
8.8. Tekrarlayıcı Bileşeni ve Veri Bağlantısı
[Repeater] bileşeni, bir veri listesindeki her bir öğenin HTML kodunu tekrarlamayı sağlar. Bir hata listesini aşağıdaki biçimde görüntülemek istediğimizi varsayalım:

Bu sorunla daha önce karşılaştık ve bunu, sunum koduna <ul><% =erreursHTML %></ul> biçiminde bir değişken ekleyerek çözdük; burada erreursHTML değeri denetleyici tarafından hesaplanıyor. Bu değer, bir listeye ait olan HTML kodunu içerir. Bunun dezavantajı, HTML listesinin sunumunu değiştirmek istediğimizde denetleyici kısmına gitmek zorunda kalmamızdır; bu da denetleyici/sunum ayrımına aykırıdır. [Repeater] bileşeni bize bir çözüm sunar. [DataList]'te olduğu gibi, başlık için <HeaderTemplate>, veri listesinin geçerli öğesi için <ItemTemplate> ve verilerin sonu için <FooterTemplate> şablonlarını tanımlayabiliriz. Burada, [Repeater] bileşeni için şu tanım olabilir:
<asp:Repeater id="Repeater1" runat="server" EnableViewState="False">
<HeaderTemplate>
Les erreurs suivantes se sont produites :
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<%# Container.DataItem %>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
Veri kaynağında birden fazla sütun varsa, [Container.DataItem] bir veri satırını temsil eder. Kaynakta tek bir sütun varsa, bir veri değerini temsil eder. Bu örnekte durum böyledir. Örnek olarak, aşağıdaki uygulamayı oluşturuyoruz:

Sayfanın sunum kodu şöyledir:
<html>
<head>
</head>
<body>
<form runat="server">
<p>
Liaison de données avec un composant [Repeater]
</p>
<hr />
<p>
<asp:Repeater id="Repeater1" runat="server" EnableViewState="False">
<ItemTemplate>
<li>
<%# Container.DataItem %>
</li>
</ItemTemplate>
<HeaderTemplate>
Les erreurs suivantes se sont produites :
<ul>
</HeaderTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</p>
</form>
</body>
</html>
Doğrulama kodu şöyledir:
<%@ Page Language="VB" %>
<script runat="server">
' sayfa yüklendiğinde yürütülen işlem
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
' bir veri kaynağı oluşturulur
with Repeater1
.DataSource=createDataSource
.DataBind
end with
end if
End Sub
function createDataSource as ArrayList
' bir arraylist oluşturulur
dim erreurs as new ArrayList
dim i as integer
for i=0 to 5
erreurs.add("erreur-"+i.ToString)
next
return erreurs
end function
</script>
<html>
...
</html>
Müşterinin ilk isteği üzerine, bir hata listesini temsil ettiği varsayılan [Repeater] bileşenine [ArrayList] nesnesini eşliyoruz.
8.9. Application
Burada, daha önce sunucu bileşenleriyle işlenmiş bir uygulamayı ele alıyoruz. Uygulama, vergi hesaplamaları simülasyonları yapmaya olanak tanır. Uygulama, burada tekrar üzerinde durmayacağımız [impot] sınıfına dayanmaktadır. Bu sınıf, OLEDB veri kaynağında bulunan verilere ihtiyaç duyar. Örnek olarak, ACCESS veri kaynağı kullanılacaktır. Bu yeni sürümde aşağıdaki yenilikleri sunuyoruz:
- verilerin geçerliliğini kontrol etmek için doğrulama bileşenlerinin kullanımı
- sonuçların görüntülenmesi için veri kaynaklarına bağlı sunucu bileşenlerinin kullanımı
8.9.1. Uygulamanın MVC yapısı
Uygulamanın MVC yapısı şu şekildedir:
![]() |
Bu üç görünüm, [main.aspx] denetleyicisinin sunum koduna konteynerler şeklinde eklenecektir. Dolayısıyla bu uygulamanın tek bir sayfası vardır: [main.aspx].
8.9.2. Uygulamanın görünümleri
[formulaire] görünümü, bir kullanıcının vergisinin hesaplanmasına olanak tanıyan bilgi giriş formudur:

Kullanıcı formu doldurur:

[Envoyer] düğmesini kullanarak vergisinin hesaplanmasını talep eder. Aşağıdaki [simulations] görünümünü alır:

Yukarıdaki bağlantı aracılığıyla forma geri döner. Formu, girdiğindeki haliyle bulur. Giriş yaparken hatalar yapabilir:

Bu hatalar, [formulaire] ekranında kendisine bildirilir:

Kullanıcı daha sonra hatalarını düzeltir. Yeni simülasyonlar yapabilir:

Böylece, bir simülasyon daha eklenmiş olan [simulations] görünümünü elde eder:

Son olarak, veri kaynağı mevcut değilse, bu durum [erreurs] görünümünde kullanıcıya bildirilir:

8.9.2.1. Sunum kodu
[main.aspx] sayfasının tüm görünümleri bir araya getirdiğini hatırlayalım. Bu, üç kapsayıcı içeren tek bir formdur:
- [panelform], [formulaire] görünümü için
- [panelerreurs], [erreurs] görünümü için
- [panelsimulations], [simulations] görünümü için
Şimdi bu üç konteynerin bileşenlerini ayrıntılı olarak inceleyeceğiz. [panelform] konteynerinin görsel gösterimi şöyledir:
![]() |
no | ad | tür | özellikler | rol |
Panel | form görünümü | |||
RadioButton | GroupName=rdmarie | radyo düğmeleri | ||
CustomValidator | ErrorMessage=Medeni durumunuzu belirtmediniz EnableClientScript=false | istemci programının beklenen medeni durumu gönderdiğini kontrol eder | ||
TextBox | çocuk sayısı | |||
RequiredFieldValidator | ErrorMessage=Çocuk sayısını belirtin ControlToValidate=txtEnfants | [txtEnfants] alanının boş olmadığını kontrol eder | ||
RangeValidator | ErrorMessage=1 ile 30 arasında bir sayı girin ControlToValidate=txtEnfants | [txtEnfants] alanının [1,30] aralığında olup olmadığını kontrol eder | ||
TextBox | EnableViewState=true | yıllık maaş | ||
RequiredFieldValidator | ControlToValidate=txtMaaş ErrorMessage=Maaş tutarınızı girin | [txtSalaire] alanının boş olmadığını kontrol eder | ||
RegularExpressionValidator | ControlToValidate=txtMaaş ErrorMessage=Geçersiz maaş RegularExpression=\s*\d+\s* | [txtSalaire] alanının sadece rakamlardan oluştuğunu kontrol eder | ||
Düğme | CausesValidation=true | formdaki [submit] düğmesi - vergi hesaplamasını başlatır | ||
Düğme | CausesValidation=false | Formdaki [submit] düğmesi - formu boşaltır |
Kullanıcının iki radyo düğmesinden birini işaretlediğini doğrulamakla görevli [cvMarié] denetimi şaşırtıcı gelebilir. Aslında, sunucu tarafından gönderilen formu doğru kullanıyorsa başka türlü olması mümkün değildir. Bunu garanti edecek hiçbir şey olmadığından, gönderilen tüm parametreleri doğrulamak zorundayız. Ayrıca, [btnEffacer] düğmesinin [CausesValidation=false] özniteliğine de dikkat edilmelidir. Zira kullanıcı bu düğmeyi kullandığında, gönderilen veriler göz ardı edileceği için kontrol edilmemelidir.
[panelForm, txtEnfants, txtSalaire, rdOui, rdNon] hariç, konteynerin tüm bileşenleri [EnableViewState=false] özelliğine sahiptir. [panelerreurs] konteynerinin görsel temsili şöyledir:
![]() |
no | ad | tür | özellikler | rol |
Panel | EnableViewState=false | hata görünümü | ||
Tekrarlayıcı | EnableViewState=false | bir hata listesi görüntüler |
[rptErreurs] bileşeni şu şekilde tanımlanmıştır:
<asp:Repeater id="rptErreurs" runat="server" EnableViewState="False">
<ItemTemplate>
<li>
<%# Container.Dataitem%>
</li>
</ItemTemplate>
<HeaderTemplate>
Les erreurs suivantes se sont produites
<ul>
</HeaderTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
[rptErreurs] bileşeniyle ilişkili veri listesi, bir hata mesajları listesi içeren [ArrayList] nesnesi olacaktır. Dolayısıyla yukarıda, <%# Container.Dataitem%> mevcut hata mesajını belirtir. [panelsimulations] kapsayıcısının görsel gösterimi şöyledir:
![]() |
no | ad | tür | özellikler | rol |
Panel | EnableViewState=false | simülasyonlar görünümü | ||
LinkButton | EnableViewState=false | form bağlantısı | ||
DataGrid | EnableViewState=false | [DataTable] nesnesine yerleştirilen simülasyonları görüntülemekle görevlidir |
[dgSimulations] bileşeni, [Webmatrix] altında aşağıdaki şekilde yapılandırılmıştır. [dgSimulations] özellik penceresinde, [Mise en forme automatique] bağlantısını seçip [Couleur 3] şemasını seçiyoruz:
![]() | ![]() |
Ardından, yine [dlgSimulations]'in özellikler penceresinde, [Générateur de propriétés] bağlantısını seçiyoruz. Sütun başlıklarının görüntülenmesini istiyoruz:

[DataGrid]'in dört sütununu tanımlamak için [Colonnes] seçeneğini seçiyoruz:

[Créer des colonnes automatiquement ...] ifadesinin işaretini kaldırıyoruz. [DataGrid]'in dört sütununu kendimiz tanımlayacağız. Bu, sırasıyla "evli", "çocuklar", "maaş", "vergi" olarak adlandırılmış dört sütuna sahip bir [DataTable] nesnesiyle ilişkilendirilecektir. [DataGrid]'te bir sütun oluşturmak için, [Colonnes connexe] seçeneğini seçip yukarıda gösterildiği gibi oluşturma düğmesini kullanıyoruz. Bir sütun oluşturulur ve özelliklerini tanımlayabiliriz. Simülasyon tablosunun ilk sütunu, [DataGrid] ile ilişkilendirilecek olan [DataTable] nesnesinin "evli" sütununu içerecektir. [DataGrid]'in bu ilk sütunu, sihirbazda şu şekilde tanımlanır:

sütun başlığı, burada "Evli" | |
[DataGrid]'in bu sütunu tarafından görüntülenecek veri kaynağındaki sütun adı. Burada, [DataTable]'in "evli" sütunudur. |
İkinci sütun şu şekilde tanımlanmıştır:
Çocuklar | |
çocuklar |
Üçüncü sütun şu şekilde tanımlanmıştır:
Yıllık maaş | |
maaş | |
{0:C} - euro sembolünü elde etmek için para birimi gösterimi |
Dördüncü sütun şu şekilde tanımlanmıştır:
Vergi tutarı | |
vergi | |
{0:C} - euro işaretini elde etmek için para birimi gösterimi |
Görünüm kodunu ve kontrol kodunu iki ayrı dosyaya yerleştiriyoruz. İlki [main.aspx] dosyasında, ikincisi ise [main.aspx.vb] dosyasında yer alacaktır. [main.aspx] kodunun içeriği şöyledir:
<%@ page src="main.aspx.vb" inherits="main" AutoEventWireUp="false" %>
<HTML>
<HEAD>
<title>Calculer votre impôt</title>
</HEAD>
<body>
<P>Calculer votre impôt</P>
<HR width="100%" SIZE="1">
<FORM id="Form1" runat="server">
<asp:panel id="panelform" Runat="server">
<TABLE id="Table1" cellSpacing="1" cellPadding="1" border="0">
<TR>
<TD height="19">Etes-vous marié(e)</TD>
<TD height="19">
<asp:RadioButton id="rdOui" runat="server" GroupName="rdMarie"></asp:RadioButton>Oui
<asp:RadioButton id="rdNon" runat="server" GroupName="rdMarie" Checked="True"></asp:RadioButton>Non
<asp:CustomValidator id="cvMarie" runat="server" ErrorMessage="Vous n'avez pas indiqué votre état marital"
Display="Dynamic" EnableClientScript="False" Visible="False" EnableViewState="False"></asp:CustomValidator></TD>
</TR>
<TR>
<TD>Nombre d'enfants</TD>
<TD>
<asp:TextBox id="txtEnfants" runat="server" Columns="3" MaxLength="3"></asp:TextBox>
<asp:RequiredFieldValidator id="rfvEnfants" runat="server" ErrorMessage="Indiquez le nombre d'enfants" Display="Dynamic"
ControlToValidate="txtEnfants" EnableViewState="False"></asp:RequiredFieldValidator>
<asp:RangeValidator id="rvEnfants" runat="server" ErrorMessage="Tapez un nombre entre 1 et 30" Display="Dynamic"
ControlToValidate="txtEnfants" Type="Integer" MaximumValue="30" MinimumValue="0" EnableViewState="False"></asp:RangeValidator></TD>
</TR>
<TR>
<TD>Salaire annuel (euro)</TD>
<TD>
<asp:TextBox id="txtSalaire" runat="server" Columns="10" MaxLength="10"></asp:TextBox>
<asp:RequiredFieldValidator id="rfvSalaire" runat="server" ErrorMessage="Indiquez le montant de votre salaire"
Display="Dynamic" ControlToValidate="txtSalaire" EnableViewState="False"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator id="revSalaire" runat="server" ErrorMessage="Salaire invalide" Display="Dynamic"
ControlToValidate="txtSalaire" ValidationExpression="\s*\d+\s*" EnableViewState="False"></asp:RegularExpressionValidator></TD>
</TR>
</TABLE>
<P>
<asp:Button id="btnCalculer" runat="server" Text="Calculer"></asp:Button>
<asp:Button id="btnEffacer" runat="server" Text="Effacer" CausesValidation="False"></asp:Button></P>
</asp:panel>
<asp:panel id="panelerreurs" runat="server" EnableViewState="False">
<asp:Repeater id="rptErreurs" runat="server" EnableViewState="False">
<ItemTemplate>
<li>
<%# Container.Dataitem%>
</li>
</ItemTemplate>
<HeaderTemplate>
Les erreurs suivantes se sont produites
<ul>
</HeaderTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</asp:panel>
<asp:panel id="panelsimulations" runat="server" EnableViewState="False">
<P>
<asp:DataGrid id="dgSimulations" runat="server" BorderColor="#DEBA84" BorderStyle="None" CellSpacing="2"
BorderWidth="1px" BackColor="#DEBA84" CellPadding="3" AutoGenerateColumns="False" EnableViewState="False">
<SelectedItemStyle Font-Bold="True" ForeColor="White" BackColor="#738A9C"></SelectedItemStyle>
<ItemStyle ForeColor="#8C4510" BackColor="#FFF7E7"></ItemStyle>
<HeaderStyle Font-Bold="True" ForeColor="White" BackColor="#A55129"></HeaderStyle>
<FooterStyle ForeColor="#8C4510" BackColor="#F7DFB5"></FooterStyle>
<Columns>
<asp:BoundColumn DataField="marié" HeaderText="Marié"></asp:BoundColumn>
<asp:BoundColumn DataField="enfants" HeaderText="Enfants"></asp:BoundColumn>
<asp:BoundColumn DataField="salaire" HeaderText="Salaire annuel" DataFormatString="{0:C}"></asp:BoundColumn>
<asp:BoundColumn DataField="impôt" HeaderText="Montant de l'impôt" DataFormatString="{0:C}"></asp:BoundColumn>
</Columns>
<PagerStyle HorizontalAlign="Center" ForeColor="#8C4510" Mode="NumericPages"></PagerStyle>
</asp:DataGrid></P>
<P>
<asp:LinkButton id="lnkForm2" runat="server" EnableViewState="False">Retour au formulaire</asp:LinkButton></P>
</asp:panel>
</FORM>
</body>
</HTML>
8.9.3. Uygulamanın kontrol kodu
Uygulamanın kontrol kodu, [global.asax.vb] ve [main.aspx.vb] dosyalarında yer almaktadır. [global.asax] dosyası şu şekilde tanımlanmıştır:
[global.asax.vb] dosyası şu şekildedir:
Imports System
Imports System.Web
Imports System.Web.SessionState
Imports st.istia.univangers.fr
Imports System.Configuration
Imports System.Collections
Imports System.Data
Public Class Global
Inherits System.Web.HttpApplication
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' bir impo nesnesi oluşturulur
Dim objImpot As impot
Try
objImpot = New impot(New impotsOLEDB(ConfigurationSettings.AppSettings("chaineConnexion")))
' nesneyi uygulamaya eklenir
Application("objImpot") = objImpot
' hata yok
Application("erreur") = False
Catch ex As Exception
'hata oluştu, bunu uygulamaya kaydediyoruz
Application("erreur") = True
Application("message") = ex.Message
End Try
End Sub
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' oturumun başlangıcı - boş bir simülasyon listesi oluşturulur
Dim simulations As New DataTable("simulations")
simulations.Columns.Add("marié", Type.GetType("System.String"))
simulations.Columns.Add("enfants", Type.GetType("System.String"))
simulations.Columns.Add("salaire", Type.GetType("System.Int32"))
simulations.Columns.Add("impôt", Type.GetType("System.Int32"))
Session.Item("simulations") = simulations
End Sub
End Class
Uygulama başlatıldığında (uygulamaya yapılan ilk istek), [Application_Start] prosedürü yürütülür. Bu prosedür, verilerini OLEDB kaynağından alan [impot] türünde bir nesne oluşturmaya çalışır. Okuyucu, bu sınıfın tanımlandığı 5. bölümü, unutmuşsa, okumasını öneririz. Veri kaynağı mevcut değilse, [impot] nesnesinin oluşturulması başarısız olabilir. Bu durumda, hata uygulamada kaydedilir; böylece sonraki tüm sorgular, nesnenin düzgün bir şekilde başlatılamadığını bilir. Oluşturma işlemi başarılı olursa, oluşturulan [impot] nesnesi de uygulamada kaydedilir. Bu nesne, tüm vergi hesaplama sorguları tarafından kullanılacaktır. Bir müşteri ilk isteğini yaptığında, [Application_Start] yordamı tarafından kendisi için bir oturum oluşturulur. Bu oturum, müşterinin yapacağı çeşitli vergi hesaplama simülasyonlarını kaydetmek amacıyla kullanılır. Bu simülasyonlar, "simulations" oturum anahtarıyla ilişkilendirilmiş bir [DataTable] nesnesinde saklanacaktır. Oturum başladığında, bu anahtar, yapısı önceden tanımlanmış ancak içeriği boş olan bir [DataTable] nesnesine eşleştirilir. Uygulama için gerekli bilgiler, [wenConfig] yapılandırma dosyasına yerleştirilir:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="chaineConnexion" value="Provider=Microsoft.Jet.OLEDB.4.0; Ole DB Services=-4; Data Source=D:\data\devel\aspnet\poly\webforms2\vs\impots6\impots.mdb" />
</appSettings>
</configuration>
[chaineConnexion] anahtarı, OLEDB kaynağına bağlantı dizesini belirtir. Kontrol kodunun diğer kısmı [main.aspx.vb]'te bulunur:
Imports System.Collections
Imports Microsoft.VisualBasic
Imports st.istia.univangers.fr
Imports System
Imports System.Web.UI.Control
Imports System.Data
Public Class main
Inherits System.Web.UI.Page
Protected WithEvents rdOui As System.Web.UI.WebControls.RadioButton
Protected WithEvents rdNon As System.Web.UI.WebControls.RadioButton
Protected WithEvents txtEnfants As System.Web.UI.WebControls.TextBox
Protected WithEvents txtSalaire As System.Web.UI.WebControls.TextBox
Protected WithEvents btnCalculer As System.Web.UI.WebControls.Button
Protected WithEvents btnEffacer As System.Web.UI.WebControls.Button
Protected WithEvents panelform As System.Web.UI.WebControls.Panel
Protected WithEvents lnkForm2 As System.Web.UI.WebControls.LinkButton
Protected WithEvents panelerreurs As System.Web.UI.WebControls.Panel
Protected WithEvents rfvEnfants As System.Web.UI.WebControls.RequiredFieldValidator
Protected WithEvents rvEnfants As System.Web.UI.WebControls.RangeValidator
Protected WithEvents rfvSalaire As System.Web.UI.WebControls.RequiredFieldValidator
Protected WithEvents rptErreurs As System.Web.UI.WebControls.Repeater
Protected WithEvents dgSimulations As System.Web.UI.WebControls.DataGrid
Protected WithEvents revSalaire As System.Web.UI.WebControls.RegularExpressionValidator
Protected WithEvents cvMarie As System.Web.UI.WebControls.CustomValidator
Protected WithEvents panelsimulations As System.Web.UI.WebControls.Panel
' yerel değişkenler
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
...
End Sub
Private Sub afficheErreurs(ByRef erreurs As ArrayList)
...
End Sub
Private Sub afficheFormulaire()
...
End Sub
Private Sub afficheSimulations(ByRef simulations As DataTable, ByRef lien As String)
...
End Sub
Private Sub btnCalculer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculer.Click
....
End Sub
Private Sub lnkForm1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
...
End Sub
Private Sub lnkForm2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lnkForm2.Click
...
End Sub
Private Sub btnEffacer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEffacer.Click
...
End Sub
Private Sub razForm()
...
End Sub
Private Sub cvMarie_ServerValidate(ByVal source As System.Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs)
...
End Sub
End Class
Kod tarafından işlenen ilk olay [Page_Load]'tir:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' öncelikle, uygulamanın durumuna bakılıyor
If CType(Application("erreur"), Boolean) Then
' uygulama başlatılamadı
' hata görünümünü görüntülüyoruz
Dim erreurs As New ArrayList
erreurs.Add("Application momentanément indisponible (" + CType(Application("message"), String) + ")")
afficheErreurs(erreurs)
Exit Sub
End If
' hata yok - ilk istekte form görüntülenir
If Not IsPostBack Then afficheFormulaire()
End Sub
İsteği işlemeye başlamadan önce, uygulamanın düzgün bir şekilde başlatılabildiğinden emin oluruz. Aksi takdirde, [erreurs] görünümünü [afficheErreurs] prosedürüyle görüntüleriz. Eğer bu ilk istekse (IsPostBack=false), [afficheFormulaire] ile [formulaire] görünümünü görüntüleriz.
[erreurs] görünümünü görüntüleyen prosedür şöyledir:
Private Sub afficheErreurs(ByRef erreurs As ArrayList)
' hata listesi oluşturulur
With rptErreurs
.DataSource = erreurs
.DataBind()
End With
' konteynerler görüntüleniyor
panelerreurs.Visible = True
panelform.Visible = False
panelsimulations.Visible = False
Exit Sub
End Sub
Prosedür, [erreurs]'te bulunan [ArrayList] türündeki hata mesajları listesini parametre olarak alır. Bu veri kaynağını, görüntüleme görevini üstlenen [rptErreurs] bileşenine bağlamamız yeterlidir.
[formulaire] görünümünü görüntüleyen prosedür şöyledir:
Private Sub afficheFormulaire()
' formu görüntüler
panelform.Visible = True
' diğer konteynerler gizlenir
panelerreurs.Visible = False
panelsimulations.Visible = False
End Sub
Bu prosedür, yalnızca [panelform] konteynerini görünür hale getirir. Bileşenler, gönderilen veya önceki değerleriyle (VIEWSTATE) görüntülenir.
Kullanıcı, [formulaire] görünümündeki [Calculer] düğmesine tıkladığında, POST'ten [main.aspx]'e bir geçiş yapılır. [Page_Load] prosedürü çalıştırılır, ardından [btnCalculer_Click] prosedürü çalıştırılır:
Private Sub btnCalculer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculer.Click
' girilen verilerin geçerliliği kontrol edilir, hata varsa bildirilir
If Not Page.IsValid Then
afficheFormulaire()
Exit Sub
End If
' hata yok - vergi hesaplanır
Dim impot As Long = CType(Application("objImpot"), impot).calculer( _
rdOui.Checked, CType(txtEnfants.Text, Integer), CType(txtSalaire.Text, Long))
' sonuç mevcut simülasyonlara eklenir
Dim simulations As DataTable = CType(Session.Item("simulations"), DataTable)
Dim simulation As DataRow = simulations.NewRow
simulation("marié") = CType(IIf(rdOui.Checked, "oui", "non"), String)
simulation("enfants") = txtEnfants.Text.Trim
simulation("salaire") = CType(txtSalaire.Text.Trim, Long)
simulation("impôt") = impot
simulations.Rows.Add(simulation)
' simülasyonlar oturuma eklenir
Session.Item("simulations") = simulations
' simülasyonlar sayfası görüntülenir
afficheSimulations(simulations, "Retour au formulaire")
End Sub
İşlem, sayfanın geçerliliğinin kontrol edilmesiyle başlar. Burada şunu hatırlatmak gerekir ki, [btnCalculer_Click] işlemi yürütüldüğünde, geçerlilik kontrolleri tamamlanmış ve sayfanın [IsValid] özniteliği ayarlanmış olur. Sayfa geçerli değilse, [formulaire] görünümü yeniden görüntülenir ve işlem sonlandırılır. [formulaire] görünümündeki, [IsValid] ile [false] arasında bir değere sahip olan doğrulama bileşenleri, [ErrorMessage] özniteliğini gösterecektir. Sayfa geçerliyse, vergi tutarı, uygulamanın başlatılması sırasında uygulamada depolanmış olan [impot] türündeki nesne kullanılarak hesaplanır. Bu yeni simülasyon, daha önce yapılmış simülasyonlar listesine eklenir ve oturumda depolanır.
Son olarak, [simulations] görünümü, aşağıdaki [afficheSimulations] prosedürü tarafından görüntülenir:
Private Sub afficheSimulations(ByRef simulations As DataTable, ByRef lien As String)
' veri tablosunu simülasyon kaynağına bağlanıyor
With dgSimulations
.DataSource = simulations
.DataBind()
End With
' bağlantı
lnkForm2.Text = lien
' görünümler
panelsimulations.Visible = True
panelerreurs.Visible = False
panelform.Visible = False
End Sub
Bu prosedürün iki parametresi vardır:
- [simulations]'te bulunan, [DataTable] türünde bir simülasyon listesi
- [lien]'teki bağlantı metni
[simulations] veri kaynağı, bunu görüntülemekle görevli bileşene bağlıdır. Bağlantı metni ise görünümdeki [LinkButton] nesnesinin [Text] özelliğine yerleştirilir.
Kullanıcı, [formulaire] görünümündeki [Effacer] düğmesine tıkladığında, [btnEffacer_click] yordamı çalıştırılır (her zaman [Page_Load]'ten sonra):
Private Sub btnEffacer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEffacer.Click
' boş formu görüntüler
razForm()
afficheFormulaire()
End Sub
Private Sub razForm()
' formu boşaltır
rdOui.Checked = False
rdNon.Checked = True
txtEnfants.Text = ""
txtSalaire.Text = ""
End Sub
Yukarıdaki kod, açıklama gerektirmeyecek kadar basittir. Geriye, [erreurs] ve [simulations] görünümlerindeki bağlantılara yapılan tıklamaları yönetmek kalıyor:
Private Sub lnkForm1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lnkForm1.Click
' formu görüntüler
afficheFormulaire()
End Sub
Private Sub lnkForm2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lnkForm2.Click
' formu görüntüler
afficheFormulaire()
End Sub
Her iki prosedür de sadece [formulaire] görünümünü görüntülemekle yetinir. Bu formdaki alanların, ya kendileri için gönderilen değerleri ya da önceki değerlerini alacağını biliyoruz. Burada olduğu gibi, müşterinin POST formu, form alanları için herhangi bir değer göndermediğinden, bu alanlar önceki değerlerine geri dönecektir. Dolayısıyla form, kullanıcı tarafından girilen değerlerle görüntülenir.
8.9.4. Testler
Uygulama için gerekli tüm dosyalar <application-path> klasörüne yerleştirilir: ![]() | [bin] klasörü, uygulama için gerekli olan [impot], [impotsData] ve [impotsOLEDB] sınıflarını içeren DLL dosyasını barındırır: |
İsteyen okuyucular, yukarıdaki [impot.dll] dosyasının nasıl oluşturulacağının açıklandığı 5. bölümü tekrar okuyabilirler. Bu işlem tamamlandıktan sonra, Cassini sunucusu (<application-path>,/impots6) parametreleriyle başlatılır. Bir tarayıcıdan [http://impots6/main.aspx] URL'si çağrılır:

ACCESS adlı dosyayı [impots.mdb]'ten [impots1.mdb] olarak yeniden adlandırırsak, şu sayfa karşımıza çıkar:

8.9.5. Sonuç
Sadece sunucu bileşenlerini kullanan MVC adlı bir uygulamamız var. Bu bileşenlerin kullanımı, uygulamanın sunum kısmını kontrol kısmından tamamen ayırmamızı sağladı. Sunum kodunda, kontrol kodu tarafından hesaplanan ve HTML kodunu içeren bir değere sahip değişkenler bulunduğu için, bu durum şimdiye kadar mümkün değildi. Artık durum böyle değil.






















