8. ASP اجزای سرور – ۲
8.1. Introduction
ما کار خود را بر روی رابط کاربری با بررسی موارد زیر ادامه میدهیم:
- کامپوننتهای اعتبارسنجی دادهها
- نحوه پیوند دادن دادهها به کامپوننتهای سرور
- کامپوننتهای سرور HTML
8.2. کامپوننتهای اعتبارسنجی دادهها
8.2.1. مقدمه
در برنامههای مبتنی بر فرم، بررسی اعتبار دادههای وارد شده در فرمها ضروری است. در مثال محاسبه مالیات، فرم زیر را داشتیم:

پس از دریافت مقادیر از این فرم، باید اعتبار دادههای وارد شده را بررسی کنیم: تعداد فرزندان و حقوق باید اعداد صحیح مثبت یا صفر باشند. اگر اینطور نباشد، فرم به همان شکلی که وارد شده به کلاینت بازگردانده میشود، به همراه پیامهایی که خطاها را نشان میدهند. ما این سناریو را با استفاده از دو ویو مدیریت کرده بودیم، یکی برای فرم بالا و دیگری برای خطاها:

ASP.NET کامپوننتهایی به نام کامپوننتهای اعتبارسنجی را فراهم میکند که امکان بررسی موارد زیر را میدهند:
کامپوننت | نقش |
بررسی میکند که یک فیلد خالی نباشد | |
دو مقدار را با یکدیگر بررسی میکند | |
بررسی میکند که یک مقدار بین دو حد قرار دارد | |
بررسی میکند که یک فیلد با یک عبارت منظم مطابقت دارد | |
به توسعهدهنده اجازه میدهد تا قواعد اعتبارسنجی خود را تعریف کند – این کامپوننت میتواند جایگزین همهٔ موارد دیگر شود | |
امکان گروهبندی پیامهای خطا تولیدشده توسط بررسیهای قبلی را در یک مکان واحد روی صفحه فراهم میکند |
اکنون هر یک از این کامپوننتها را معرفی خواهیم کرد.
8.2.2. RequiredFieldValidator
ما در حال ساخت صفحه زیر هستیم: [requiredfieldvalidator1.aspx]:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
1 | TextBox | EnableViewState=true | میدان ورودی | |
2 | RequiredFieldValidator | EnableViewState=false EnableClientScript=true پیام خطا=میدان [name] الزامی است | کامپوننت اعتبارسنجی | |
۳ | دکمه | EnableViewState=false ValidationCauses=true | دکمه [submit] |
میدان [RequiredFieldValidator1] برای نمایش پیام خطا در صورتی که میدان [txtNom] خالی باشد یا شامل رشتهای از فضاها باشد، استفاده میشود. ویژگیهای آن به شرح زیر است:
یک فیلد که مقدار آن باید توسط کامپوننت بررسی شود. مقدار یک کامپوننت به چه معناست؟ این مقدار، ارزش ویژگی [value] در تگ متناظر HTML است. برای [TextBox]، این محتواِ فیلد ورودی خواهد بود؛ برای [DropDownList]، این مقدار عنصر انتخابشده خواهد بود. | |
بولی – تنظیم آن روی true نشان میدهد که محتویات فیلد قبلی نیز باید در سمت کلاینت اعتبارسنجی شوند. در این صورت، فرم تنها در صورتی توسط مرورگر ارسال میشود که هیچ خطایی نداشته باشد. با این حال، بررسیهای اعتبارسنجی در سمت سرور نیز انجام میشوند، برای مثال در صورتی که کلاینت مرورگر نباشد. | |
پیام خطایی که کامپوننت باید در صورت تشخیص خطا نمایش دهد |
اعتبارسنجی دادهها در صفحه تنها در صورتی انجام میشود که دکمهای یا پیوندی که [POST] را در صفحه فعال کرده باشد، دارای ویژگی [CausesValidation=true] باشد. [true] مقدار پیشفرض این ویژگی است.
بیایید این برنامه را اجرا کنیم. ابتدا از یک مرورگر [Mozilla] استفاده خواهیم کرد:

کد HTML که توسط [Mozilla] دریافت شده است به شرح زیر است:
<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] از طریق ویژگی [onclick] به یک تابع جاوااسکریپت متصل است. همچنین میتوانیم ببینیم که صفحه حاوی هیچ کد [Javascript] نیست. آزمون [typeof(Page_ClientValidate) == 'function'] ناموفق خواهد بود و تابع جاوااسکریپت فراخوانی نخواهد شد. سپس فرم به سرور ارسال میشود تا بررسیهای اعتبارسنجی را انجام دهد. بیایید از دکمه [Envoyer] بدون مشخص کردن نام استفاده کنیم. پاسخ سرور به شرح زیر است:

چه اتفاقی افتاد؟ فرم برای سرور ارسال شد. سپس سرور کد تمام کامپوننتهای اعتبارسنجی روی صفحه را اجرا کرد. در این مورد، تنها یک مورد وجود دارد. اگر حتی یک جزء اعتبارسنجی خطایی را تشخیص دهد، سرور فرم را دقیقاً همانطور که ارسال شده بازمیگرداند (در واقع، برای جزئیاتی با [EnableViewState=true]، به همراه یک پیام خطا برای هر جزء اعتبارسنجی که خطایی را تشخیص داده است). این پیام، ویژگی [ErrorMessage]ِ کامپوننت اعتبارسنجی است. این همان سازوکاری است که در بالا میبینیم. اگر چیزی را در فیلد [nom] وارد کنیم، پیام خطا دیگر هنگام ارسال فرم نمایش داده نمیشود:

اکنون، بیایید از اینترنت اکسپلورر استفاده کنیم و URL [http://localhost/requiredfieldvalidator1.aspx] را درخواست کنیم. صفحه زیر را دریافت میکنیم:

کد HTML که توسط IE دریافت شده به شرح زیر است:
<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>
میتوانیم ببینیم که این کد بسیار طولانیتر از کدی است که توسط [Mozilla] دریافت شده است. در اینجا وارد جزئیات نمیشویم. این تفاوت از این واقعیت ناشی میشود که سرور در سند HTML که ارسال کرده است، توابع جاوااسکریپت را گنجانده است. چرا دو کد متفاوت HTML وجود دارد در حالی که URL درخواستشده توسط هر دو مرورگر یکسان است؟ ما قبلاً اشاره کردهایم که فناوری ASP.NET باعث میشود سرور سند HTML ارسالی به کلاینت را برای مطابقت با مشخصات آن کلاینت تطبیق دهد. مرندرهای مختلفی در بازار وجود دارند که همگی از قابلیتهای یکسانی برخوردار نیستند. برای مثال، مرورگرهای مایکروسافت و نتاسکیپ از مدل شیءگرایی یکسانی برای سند دریافتی خود استفاده نمیکنند. در نتیجه، کد جاوااسکریپتی که برای دستکاری این سند در سمت مرورگر به کار میرود، در این دو مرورگر متفاوت است. به همین ترتیب، سازندگان مرورگر نسخههای متوالی از مرورگرهای خود را منتشر کردهاند و پیوسته قابلیتهای آنها را بهبود میبخشند. در نتیجه، ممکن است سند HTML که توسط IE5 قابل درک است، توسط IE3 قابل درک نباشد. مثال فوق این تطبیق توسط سرور را برای سازگاری با کلاینت خود نشان میدهد. به دلیلی که در اینجا به تفصیل مورد بررسی قرار نگرفته است، وبسرور تشخیص داد که کلاینت [Mozilla] قادر به پردازش کد اعتبارسنجی جاوااسکریپت نیست. در نتیجه، این کد در سند HTML که برای آن ارسال شد، گنجانده نشد و اعتبارسنجی در سمت سرور انجام شد. برای [IE6]، این کد جاوااسکریپت در سند HTML که ارسال شد، گنجانده شده است، همانطور که میبینیم. برای مشاهده عملکرد آن، بیایید آزمایش زیر را انجام دهیم:
- وبسرور را متوقف کنید
- از دکمه [Envoyer] بدون پر کردن فیلد [nom] استفاده میکنیم
سپس صفحه جدید زیر به ما نمایش داده میشود:

در واقع این مرورگر است که پیام خطا را نمایش داده است. این به این دلیل است که سرور متوقف شده است. ما میتوانیم این را با وارد کردن چیزی در فیلد [nom] و ارسال آن تأیید کنیم. این بار، پاسخ به شرح زیر است:

چه اتفاقی افتاد؟ مرورگر کد اعتبارسنجی جاوا اسکریپت را اجرا کرد. این کد تشخیص داد که صفحه معتبر است. بنابراین مرورگر فرم را به وب سرور ارسال کرد که خاموش بود. مرورگر متوجه این موضوع شد و صفحه نشان داده شده در بالا را نمایش داد. اگر سرور را مجدداً راهاندازی کنید، همه چیز به حالت عادی بازمیگردد.
از این مثال چه میتوانیم بیاموزیم؟
- ارزش مفهوم مؤلفه اعتبارسنجی، که امکان بازگرداندن هر فرم نادرست به سمت کلاینت را فراهم میکند
- ارزش [VIEWSTATE]، که امکان بازگرداندن این فرم را دقیقاً به همان شکلی که ارسال شده بود فراهم میکند
- توانایی سرور برای سازگار شدن با کلاینت خود. کلاینت از طریق هدرهای HTTP و [User-Agent:] که به سرور ارسال میکند، شناسایی میشود. بنابراین این سرور نیست که «حدس» میزند با چه کسی سر و کار دارد. این قابلیت تطبیق برای توسعهدهنده بسیار مفید است، زیرا او نیازی ندارد نگران نوع کلاینتی باشد که برنامهاش با آن در تعامل است.
8.2.3. CompareValidator
ما در حال ساخت صفحه زیر هستیم: [comparevalidator1.aspx]:

خیر. | نام | نوع | ویژگیها | نقش |
۱ | DropDownList | EnableViewState=true | لیست کشویی | |
2 | DropDownList | EnableViewState=true | لیست کشویی | |
۳ | CompareValidator | EnableViewState=false EnableClientScript=true پیام خطا=انتخاب ۱ نامعتبر مقدار برای مقایسه=؟ Operator=NotEqual Type=string | کامپوننت اعتبارسنجی | |
۴ | CompareValidator | EnableViewState=false EnableClientScript=true ErrorMessage=انتخاب ۲ نامعتبر است ControlToCompare=? Operator=NotEqual Type=string | کامپوننت اعتبارسنجی | |
5 | دکمه | EnableViewState=false ValidationReasons=true | دکمه [submit] |
کامپوننت [CompareValidator] برای مقایسه دو مقدار در مقابل یکدیگر استفاده میشود. عملگرهایی که میتوان استفاده کرد [Equal, NotEqual, LessThan, LessThanEqual, GreaterThan, GreaterThanEqual] هستند. مقدار اول توسط خاصیت [ControlToValidate] و مقدار دوم توسط [ValueToCompare] (اگر مقدار اول قرار است با یک مقدار ثابت مقایسه شود) یا توسط [ControlToCompare] (اگر قرار است با مقدار یک کامپوننت دیگر مقایسه شود) تنظیم میشود. ویژگیهای مهم کامپوننت [CompareValidator] به شرح زیر است:
میدانی که محتوای آن باید توسط کامپوننت بررسی شود | |
بولی – تنظیم آن روی true نشان میدهد که محتوای فیلد قبلی نیز باید در سمت کلاینت اعتبارسنجی شود | |
پیام خطایی که کامپوننت باید در صورت تشخیص خطا نمایش دهد | |
مقداری که مقدار فیلد باید با آن مقایسه شود [ControlToValidate] | |
کامپوننتی که مقدار فیلد باید با آن مقایسه شود [ControlToValidate] | |
عملگر مقایسه بین دو مقدار | |
نوع مقادیری که باید مقایسه شوند |
کد نمایش برای این صفحه به شرح زیر است:
<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>
محدودیتهای اعتبارسنجی برای صفحه به شرح زیر است:
- مقدار انتخابشده در [cmbChoix1] باید با رشته "?" متفاوت باشد. این به معنای ویژگیهای زیر برای مؤلفه [CompareValidator1] است: Operator=NotEqual, ValueToCompare=?, Type=string
- مقدار انتخابشده در [cmbChoix2] باید با مقدار انتخابشده در [cmbChoix1] متفاوت باشد. این به معنای ویژگیهای زیر برای کامپوننت [CompareValidator2] است: Operator=NotEqual, ControlToCompare=cmbChoix1, Type=string
ما این برنامه را اجرا میکنیم. در اینجا مثالی از یک صفحه دریافتشده در طول مبادلات کلاینت-سرور آورده شده است:

اگر به همان صفحه از طریق Internet Explorer 6 دسترسی پیدا شود، کد جاوااسکریپت در صفحه گنجانده میشود که باعث میشود رفتار آن کمی متفاوت باشد. هرگونه خطا به محض اینکه کاربر مقداری را در یکی از فهرستهای کشویی تغییر دهد، علامتگذاری میشود. این امر تجربه کاربری را بهبود میبخشد.
8.2.4. CustomValidator, RangeValidator
ما در حال ساخت صفحه زیر هستیم: [customvalidator1.aspx]:

خیر. | نام | نوع | ویژگیها | نقش |
DropDownList | EnableViewState=true | لیست کشویی | ||
CompareValidator | EnableViewState=false EnableClientScript=true ErrorMessage=صلاحیت نامعتبر عملگر=مساوی نیست مقدار برای مقایسه=؟ Type=String | کامپوننت اعتبارسنجی برای کنترل [1] | ||
TextBox | EnableViewState=false | میدان ورودی | ||
CustomValidator | EnableViewState=false EnableClientScript=true پیام خطا=تعیین صلاحیت نامعتبر ClientValidationFunction=chkOtherQualification | کامپوننت اعتبارسنجی فیلد [3] | ||
TextBox | EnableViewState=false | میدان ورودی | ||
RangeValidator | EnableViewState=false EnableClientScript=true ErrorMessage=سال فارغالتحصیلی باید در بازه [1990,2004] باشد MinValue=1990 MaxValue=2004 Type=Integer ControlToValidate=txtAnDiplome | کامپوننت اعتبارسنجی برای فیلد [5] | ||
RequiredFieldValidator | EnableViewState=false EnableClientScript=true پیام خطا=سال صلاحیت مورد نیاز ControlToValidate=txtAnDiplome | کامپوننت اعتبارسنجی فیلد [5] | ||
دکمه | EnableViewState=false ValidationReasons=true | دکمه [submit] |
میدان [RangeValidator] برای بررسی اینکه مقدار یک کنترل بین دو حد [MinValue] و [MaxValue] قرار دارد، استفاده میشود. ویژگیهای آن به شرح زیر است:
میدانی که مقدار آن باید توسط کامپوننت بررسی شود | |
منطقی – وقتی روی true تنظیم شود، این نشان میدهد که محتویات فیلد قبلی نیز باید در سمت کلاینت اعتبارسنجی شود | |
پیام خطایی که کامپوننت باید در صورت تشخیص خطا نمایش دهد | |
حداقل مقدار برای فیلدی که باید بررسی شود | |
حداکثر مقدار برای فیلدی که باید بررسی شود | |
نوع مقدار فیلد برای اعتبارسنجی |
میدان [CustomValidator] امکان بررسیهای اعتبارسنجی را فراهم میکند که نمیتوان آنها را با کامپوننتهای اعتبارسنجی ارائهشده توسط ASP.NET انجام داد. این اعتبارسنجی توسط تابعی که توسعهدهنده نوشته است انجام میشود. این تابع در سمت سرور اجرا میشود. از آنجا که اعتبارسنجی میتواند در سمت کلاینت نیز انجام شود، توسعهدهنده ممکن است نیاز داشته باشد تابعی جاوااسکریپتی توسعه دهد تا در سند HTML گنجانده شود. ویژگیهای آن به شرح زیر است:
میدانی که مقدار آن باید توسط کامپوننت اعتبارسنجی شود | |
منطقی – اگر true باشد، نشان میدهد که محتویات فیلد قبلی نیز باید در سمت کلاینت اعتبارسنجی شود | |
پیام خطایی که کامپوننت باید در صورت تشخیص خطا نمایش دهد | |
تابعی که باید در سمت کلاینت اجرا شود |
کد نمایش صفحه به شرح زیر است:
<%@ 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>
ویژگی [OnServerValidate] از کامپوننت [CustomValidator] برای مشخص کردن تابع مسئول اعتبارسنجی سمت سرور استفاده میشود. در مثال بالا، کامپوننت [CustomValidator1] رویه زیر [CustomValidator1_ServerValidate_1] را فراخوانی میکند:
<%@ Page Language="VB" %>
<script runat="server">
Sub CustomValidator1_ServerValidate_1(sender As Object, e As ServerValidateEventArgs)
' میدان [txtAutreDiplome] نباید خالی باشد اگر [cmbDiplomes]=[autre]
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] دو پارامتر میگیرد:
- sender: شیئی که رویداد را فعال کرده است
- e: رویداد. این رویه باید ویژگی [e.IsValid] را در صورت صحیح بودن دادههای اعتبارسنجیشده روی true و در غیر این صورت روی false تنظیم کند.
در اینجا، بررسیهای زیر انجام میشود:
- فهرست کشویی [cmbDiplomes] نمیتواند مقدار [?] را داشته باشد. این مورد توسط کامپوننت [CompareValidator2] بررسی میشود.
- کاربر یک مدرک تحصیلی را از فهرست کشویی [cmbDiplomes] انتخاب میکند. اگر مدرک تحصیلی او در فهرست وجود نداشته باشد، میتواند گزینه [Autre] را از فهرست انتخاب کند. سپس باید مدرک خود را در فیلد ورودی [txtAutreDiplome] وارد کنند. اگر [Autre] در [cmbDiplomes] انتخاب شده باشد، فیلد [txtAutreDiplome] نباید خالی باشد. اگر هیچیک از [Autre] یا [?] در [cmbDiplomes] انتخاب نشده باشد، آنگاه فیلد [txtAutreDiplome] باید خالی باشد. این مورد توسط تابع مرتبط با کامپوننت [CustomValidator1] بررسی میشود.
- سال فارغالتحصیلی باید در بازه مشخصشده در [1900-2004] قرار داشته باشد. این مورد توسط [RangeValidator1] بررسی میشود. با این حال، اگر کاربر فیلد را خالی بگذارد، تابع اعتبارسنجی برای [RangeValidator1] استفاده نمیشود. بنابراین، کامپوننت [RequiredFieldValidator2] برای بررسی اینکه فیلد حاوی داده است، اضافه میشود. این یک قاعده کلی است. محتویات یک فیلد در صورتی که خالی باشد، بررسی نمیشوند. تنها استثنا زمانی است که فیلد با کامپوننت [RequiredFieldValidator] مرتبط باشد.
در اینجا مثالی از یک اجرای برنامه در مرورگر [Mozilla] آورده شده است:

اگر از مرورگر [IE6] استفاده کنیم، میتوانیم یک تابع اعتبارسنجی سمت کلاینت برای کامپوننت [CustomValidator1] اضافه کنیم. برای این کار، این کامپوننت دارای ویژگیهای زیر است:
- EnableClientScript=true
- ClientValidationFunction=chkAutreDiplome
تابع [chkAutreDiplome ] به شرح زیر است:
<head>
<meta http-equiv="pragma" content="no-cache" />
<script language="javascript">
function chkAutreDiplome(source,args){
//اعتبار میدان txtAutreDiplome را بررسی میکند
with(document.frmCandidature){
diplome=cmbDiplomes.options[cmbDiplomes.selectedIndex].text;
args.IsValid= !(diplome=="[Autre]" && txtAutreDiplome.value=="")
&& ! (diplome!="[Autre]" && diplome!="?" && txtAutreDiplome.value!="");
}
}
</script>
</head>
تابع [chkAutreDiplome] همان دو پارامتر تابع سرور [CustomValidator1_ServerValidate_1] را میگیرد:
- منبع: ابجکتی که رویداد را فعال کرده است
- args: رویداد. این دارای یک ویژگی به نام [IsValid] است که اگر دادههای اعتبارسنجیشده صحیح باشند، باید توسط تابع روی true تنظیم شود. مقدار false باعث نمایش پیام خطای مرتبط در محل کامپوننت اعتبارسنجی میشود و فرم برای سرور ارسال نخواهد شد.
8.2.5. RegularExpressionValidator
ما در حال ساخت صفحه [regularexpressionvalidator1.aspx] زیر هستیم:

خیر. | name | نوع | ویژگیها | نقش |
TextBox | EnableViewState=true | میدان ورودی | ||
RequiredFieldValidator | ControlToValidate=txtMel نمایش=پویا | کامپوننت اعتبارسنجی برای کنترل [1] | ||
RegularExpressionValidator | ControlToValidate=txtMel نمایش=پویا | کامپوننت اعتبارسنجی برای کنترل [1] | ||
دکمه | EnableViewState=false ValidationReasons=true | دکمه [submit] |
در اینجا، میخواهیم فرمت یک آدرس ایمیل را اعتبارسنجی کنیم. این کار را با استفاده از یک کامپوننت [RegularExpressionValidator] انجام میدهیم که به ما امکان میدهد یک فیلد را با استفاده از یک عبارت منظم (regular expression) اعتبارسنجی کنیم. شایان ذکر است که عبارت منظم، الگویی برای یک رشته از کاراکترها است. بنابراین، محتویات یک فیلد را با این الگو مطابقت میدهیم. از آنجایی که محتویات یک فیلد در صورت خالی بودن بررسی نمیشوند، ما همچنین به یک کامپوننت [RequiredFieldValidator] نیاز داریم تا بررسی کند که آدرس ایمیل خالی نیست. کلاس [RegularExpressionValidator] دارای خواصی مشابه با کلاسهای کامپوننت که قبلاً پوشش داده شدهاند، است:
field که مقدار آن باید توسط کامپوننت بررسی شود | |
بولی – وقتی روی true تنظیم شود، این نشان میدهد که محتویات فیلد قبلی نیز باید در سمت کلاینت اعتبارسنجی شود | |
پیام خطایی که کامپوننت باید در صورت تشخیص خطا نمایش دهد | |
بیان منظم (regular expression) که محتوای [ControlToValidate] بر اساس آن بررسی خواهد شد | |
حالت نمایش: ایستا: فیلد همیشه موجود است حتی اگر پیام خطا نمایش ندهد؛ پویا: فیلد فقط در صورتی که پیام خطا وجود داشته باشد، موجود است؛ هیچ: پیام خطا نمایش داده نمیشود. این فیلد برای سایر اجزا نیز وجود دارد اما تا به حال استفاده نشده است. |
الگوی عبارت منظم برای یک آدرس ایمیل میتواند به شکل زیر باشد: \s*[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+\s*
یک آدرس ایمیل به شکل [champ1.champ2....@champA.champB...] است. باید حداقل یک بخش قبل از علامت @ و حداقل دو بخش بعد از آن وجود داشته باشد. این بخشها از حروف عددی و علامت «-» تشکیل شدهاند. یک حرف عددی با نماد \w نمایش داده میشود. مجموعه [\w-] نمایانگر کاراکتر \w یا کاراکتر - است. علامت + پس از یک مجموعه S به این معنی است که آن مجموعه میتواند یک یا چند بار تکرار شود؛ علامت * به این معنی است که آن مجموعه میتواند صفر یا چند بار تکرار شود؛ علامت ؟ به این معنی است که آن مجموعه میتواند صفر یا یک بار تکرار شود.
یک فیلد در آدرس ایمیل با الگوی [\w-]+ مطابقت دارد. این واقعیت که باید حداقل یک فیلد قبل از علامت @ و حداقل دو فیلد بعد از آن، که با علامت . از هم جدا شدهاند، وجود داشته باشد، با الگوی زیر مطابقت دارد: [\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+. ممکن است به کاربر اجازه داده شود که قبل و بعد از آدرس، فاصلهگذاری کند. این فاصلهها در حین پردازش حذف خواهند شد. یک دنباله از فاصلهها، که میتواند خالی باشد، با الگوی \s* نشان داده میشود. بنابراین، عبارت منظم برای آدرس ایمیل به این صورت است: \s*[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+\s*.
بنابراین کد نمایش صفحه به شرح زیر است:
<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
به دلایل زیباییشناختی، ممکن است بخواهید پیامهای خطا را در یک مکان واحد گروهبندی کنید، همانند مثال زیر [summaryvalidator1.aspx]، که در آن تمام مثالهای قبلی را در یک صفحه گردآوری کردهایم:

تمام کنترلهای اعتبارسنجی دارای ویژگیهای زیر هستند:
- [Display=Dynamic] که تضمین میکند کنترلها در صورتی که پیام خطای آنها خالی باشد، هیچ فضایی در صفحه اشغال نکنند
- [EnableClientScript=false] برای غیرفعال کردن تمام اعتبارسنجیهای سمت کلاینت
- [Text=*]. این پیامی است که در صورت بروز خطا نمایش داده میشود؛ محتوای ویژگی [ErrorMessage] خود توسط کنترل [ValidationSummary] نمایش داده میشود که در ادامه ارائه میدهیم.
این مجموعه کنترلها در داخل یک کامپوننت [Panel] به نام [vueFormulaire] قرار میگیرد. در یک کامپوننت دیگر، [Panel]، که با نام [vueErreurs] شناخته میشود، یک کنترل با نام [ValidationSummary] قرار میدهیم:

خیر. | نام | نوع | ویژگیها | نقش |
1 | ValidationSummary | متن سربرگ=خطاهای زیر رخ داده است، فعالسازی اسکریپت سمت کلاینت=false، نمایش خلاصه=true | نمایش خطاها از تمام کنترلهای اعتبارسنجی صفحه | |
2 | LinkButton | CausesValidation=false | لینک بازگشت به فرم |
برای لینک [lnkErreursToFormulaire] نیازی به فعالسازی اعتبارسنجی نیست، زیرا این لینک هیچ مقداری را برای تأیید ارسال نمیکند.
هنگامی که تمام دادهها معتبر هستند، نمای زیر به کاربر نمایش داده میشود: [infos]:

1
خیر. | نام | نوع | ویژگیها | نقش |
1 | برچسب | پیام اطلاعاتی برای کاربر |
کد نمایش این صفحه به شرح زیر است:
<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>
در اینجا چند نمونه از نتایج بهدستآمده آورده شده است. ما نمای [formulaire] را بدون وارد کردن هیچ مقداری اعتبارسنجی میکنیم:

دکمه [Envoyer] پاسخ زیر را به ما میدهد:

نما [erreurs] نمایش داده شد. اگر از لینک برای بازگشت به فرم استفاده کنیم، آن را در وضعیت زیر مییابیم:

این نما [formulaire] است. به کاراکتر [*] در کنار دادهی نادرست توجه کنید. این فیلد [Text] از بررسیهای اعتبارسنجی است که نمایش داده شده است. اگر فیلدها را به درستی پر کنیم، نمای [infos] را خواهیم دید:

کد کنترل صفحه به شرح زیر است:
<%@ Page Language="VB" %>
<script runat="server">
' روند اجرایی هنگام بارگذاری صفحه
Sub page_Load(sender As Object, e As EventArgs)
'در اولین درخواست، نمای [formulaire] نمایش داده میشود
if not ispostback then
afficheVues(true,false,false)
end if
end sub
sub afficheVues(byval formulaireVisible as boolean, _
erreursVisible as boolean, infosVisible as boolean)
' مجموعهای از نماها
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)
'نمای فرم را نمایش میدهد
afficheVues(true,false,false)
' بازبینی اعتبارسنجیها را مجدداً اجرا میکند
Page.validate
End Sub
Sub btnEnvoyer_Click(sender As Object, e As EventArgs)
' آیا صفحه معتبر است؟
if not Page.IsValid then
' نمایش نما [erreurs]
afficheVues(false,true,false)
else
' در غیر این صورت نما [infos]
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>
- در رویه [Page_Load] که برای هر درخواست مشتری اجرا میشود، نما [formulaire] نمایش داده میشود، در حالی که سایر نماها مخفی هستند. این کار فقط در اولین درخواست انجام میشود. این رویه یک رویهٔ کمکی به نام [afficheVues] را فراخوانی میکند که سه مقدار بولی به آن ارسال میشود تا مشخص کند آیا سه نما نمایش داده شوند یا خیر.
- هنگامی که رویه [btnEnvoyer_Click] فراخوانی میشود، بررسیهای دادهای قبلاً انجام شده است. دکمه [btnEnvoyer]، از طریق خاصیت [CausesValidation=true]، این بررسیهای دادهای را راهاندازی میکند. تمام کنترلهای اعتبارسنجی اجرا شده و ویژگی [IsValid] آنها تنظیم شده است. این ویژگی نشان میدهد که آیا دادههای اعتبارسنجیشده توسط کنترل معتبر بودهاند یا خیر. علاوه بر این، ویژگی [IsValid] خود صفحه نیز تنظیم شده است. این مقدار تنها در صورتی به [vrai] تنظیم میشود که مقدار ویژگی [IsValid] تمام بررسیهای اعتبارسنجی روی صفحه، برابر با [vrai] باشد. بنابراین، رویه [btnEnvoyer_Click] با بررسی اینکه آیا صفحه معتبر است یا خیر، شروع میشود. اگر صفحه معتبر نباشد، نما [erreurs] نمایش داده میشود. این نما شامل کنترل [ValidationSummary] است که ویژگیهای [ErrorMessage] را از تمام کنترلها میگیرد (به اسکرینشات بالا مراجعه کنید). اگر صفحه معتبر باشد، نمای [infos] به همراه یک پیام اطلاعاتی نمایش داده میشود.
- روند [lnkErreursToFormulaire_Click] مسئول نمایش نما [formulaire] در وضعیتی است که در آن اعتبارسنجی شده است. تمام فیلدهای ورودی در نما [formulaire] که دارای ویژگی [EnableViewState=true] هستند، وضعیتشان بهطور خودکار بازسازی میشود. جالب اینجاست که وضعیت اجزای اعتبارسنجی بازیابی نمیشود. در واقع میتوانست انتظار داشت که با بازگشت به نمای [erreurs]، کنترلهای نامعتبر، فیلد [Text] خود را نمایش دهند. اما اینطور نیست. بنابراین ما با استفاده از متد [Page.Validate] صفحه، اعتبارسنجی دادهها را به اجبار اجرا کردیم. این کار باید پس از قابل مشاهده شدن پنل [vueFormulaire] انجام شود. بنابراین در مجموع دو مرحله اعتبارسنجی وجود دارد. در عمل باید از این امر اجتناب کرد. در اینجا، این مثال به ما امکان داد تا مفاهیم جدیدی را در مورد اعتبارسنجی صفحه معرفی کنیم.
8.3. کامپوننتهای ListControl و پیوند داده
تعدادی از مؤلفههای سرور مورد بررسی امکان نمایش یک فهرست مقادیر را فراهم میکنند (DropDownList, ListBox). سایر مؤلفهها که هنوز دربارهشان بحث نکردهایم، امکان نمایش چندین فهرست مقادیر در جداول را فراهم میکنند (HTML). برای همهٔ آنها، از طریق یک برنامه، میتوان مقادیر فهرستها را یکییکی با مؤلفهٔ مربوطه مرتبط کرد. همچنین امکان اتصال اشیاء پیچیدهتر به این کامپوننتها نیز وجود دارد، مانند اشیاء از انواع [Array]، [ArrayList]، [DataSet]، [HashTable]، ... که کدی را که دادهها را با کامپوننت مرتبط میکند، سادهتر میسازد. این ارتباط به عنوان پیوند داده (data binding) شناخته میشود.
تمام کامپوننتهایی که از کلاس [ListControl] مشتق شدهاند، میتوانند با یک لیست داده مرتبط شوند. اینها کامپوننتهای [DropDownList]، [ListBox]، [CheckButtonList] و [RadioButtonList] هستند. هر یک از این کامپوننتها میتواند به یک منبع داده متصل شود. این میتواند یکی از چندین گزینه باشد: [Array]، [ArrayList]، [DataTable]، [DataSet]، [HashTable]، …، عموماً یک شیء است که یکی از رابطهای IEnumerable، ICollection یا IListSource را پیادهسازی میکند. در اینجا تنها به چند نمونه از آنها میپردازیم. یک شیء [DataSet] نمایانگر یک پایگاه دادهٔ رابطهای است. بنابراین، این شیء مجموعهای از جداول مرتبط با یکدیگر از طریق روابط است. شیء [DataTable] نمایانگر چنین جدولی است. منبع داده ویژگیهای [Text] و [Value] را به هر یک از اعضای [Item] از شیء [ListControl] اختصاص میدهد. اگر T مقدار [Text] و V مقدار [Value] باشد، تگ HTML تولیدشده برای هر عنصر [ListControl] به شرح زیر است:
<option value="V">T</option> | |
<input type="checkbox" value="V">T | |
<input type="radio" value="V">T |
یک مؤلفه [ListControl] از طریق ویژگیهای زیر به یک منبع داده متصل میشود:
یک منبع داده [Array], [ArrayList], [DataTable], [DataSet], [HashTable], ... | |
که در آن منبع داده یک [DataSet] است، نام جدولی را که باید بهعنوان منبع داده استفاده شود، نشان میدهد. بنابراین منبع داده واقعی یک جدول است. | |
که در آن منبع داده یک جدول است ([DataTable], [DataSet])، نمایانگر نام ستون جدول است که مقادیر را برای فیلد [Text] عناصر در [ListControl] فراهم میکند | |
که در آن زمانی که منبع داده یک جدول ([DataTable], [DataSet]) است، نمایانگر نام ستون جدول است که مقادیر را برای فیلد [Value] عناصر در [ListControl] فراهم میکند |
ارتباط یک کامپوننت [ListControl] با یک منبع داده، کامپوننت را با مقادیر منبع داده اولیه نمیکند. این کار توسط عملیات [ListControl].DataBind انجام میشود.
بسته به ماهیت منبع داده، اتصال آن به یک کامپوننت [ListControl] به شیوههای متفاوتی انجام میشود:
[ListControl].DataSource=A میدانهای [Text] و [Value] از عناصر در [ListControl] مقادیرشان را از عناصر A خواهند داشت | |
[ListControl].DataSource=AL fields [Text] و [Value] از عناصر در [ListControl] مقادیرشان را از عناصر در AL خواهند داشت | |
[ListControl].DataSource=DT, [ListControl].DataTextField="col1", [ListControl]. DatavalueField ="col2" که col1 و col2 دو ستون در جدول DT هستند. میدانهای [Text] و [Value] در عناصر [ListControl] دارای مقادیری خواهند بود که با مقادیر ستونهای col1 و col2 در جدول DT مطابقت دارند. | |
[ListControl].DataSource=DS, [ListControl].DataSource="table", که در آن "table" نام یکی از جدولها در DS است. [ListControl].DataTextField="col1", [ListControl]. DatavalueField ="col2", که col1 و col2 دو ستون در جدول "table" هستند. میدانهای [Text] و [Value] از عناصر در [ListControl] دارای مقادیری خواهند بود که با مقادیر ستونهای col1 و col2 در جدول «table» مطابقت دارند. | |
[ListControl].DataSource=HT, [ListControl].DataTextField="key", [ListControl]. DatavalueField = "value"، جایی که [key] و [value] به ترتیب کلیدها و مقادیر HT هستند. |
ما این اطلاعات را با استفاده از مثال زیر، [databind1.aspx]، به کار خواهیم بست:
![]() |
در اینجا پنج پیوند داده داریم که هر یک دارای چهار کنترل از انواع [DropDownList]، [ListBox]، [CheckBoxList] و [RadioButtonList] هستند. این پنج پیوند از نظر منابع دادهشان متفاوتاند:
لینک | منبع داده |
آرایه | |
ArrayList | |
DataTable | |
DataSet | |
HashTable |
8.3.1. کد نمایش مؤلفه
کد نمایش برای کنترلها در لینک ۱ به شرح زیر است:
<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>
آنها برای لینکهای ۲ تا ۵ به جز شماره لینک یکسان هستند.
8.3.2. پیوند به یک منبع داده از نوع آرایه
چهار کنترل [ListBox] که در بالا فهرست شدهاند، در رویه [Page_Load] کد کنترل به شرح زیر مرتبط شدهاند:
' دادههای جهانی
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
' روند زمانی اجرا میشود که صفحه بارگذاری میشود
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
' منابع داده ایجاد میشوند تا به اجزا متصل شوند
createDataSources
'لینک به یک آرایه [Array]
bindToArray
' لینک به یک لیست [ArrayList]
bindToArrayList
' لینک به یک جدول [DataTable]
bindToDataTable
' لینک به یک گروه داده [DataSet]
bindToDataSet
' پیوند به یک فرهنگ لغت [HashTable]
bindToHashTable
end if
End Sub
sub createDataSources
'منابع دادهای را ایجاد میکند که به کامپوننتها متصل خواهند شد
' arraylist
dim i as integer
for i=0 to textes.length-1
myDataListe.add(textes(i))
next
' جدول داده
'دو ستون آن را تعریف میکند
myDataTable.Columns.Add("id",Type.GetType("System.Int32"))
myDataTable.Columns.Add("texte",Type.GetType("System.String"))
' جدول پر میشود
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
'مجموعه دادهها – یک جدول واحد
myDataSet.Tables.Add(myDataTable)
'جدول هش
for i=0 to textes.length-1
myHashTable.add(valeurs(i),textes(i))
next
end sub
' پیوند آرایه
sub bindToArray
' ارتباط با مؤلفهها
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
' انتخاب عناصر
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
کنترلها در اینجا تنها در اولین درخواست به دادهها متصل میشوند. پس از آن، کنترلها از طریق مکانیزم [VIEWSTATE] اجزای خود را حفظ خواهند کرد. این پیوند در رویه [bindToArray] انجام میشود. از آنجا که منبع داده از نوع [Array] است، تنها فیلد [DataSource] از کامپوننتهای [ListControl] مقداردهی اولیه میشود. کنترل با استفاده از روش [ListControl].DataBind از منبع داده مرتبط پر میشود. تنها در این صورت است که اشیاء [ListControl] دارای عناصر هستند. برخی از این عناصر سپس قابل انتخاب هستند.
8.3.3. پیوند به یک منبع داده از نوع ArrayList
منبع داده [myDataListe] در رویه [createDataSources] مقداردهی اولیه میشود:
' دادههای جهانی
dim textes() as string={"un","deux","trois","quatre"}
dim myDataListe as new ArrayList
..
' روندی که هنگام بارگذاری صفحه اجرا میشود
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
'منابع دادهای که باید به اجزا متصل شوند ایجاد میشوند
createDataSources
...
end if
End Sub
sub createDataSources
'منابع دادهای را ایجاد میکند که به کامپوننتها متصل خواهند شد
' آرایهفهرست
dim i as integer
for i=0 to textes.length-1
myDataListe.add(textes(i))
next
...
end sub
چهار کنترل [ListBox] برای لینک ۲ به شرح زیر در رویه [bindToArrayList] کد کنترل مرتبط شدهاند:
' پیوند آرایهلیست
sub bindToArrayList
' ارتباط با کامپوننتها
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
'انتخاب عناصر
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
از آنجا که منبع داده از نوع [ArrayList] است، تنها فیلد [DataSource] از کامپوننتهای [ListControl] مقداردهی اولیه میشود.
8.3.4. منبع داده از نوع DataTable
منبع داده [myDataTable] در رویه [createDataSources] مقداردهی اولیه میشود:
' دادههای سراسری
dim textes() as string={"un","deux","trois","quatre"}
dim myDataTable as new DataTable("table1")
...
' روندی که هنگام بارگذاری صفحه اجرا میشود
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
' ایجاد منابع داده برای پیوند با مؤلفهها
createDataSources
...
end if
End Sub
sub createDataSources
'منابع دادهای را ایجاد میکند که به کامپوننتها متصل خواهند شد
...
'جدول داده
' تعریف دو ستون آن
myDataTable.Columns.Add("id",Type.GetType("System.Int32"))
myDataTable.Columns.Add("texte",Type.GetType("System.String"))
' جدول را پر میکنیم
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
ما با ایجاد یک شیء [DataTable] با دو ستون: [id] و [texte] شروع میکنیم. ستون [id] فیلد [Value] را برای عناصر [ListControl] پر میکند و ستون [texte] فیلدهای [Text] آنها را پر میکند. جدول [DataTable] که شامل دو ستون است، به شرح زیر ساخته شده است:
myDataTable.Columns.Add("id",Type.GetType("System.Int32"))
myDataTable.Columns.Add("texte",Type.GetType("System.String"))
بنابراین ما یک جدول با دو ستون ایجاد میکنیم:
- اولی که «id» نام دارد، از نوع عدد صحیح است
- دومی، با نام «text»، از نوع string است
اکنون که ساختار جدول ایجاد شده است، میتوانیم آن را با کد زیر پر کنیم:
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] شامل اعداد صحیح از [0,1,..,n] خواهد بود، در حالی که ستون [texte] شامل مقادیر جدول [data] خواهد بود. پس از انجام این کار، جدول [dataListe] پر میشود. چهار کنترل [ListBox] در لینک ۳ در رویه [bindToDataTable] کد کنترل به شرح زیر مرتبط شدهاند:
sub bindToDataTable
'پیوند به کامپوننتها
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
' انتخاب عناصر
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
هر مؤلفه [ListControl] به منبع [myDataTable] با تخصیص موارد زیر به هر یک از آنها پیوند داده میشود:
جدول [myDataTable] منبع داده است. ستون [id] در این جدول، فیلدهای [Value] عناصر مؤلفه را پر میکند، در حالی که ستون [texte] فیلدهای [Text] آنها را پر میکند.
8.3.5. منبع داده از نوع DataSet
منبع داده [myDataSet] در رویه [createDataSources] مقداردهی اولیه میشود:
' دادههای جهانی
dim myDataTable as new DataTable("table1")
dim myDataSet as new DataSet
...
' روند اجرا هنگام بارگذاری صفحه
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
'منابع دادهای که باید به مؤلفهها متصل شوند ایجاد میشوند
createDataSources
...
end if
End Sub
sub createDataSources
'منابع دادهای را ایجاد میکند که به کامپوننتها متصل خواهند شد
'مجموعه داده – یک جدول واحد
myDataSet.Tables.Add(myDataTable)
...
end sub
یک شیء [DataSet] نمایانگر مجموعهای از جداول از نوع [DataTable] است. جدول [myDataTable] که قبلاً ایجاد شده است، به [DataSet] اضافه میشود. چهار کنترل [ListBox] در لینک ۴ به شرح زیر در رویه [bindToDataSet] کد کنترل پیوند داده شدهاند:
sub bindToDataSet
'لینکدهی به کامپوننتها
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
'انتخاب عناصر
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
هر جزء [ListControl] به منبع داده به شرح زیر متصل میشود:
گروه داده [myDataSet] منبع داده است. از آنجا که این ممکن است شامل چندین جدول باشد، نام جدول مورد استفاده در [DataMember] مشخص شده است. ستون [id] در این جدول، فیلدهای [Value] عناصر جزئی را پر میکند، در حالی که ستون [texte] فیلدهای [Text] آنها را پر میکند.
8.3.6. منبع داده از نوع HashTable
منبع داده [myHashTable] در رویه [createDataSources] مقداردهی اولیه میشود:
' دادههای جهانی
dim textes() as string={"un","deux","trois","quatre"}
dim valeurs() as string={"1","2","3","4"}
dim myHashTable as new HashTable
...
' روند اجرا شده هنگام بارگذاری صفحه
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
'منابع دادهای که باید به مؤلفهها متصل شوند ایجاد میشوند
createDataSources
...
end if
End Sub
sub createDataSources
'منابع دادهای را ایجاد میکند که به کامپوننتها متصل خواهند شد
...
'جدول هش
for i=0 to textes.length-1
myHashTable.add(valeurs(i),textes(i))
next
end sub
واژهنامه [myHashTable] را میتوان به صورت جدولی با دو ستون به نامهای «کلید» و «مقدار» در نظر گرفت. ستون [key] نمایانگر کلیدهای واژهنامه است و ستون [value] نمایانگر مقادیر مرتبط با آنهاست. ستون [key] شامل محتویات آرایه [valeurs] است و ستون [value] شامل محتویات آرایه [textes] است. این منبع به کنترلها در رویه [bindToHashTable] پیوند داده شده است:
sub bindToHashTable
'لینکدهی به کامپوننتها
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
'انتخاب عناصر
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
برای هر مؤلفه، پیوند با استفاده از دستورالعملهای زیر برقرار میشود:
منبع داده، فرهنگ لغت [myHashTable] است. مقادیر کنترلی توسط ستون [key] فرهنگ لغت و متون توسط ستون [value] فراهم میشوند. عناصر فرهنگ لغت به ترتیب کلیدها که اصولاً تصادفی است، در کنترلها درج میشوند.
8.3.7. دستورالعملهای وارد کردن فضاهای نام
تعدادى از فضاهاى نامى بهطور خودکار وارد یک صفحه ASP.NET مىشوند. این امر برای «System.Data» صدق نمیکند، که شامل کلاسهای [DataTable] و [DataSet] است. بنابراین، این کلاس باید وارد شود. این کار به شرح زیر انجام میشود:
<%@ Page Language="VB" %>
<%@ import Namespace="System.Data" %>
<script runat="server">
...
</script>
<html>
...
</html>
8.4. کامپوننت DataGrid و پیوند دادهها
کامپوننت [DataGrid] امکان نمایش دادهها در قالب جدول را فراهم میکند، اما فراتر از این نمایش ساده میرود:
- این امکان را فراهم میکند تا «نمایش بصری» جدول را با دقت پیکربندی کنید
- این امکان را میدهد که منبع داده بهروزرسانی شود
کامپوننت [DataGrid] هم قدرتمند و هم پیچیده است. ما آن را گام به گام معرفی خواهیم کرد.
8.4.1. نمایش منبع داده آرایهای: ArrayList، DataTable، DataSet
کامپوننت [DataGrid] به منابع داده از انواع [Array]، [ArrayList]، [DataTable] و [DataSet] را در جدولی از نوع HTML نمایش دهید. برای این چهار نوع داده، کافی است منبع را با خاصیت [DataSource] از کامپوننت [DataGrid] مرتبط کنید:
یک منبع داده [Array], [ArrayList], [DataTable], [DataSet], ... | |
جایی که منبع داده یک [DataSet] است، این نشاندهنده نام جدولی است که باید به عنوان منبع داده استفاده شود. بنابراین منبع داده واقعی یک جدول است. اگر این فیلد خالی گذاشته شود، تمام جداول در [DataSet] نمایش داده میشوند. |
اکنون صفحه [datagrid1.aspx] را ارائه میدهیم که وابستگی یک [DataGrid] را به چهار منبع داده مختلف نشان میدهد:

این صفحه شامل چهار مؤلفه [DataGrid] است که با استفاده از [WebMatrix] به شرح زیر ساخته شدهاند. این مؤلفه کشیده شده و در موقعیت مورد نظر در برگه [Design] رها میشود:

سپس یک جدول عمومی HTML رسم میشود. ویژگیهای یک [DataGrid] را میتوان در زمان طراحی تعریف کرد. این کاری است که ما در اینجا برای ویژگیهای قالببندی آن انجام میدهیم. برای این کار، [DataGrid] مورد نظر را برای پیکربندی انتخاب میکنیم. ویژگیهای آن در پنجرهای در پایین سمت راست ظاهر میشوند:

ما از دو پیوند بالا استفاده خواهیم کرد. پیوند [Générateur de propriétés] دسترسی به ویژگیهای اصلی [DataGrid] را فراهم میکند:

ما تیک گزینه [Afficher l'en-tête] را برای چهار کامپوننت [DataGrid] برداشته و صفحه را ذخیره میکنیم. لینک دیگر، [Mise en forme automatique]، به شما امکان میدهد از میان چندین استایل برای جدول HTML که نمایش داده خواهد شد، انتخاب کنید:

ما [couleur i] را برای [DataGrid] شماره i انتخاب میکنیم. این انتخابهای طراحی در کد ارائه صفحه منعکس میشوند:
<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>
در حالت طراحی، ما فقط ویژگیهای قالببندی را تنظیم کردهایم. این در کد کنترل است که ما دادهها را با چهار مؤلفه مرتبط میکنیم:
<%@ Page Language="VB" %>
<%@ import Namespace="system.data" %>
<script runat="server">
'دادههای کلی
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
' روشی که هنگام بارگذاری صفحه اجرا میشود
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
'منابع دادهای که باید به اجزا متصل شوند ایجاد میشوند
createDataSources
'لینک به یک آرایه [Array]
bindToArray
' لینک به یک لیست [ArrayList]
bindToArrayList
' لینک به یک جدول [DataTable]
bindToDataTable
' پیوند به یک گروه داده [DataSet]
bindToDataSet
end if
End Sub
sub createDataSources
'منابع دادهای را ایجاد میکند که به کامپوننتها متصل خواهند شد
' فهرست آرایهای
dim i as integer
for i=0 to textes1.length-1
myDataListe.add(textes1(i))
next
' جدول داده
'دو ستون آن را تعریف میکند
myDataTable.Columns.Add("id",Type.GetType("System.Int32"))
myDataTable.Columns.Add("texte1",Type.GetType("System.String"))
myDataTable.Columns.Add("texte2",Type.GetType("System.String"))
' جدول پر میشود
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
'مجموعه داده – یک جدول واحد
myDataSet.Tables.Add(myDataTable)
end sub
' پیوند آرایه
sub bindToArray
with DataGrid1
.DataSource=textes1
.DataBind
end with
end sub
' پیوند فهرست آرایهای
sub bindToArrayList
with DataGrid2
.DataSource=myDataListe
.DataBind
end with
end sub
' پیوند داداشبکه
sub bindToDataTable
with DataGrid3
.DataSource=myDataTable
.DataBind
end with
end sub
' پیوند مجموعه داده
sub bindToDataSet
with DataGrid4
.DataSource=myDataSet
.DataBind
end with
end sub
</script>
<html>
...
</html>
کد تا حد زیادی شبیه به مثال قبلی است، بنابراین به طور خاص در مورد آن توضیحی نمیدهیم. با این حال، توجه کنید که پیوند دادهها چگونه انجام میشود. برای هر یک از چهار کنترل، توالی زیر کافی است:
که در آن [source de données] از نوع [Array] یا [ArrayList] یا [DataTable] یا [DataSet] است. بنابراین میتوانیم ببینیم که این یک ابزار قدرتمند برای نمایش دادهها در جداول است:
- قالببندی با استفاده از [WebMatrix] یا هر IDE دیگری در مرحله طراحی انجام میشود
- ارتباط داده در کد برقرار میشود. با [WebMatrix]، این کار در زمان طراحی قابل انجام است اگر منبع داده یک پایگاه داده سرور SQL یا یک پایگاه داده ACCESS باشد. در این صورت، باید یک کامپوننت از نوع [SqlDataSource] یا [AccessDataSource] روی شیت قرار داده شود. این کامپوننت میتواند در زمان طراحی به منبع داده فیزیکی، یعنی پایگاه داده سرور SQL یا پایگاه داده ACCESS، بسته به مورد، متصل شود. اگر یک شیء [SqlDataSource] یا [AccessDataSource] که به یک منبع فیزیکی متصل است به ویژگی [DataSource] یک مؤلفه [DataGrid] اختصاص داده شود، آنگاه، در حالت طراحی، دادههای واقعی در کامپوننت [DataGrid] ظاهر خواهند شد.
8.5. ViewState برای اجزای فهرست داده
در اینجا هدف ما برجسته کردن مکانیزم [VIEWSATE] برای اجزای فهرست داده است. دو روش برای حفظ وضعیت یک جزء فهرست داده بین دو درخواست مشتری وجود دارد:
- ویژگی [VIEWSTATE] آن را روی true تنظیم کنید
- ویژگی [VIEWSTATE] آن را روی false تنظیم کرده و منبع دادههای آن را در جلسه (session) ذخیره کنید تا بتوان در درخواست بعدی، این کامپوننت را به آن منبع متصل کرد.
مثال زیر جنبههای خاصی از مکانیزم [VIEWSTATE] برای محفظههای داده را نشان میدهد. در اولین درخواست کلاینت، برنامه نمای زیر را نمایش میدهد:
![]() |
خیر. | name | نوع | ویژگیها | نقش |
۱ | DataGrid | EnableViewState=true | منبع داده S را نمایش میدهد | |
2 | DataGrid | EnableViewState=true | منبع یکسان S را مانند [DataGrid1] نمایش میدهد | |
3 | دکمه | EnableViewState=false | دکمه [submit] |
کامپوننت [DataGrid1] توسط مکانیزم [VIEWSTATE] نگهداری میشود. ما در حال بررسی هستیم که آیا این مکانیزم، که نمایش [DataGrid1] را در هر درخواست مجدداً تولید میکند، منبع دادههای آن را نیز مجدداً تولید میکند یا خیر. برای این منظور، منبع دادهها به کامپوننت [DataGrid2] متصل شده است. این کد برای هر درخواست از طریق یک لینک صریح به منبع داده [DataGrid1] تولید میشود. همچنین ویژگی [EnableViewState] آن به [vrai] متصل است.
کد ارائهٔ برنامه [main.aspx] به شرح زیر است:
<%@ 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] به شرح زیر است:
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
'در پرسوجوی اول، منبع داده تعریف شده و به اولین جدول داده متصل میشود
If Not IsPostBack Then
'منبع داده را تعریف میکند
With DataGrid1
.DataSource = createDataSource()
.DataBind()
End With
End If
' برای هر پرسوجو، DataGrid2 را به منبع DataGrid اول پیوند دهید
With Datagrid2
.DataSource = DataGrid1.DataSource
.DataBind()
End With
End Sub
Private Function createDataSource() As DataTable
'منبع داده اولیه شده است
Dim thèmes As New DataTable
'ستونها
With thèmes.Columns
.Add("id", GetType(System.Int32))
.Add("thème", GetType(System.String))
.Add("description", GetType(System.String))
End With
'ستون «id» کلید اصلی خواهد بود
thèmes.Constraints.Add("cléprimaire", thèmes.Columns("id"), True)
' ردهها
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] یک منبع S از نوع [DataTable] ایجاد میکند. ما روی کد آن تمرکز نمیکنیم، زیرا محور این مثال نیست. آنچه برای ما جالب است، متدی است که برای ساخت دو کامپوننت [DataGrid] استفاده میشود:
- کامپوننت [DataGrid1] یکبار در طول اولین پرسوجو به جدول S متصل میشود. پس از آن دیگر متصل نمیشود.
- کامپوننت [DataGrid2] با هر پرسوجوی جدید به منبع [DataGrid1.DataSource] متصل میشود.
در طول پرسوجوی اول، نمای زیر را به دست میآوریم:

کاملاً منطقی است که هر دو مؤلفه منبع دادهای را که به آن متصل شدهاند نمایش میدهند. ما از دکمه [Envoyer] برای ارسال درخواست [PostBack] به سرور استفاده میکنیم. نمای حاصل سپس به شرح زیر است:

میتوانیم ببینیم که کامپوننت [DataGrid1] مقدار خود را حفظ کرده است، اما کامپوننت [DataGrid2] این کار را نکرده است. توضیح:
- حتی پیش از شروع رویه [Page_Load]، اشیاء [DataGrid1] و [DataGrid2] به دلیل مکانیزم [viewstate]، به مقادیر قبلی خود در پرسوجوی پیشین بازگشتهاند. در واقع، هر دو خاصیت [EnableViewState] خود را روی [vrai] تنظیم کردهاند.
- روال [Page_Load] اجرا میشود. از آنجا که این شامل یک عملیات [PostBack] است، کامپوننت [DataGrid1] توسط [Page_Load] تغییر نمیکند (به کد مراجعه کنید). بنابراین مقدار بازیابیشده توسط [viewstate] را حفظ میکند. این موضوع در تصویر بالا نشان داده شده است.
- از سوی دیگر، کامپوننت [DataGrid2] از طریق [DataBind] به منبع داده [DataGrid1.DataSource] متصل است. بنابراین، آن دوباره ساخته میشود و مقداری که به تازگی از طریق [viewstate] به دست آورده بود، از بین میرود. بنابراین در اینجا ترجیح داده میشد که خاصیت آن از [EnableViewState] به [faux] تنظیم شود تا از مدیریت وضعیت غیرضروری جلوگیری شود. اسکرین بالا نشان میدهد که [DataGrid2] به یک منبع خالی متصل شده است. از آنجایی که این منبع [DataGrid1.DataSource] است، میتوان نتیجه گرفت که اگرچه مکانیزم [viewstate] در واقع نمایش کامپوننت [DataGrid1] را بازیابی میکند، اما ویژگیهای آن، مانند [DataSource] را بازیابی نمیکند.
از این مثال چه نتیجهای میتوان گرفت؟ شما باید از تنظیم خاصیت [EnableViewState] یک مخزن داده روی [vrai] خودداری کنید، اگر قرار است به یک منبع داده برای هر پرسوجو پیوند (DataBind) داده شود. با این حال، موارد خاصی وجود دارد که حتی در این سناریو، ویژگی [EnableViewState] کانتینر باید روی [vrai] باقی بماند؛ در غیر این صورت، رویدادهایی که میخواهیم مدیریت کنیم، فعال نخواهند شد. بعداً با مثالی از این مورد مواجه خواهیم شد.
اغلب منبع دادهٔ یک مخزن داده در طول پرسوجوها تغییر میکند. بنابراین برای هر پرسوجو لازم است مخزن را به منبع داده متصل کرد. معمولاً منبع داده در محدودهٔ جلسه قرار میگیرد تا پرسوجوها بتوانند به آن دسترسی داشته باشند. مثال دوم ما این مکانیزم را نشان میدهد. برنامه تنها یک نما ارائه میدهد:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
۱ | DataGrid | EnableViewState=true | منبع داده S را نمایش میدهد | |
2 | DataGrid | EnableViewState=false | منبع یکسان S را مانند [DataGrid1] نمایش میدهد | |
3 | دکمه | EnableViewState=false | دکمه [submit] | |
4 | برچسب | EnableViewState=false | متنهای اطلاعاتی |
کامپوننت [DataGrid1] تنها در طول اولین پرسوجو به دادهها متصل میشود. این کامپوننت به لطف مکانیزم کامپوننت [viewstate]، مقدار خود را در پرسجوهای بعدی حفظ خواهد کرد. کامپوننت [DataGrid2] به یک منبع داده برای هر درخواست متصل است، که در هر درخواست جدید یک عنصر به آن اضافه میشود. بنابراین لازم است که کامپوننت [DataGrid2] به هر درخواست متصل (DataBind) شود. بنابراین، ما ویژگی [EnableViewState] آن را به [faux]، همانطور که قبلاً توصیه شده بود، تنظیم کردهایم. بدین ترتیب، در پرسش دوم (با استفاده از دکمه [Envoyer])، پاسخ زیر را دریافت میکنیم:

کامپوننت [DataGrid1] مقدار اولیه خود را حفظ کرده است. کامپوننت [DataGrid2] یک عنصر اضافی دارد. سه ورودی [1,2,2] نمایانگر شماره درخواست هستند. میتوانیم ببینیم که یکی از این ورودیها نادرست است. سعی خواهیم کرد بفهمیم چرا.
کد نمایش برنامه [main.aspx] به شرح زیر است:
<%@ 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] به شرح زیر است:
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
' در پرسوجوی اول، منبع داده تعریف شده و به اولین گرید داده متصل میشود
If Not IsPostBack Then
'منبع داده را تعریف میکند
dtThèmes = createDataSource()
With DataGrid1
.DataSource = dtThèmes
.DataBind()
End With
' ذخیره اطلاعات در جلسه
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
' با هر پرسوجو یک تم جدید اضافه میشود
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)
'DataGrid2 را به منبع داده متصل میکند
With Datagrid2
.DataSource = dtThèmes
.DataBind()
End With
' اطلاعات درباره تعداد درخواستها
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
' اطلاعاتی در جلسه ذخیره میشود
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] را بازتولید نکردهایم. این کد مشابه برنامه قبلی است، با این تفاوت که تنها سه خط در کد منبع گنجانده شده است. ابتدا به نحوه مدیریت منبع داده و دو کانتینر نگاهی بیندازیم:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'در اولین درخواست، منبع داده تعریف شده و به اولین DataGrid متصل میشود
If Not IsPostBack Then
'منبع داده را تعریف میکند
dtThèmes = createDataSource()
With DataGrid1
.DataSource = dtThèmes
.DataBind()
End With
' ذخیره اطلاعات در جلسه
Session("source") = dtThèmes
...
End If
'با هر درخواست، یک تم جدید اضافه میشود
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)
'دادهگرید2 را به منبع داده متصل میکند
With Datagrid2
.DataSource = dtThèmes
.DataBind()
End With
...
End Sub
کامپوننت [DataGrid1] تنها در طول اولین پرسوجو به منبع داده S متصل میشود (نه IsPostBack). سپس در جلسه (session) قرار میگیرد. پس از آن دیگر در جلسه قرار نخواهد گرفت. منبع داده S که در جلسه قرار گرفته است، در هر پرسوجو بازیابی میشود و یک سطر جدید به آن اضافه میگردد. کامپوننت [DataGrid2] در هر پرسوجو بهطور صریح به منبع داده S متصل میشود. به همین دلیل است که محتوای آن با هر پرسوجو یک سطر افزایش مییابد. مشاهده میشود که پس از تغییر محتوای منبع داده S، آن بهطور صریح از طریق عملیاتی دوباره در جلسه قرار داده نمیشود:
چرا این اتفاق میافتد؟ وقتی یک درخواست آغاز میشود، جلسه شامل یک شی Session("source") از نوع [DataTable] است که منبع داده را همانطور که در درخواست قبلی بود نگه میدارد. بیایید این شی Session("source") را S بنامیم. وقتی مینویسیم:
dtThèmes = CType(Session("source"), DataTable)
[dtThèmes] و [S] دو مرجع به یک شی واحد، یعنی [DataTable]، هستند. بنابراین، هنگامی که کد مربوط به [Page_Load] یک عنصر را به جدولی که توسط [dtThèmes] ارجاع شده اضافه میکند، همزمان آن را به جدولی که توسط [S] ارجاع شده نیز اضافه میکند. در پایان اجرای صفحه، تمام اشیاء حاضر در جلسه ذخیره خواهند شد، از جمله شیء Session("source")، c.a.d. S، c.a.d و [dtThèmes] ذخیره خواهند شد. بنابراین در واقع محتوای جدید منبع داده است که ذخیره میشود. نیازی نبود نوشت:
برای انجام این ذخیره، از آنجا که Session("source") از قبل برابر [dtThèmes] است. این دیگر صدق نمیکند وقتی دادههای ذخیرهشده در جلسه به شکل اشیاء نیستند، مانند ساختارهای [Integer, Float, ...]. این موضوع توسط مدیریت شمارنده درخواست نشان داده میشود:
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
'در اولین درخواست، منبع داده تعریف شده و به اولین DataGrid متصل میشود
....
' ذخیره اطلاعات در جلسه
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
'با هر پرسوجو، یک تم جدید اضافه میشود
....
' اطلاعات درباره تعداد پرسوجوها
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
' برخی اطلاعات در جلسه ذخیره میشوند
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
شمارندههای درخواست در سه عنصر ذخیره میشوند:
- numRequête1 و numRequête2 از نوع [Integer] – [Integer] یک کلاس نیست بلکه یک ساختار است
- numRequête3 از نوع [entier] – [entier] کلاسی است که برای این منظور تعریف شده است
وقتی مینویسید:
numRequête1 = CType(Session("numRequête1"), Integer)
..
numRequête2 = CType(Session("numRequête2"), Integer)
..
numRequête3 = CType(Session("numRequête3"), entier)
..
- ساختار [Session("numRequête1")] به [numRequête1] کپی میشود. بنابراین، هنگامی که عنصر [numRequête1] تغییر مییابد، عنصر [Session("numRequête1")] تغییر نمییابد.
- همین امر در مورد [Session("numRequête2")] و [numRequête2] نیز صدق میکند.
- عناصر [Session("numRequête3")] و [numRequête3] هر دو ارجاع به یک شیء از نوع [entier] هستند. شیء ارجاعشده را میتوان از طریق هر یک از این ارجاعات تغییر داد.
از این میتوان نتیجه گرفت که نیازی به نوشتن زیر نیست:
برای ذخیره مقدار جدید [numRequête3] در جلسه. در عوض، باید نوشت:
برای ذخیره مقادیر جدید ساختارهای [numRequête1] و [numRequête2]. ما این کار را فقط برای [numRequête2] انجام میدهیم، که توضیح میدهد چرا در اسکرینشاتی که پس از پرسوجوی دوم به دست آمده، شمارنده برای [numRequête1] نادرست است.
بنابراین مهم است بدانیم که وقتی دادهها یکبار در یک جلسه بارگذاری میشوند، اگر توسط یک شیء نمایش داده شوند، نیازی به بارگذاری مجدد مکرر ندارند. در موارد دیگر، اگر تغییر کرده باشند، باید دوباره بارگذاری شوند.
8.6. نمایش لیست دادهها با استفاده از یک DataGrid صفحهبندیشده و مرتبشده
کامپوننت [DataGrid] به شما امکان میدهد محتوای یک [DataSet] را نمایش دهید. تاکنون، ما همیشه فایلهای [DataSet] خود را به صورت دستی ساختهایم. این بار، ما از یک فایل [DataSet] که از یک پایگاه داده بازیابی شده است، استفاده میکنیم. ما در حال ساخت برنامه MVC زیر هستیم:
![]() |
این سه نما در قالب کانtejnerها در کد ارائه کنترلکننده [main.aspx] گنجانده خواهند شد. در نتیجه، این برنامه دارای یک صفحه واحد به نام [main.aspx] است.
8.6.1. کلاسهای کسبوکار
کلاس [produits] دسترسی به پایگاه داده زیر ACCESS را فراهم میکند:

کد کلاس [produits] به شرح زیر است:
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)
' رشته اتصال ذخیره میشود
Me.chaineConnexionOLEDB = chaineConnexionOLEDB
End Sub
Public Function getDataSet(ByVal commande As String) As DataSet
'یک شیء DataAdapter برای خواندن دادهها از منبع OLEDB ایجاد میشود
Dim adaptateur As New OleDbDataAdapter(commande, chaineConnexionOLEDB)
'یک نمایش در حافظه از نتیجه عبارت SELECT ایجاد میکند
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
' نتیجه بازگردانده میشود
Return contenu
End Function
End Class
End Namespace
پایگاه داده ACCESS از طریق درایور OLEDB مدیریت خواهد شد. سازنده کلاس [produits] با رشته اتصال، شناسگر، درایور OLEDB و پایگاه داده قابل مدیریت تأمین میشود. کلاس [produits] دارای متدی به نام [getDataSet] است که یک [DataSet] حاصل از اجراییک پرسوجوی SQL، [select]، که متنش بهعنوان پارامتر ارسال میشود. در طول این متد، چندین عملیات انجام میشود: برقراری اتصال به پایگاه داده، اجرای پرسوجوی [select] و بستن اتصال. تمام این مراحل ممکن است منجر به ایجاد یک استثنا شود که در اینجا مدیریت میشود. یک برنامهٔ آزمایشی ممکن است به این شکل باشد:
Option Explicit On
Option Strict On
' فضاهای نام
Imports System
Imports System.Data
Imports Microsoft.VisualBasic
Namespace st.istia.univangers.fr
' صفحه آزمایشی
Module testproduits
Sub Main(ByVal arguments() As String)
' محتویات جدول محصولات را نمایش میدهد
'جدول در یک پایگاه داده به نام ACCESS قرار دارد که pg نام فایل خود را از آن میگیرد
Const syntaxe1 As String = "pg bdACCESS"
'بررسی پارامترهای برنامه
If arguments.Length <> 1 Then
' پیام خطا
Console.Error.WriteLine(syntaxe1)
'پایان
Environment.Exit(1)
End If
' آمادهسازی رشته اتصال
Dim chaineConnexion As String = "Provider=Microsoft.Jet.OLEDB.4.0; Ole DB Services=-4; Data Source=" + arguments(0)
' ایجاد یک شیء محصولات
Dim objProduits As produits = New produits(chaineConnexion)
' بازیابی جدول محصولات در یک مجموعه داده
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
' نمایش محتویات آن
Dim lignes As DataRowCollection = contenu.Tables(0).Rows
For i As Integer = 0 To lignes.Count - 1
' ردیف i از جدول
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
عناصر مختلف این برنامه به شرح زیر کامپایل میشوند:
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. دیدگاهها
حالا که کلاس دسترسی به دادهها را داریم، کنترلرها و ویوهایی را برای این برنامه وب مینویسیم. ابتدا بیایید ببینیم چگونه کار میکند. اولین ویو به شرح زیر است:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
۱ | TextBox | EnableViewState=true | میدان ورودی پرسوجوی 'SELECT' | |
2 | RequiredFieldValidator | EnableViewState=false | بررسی وجود ۱ | |
3 | TextBox | EnableViewState=true | میدان ورودی – تعداد سطرهای دادهای را که در هر صفحه نتایج نمایش داده میشود مشخص میکند | |
4 | RequiredFieldValidator | EnableViewState=false | وجود ۳ را بررسی میکند | |
۵ | RangeValidator | EnableViewState=false | تأیید میکند که (3) در محدوده [1,30] قرار دارد | |
6 | دکمه | EnableViewState=false | دکمه [submit] |
ما این نما را نمای [formulaire] مینامیم. این نما به کاربر اجازه میدهد تا یک پرسوجوی SELECT SQL را روی پایگاه داده [produits.mdb] اجرا کند. اجرای این پرسوجو یک نمای جدید ایجاد میکند:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
۱ | برچسب | EnableViewState=false | میدان اطلاعاتی | |
2 | RadioButton | EnableViewState=false GroupName=rdTri | امکان انتخاب ترتیب مرتبسازی را برای شما فراهم میکند | |
۳ | DataGrid | EnableViewState=true AllowPaging=true AllowSorting=true | جدول نمایش نتایج انتخاب | |
۴ | LinkButton | EnableViewState=false | دکمه لینک [submit] |
ما این نما را نمای [résultats] مینامیم. این نما شامل [DataGrid] است که نتیجه دستور انتخاب SQL را نمایش میدهد. کاربر ممکن است در پرسوجوی خود اشتباه کند. برخی خطاها به لطف بررسیهای اعتبارسنجی در نمای [erreurs] علامتگذاری خواهند شد.

سایر خطاها در نمای [erreurs] علامتگذاری خواهند شد:

نما [erreurs] نمایش داده میشود:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
۱ | متغیر | برای نمایش خطاها، کد HTML لازم است | ||
۳ | LinkButton | EnableViewState=false | دکمه لینک [submit] |
سه نمای برنامه سه کانتینر (پنل) متفاوت در یک صفحه واحد [main.aspx] هستند. کد ارائه آن به شرح زیر است:
<%@ 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
بیایید نگاهی دقیقتر به پیجینیشن کامپوننت [DataGrid] بیندازیم، ویژگیای که برای اولین بار با آن مواجه میشویم. در کد بالا، این پیجینیشن توسط ویژگیهای زیر کنترل میشود:
<asp:DataGrid id="DataGrid1" runat="server" PageSize="4" AllowPaging="True" ...>
...
<PagerStyle NextPageText="Suivant" PrevPageText="Précédent" ...></PagerStyle>
</asp:DataGrid></P>
فعالسازی پیجینیشن | |
چهار خط داده در هر صفحه | |
متن لینک برای رفتن به صفحه بعدی منبع داده | |
متن لینک برای رفتن به صفحه قبلی منبع داده |
این اطلاعات را میتوان مستقیماً در ویژگیهای تگ <asp:datagrid> وارد کرد. همچنین میتوانید از [WebMatrix] استفاده کنید. در پنجرهٔ ویژگیها برای [DataGrid]، پیوند [Générateur de propriétés] را دنبال کنید:

این کار، جادوگر زیر را باز میکند:

گزینه [Pagination] را انتخاب کنید:

مقادیر ویژگیهای پیجینیشن برای [DataGrid] از کد ارائه در بالا نشان داده شده است.
علاوه بر این، ما مرتبسازی دادهها را بر روی یکی از ستونهای [DataGrid] فعال میکنیم. راههای مختلفی برای انجام این کار وجود دارد. یکی از آنها تنظیم خاصیت [AllowSorting=true] در پنجرهٔ ویژگیهای [DataGrid] است. همچنین میتوانید از تولیدکننده ویژگی استفاده کنید. هر روشی که به کار رود، این امر منجر به وجود ویژگی [AllowSorting=true] در تگ <asp:DataGrid> کامپوننت میشود:
<asp:DataGrid id="DataGrid1" runat="server" ... AllowPaging="True" PageSize="4" AllowSorting="True">
8.6.4. کنترلکنندهها
کنترلکننده [global.asax, global.asax.vb] به شرح زیر است:
[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)
'ایجاد یک شیء محصول
Dim objProduits As produits
Try
objProduits = New produits(ConfigurationSettings.AppSettings("OLEDBStringConnection"))
' شیء به برنامه اضافه میشود
Application("objProduits") = objProduits
' بدون خطا
Application("erreur") = False
Catch ex As Exception
'خطایی رخ داده است؛ این در برنامه ثبت میشود
Application("erreur") = True
Application("message") = ex.Message
End Try
End Sub
End Class
هنگامی که برنامه کاربردی شروع میشود (Application_Start)، ما یک شیء [produits] ایجاد کرده و آن را در برنامه کاربردی قرار میدهیم تا برای تمام درخواستها از سوی همه کلاینتها در دسترس باشد. اگر در حین این ایجاد یک خطا (exception) رخ دهد، در برنامه کاربردی ثبت میشود. روال [Application_Start] تنها یک بار اجرا میشود. پس از آن، کنترلر [global.asax] دیگر دخالتی نخواهد داشت. سپس کنترلر [main.aspx.vb] کنترل را به دست میگیرد:
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
' اجزای صفحه
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
' دادههای صفحه
Protected erreursHTML As String
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'بررسی کنید که آیا برنامه با خطایی مواجه شده است
If CType(Application("erreur"), Boolean) Then
' برنامه به درستی راهاندازی نشده است
Dim erreurs As New ArrayList
erreurs.Add("Application momentanément indisponible (" + CType(Application("message"), String) + ")")
afficheErreurs(erreurs, False)
Exit Sub
End If
'اولین درخواست
If Not IsPostBack Then
'نمایش فرم خالی
afficheFormulaire()
End If
End Sub
Private Sub afficheErreurs(ByVal erreurs As ArrayList, ByVal afficheLien As Boolean)
'نمای خطاها را نمایش میدهد
erreursHTML = ""
For i As Integer = 0 To erreurs.Count - 1
erreursHTML += "<li>" + erreurs(i).ToString + "</li>" + ControlChars.CrLf
Next
lnkErreurs.Visible = afficheLien
'نمایش نمای [erreurs]
vueErreurs.Visible = True
vueFormulaire.Visible = False
vueRésultats.Visible = False
End Sub
Private Sub afficheFormulaire()
'نما نمایش داده میشود [formulaire]
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)
'کنترلها را راهاندازی میکند
lblSelect.Text = sqlTexte
With DataGrid1
.DataSource = données
.PageSize = CType(txtPages.Text, Integer)
.CurrentPageIndex = 0
.DataBind()
End With
'نمای [résultats] نمایش داده میشود
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
'آیا صفحه معتبر است؟
If Not Page.IsValid Then
afficheFormulaire()
Exit Sub
End If
' اجرای پرسوجوی کلاینت SELECT
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
'همه چیز خوب است – نمایش نتایج
afficheRésultats(txtSelect.Text.Trim, données)
'ذخیرهٔ دادهها در جلسه
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
' مجموعهٔ نماها
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
' تغییر صفحه
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
'مرتبسازی نمای داده
Dim données As DataView = CType(Session("données"), DataView)
données.Sort = e.SortExpression + " " + CType(IIf(rdCroissant.Checked, "asc", "desc"), String)
' نمایش آن
With DataGrid1
.CurrentPageIndex = 0
.DataSource = données
.DataBind()
End With
End Sub
End Class
وقتی صفحه [Page_Load] بارگذاری میشود، ابتدا بررسی میکنیم که آیا برنامه به درستی راهاندازی شده است یا خیر. در غیر این صورت، نما [erreurs] را بدون لینک بازگشت به فرم نمایش میدهیم، زیرا این لینک در آن صورت غیرضروری است. در واقع، تنها نمای [erreurs] میتواند در صورتی که برنامه به درستی راهاندازی نشده باشد، نمایش داده شود. در غیر این صورت، اگر این اولین درخواست مشتری باشد، نمای [formulaire] را نمایش میدهیم. مابقی را به خواننده واگذار میکنیم تا کد را درک کند. ما صرفاً بر روی سه رویه تمرکز خواهیم کرد: رویه [btnExécuter_Click]، که زمانی اجرا میشود که کاربر درخواست اجرای پرسوجوی SQL را که در نمای [formulaire] وارد شده است، داده باشد، روال [DataGrid1_PageIndexChanged]، که زمانی اجرا میشود کهکاربر از لینکهای [Suivant] و [Précédent] در [DataGrid] استفاده میکند، و رویه [DataGrid1_SortCommand]، که زمانی اجرا میشود که کاربر برای مرتبسازی دادهها در یک سرستون کلیک میکندفرمان مرتبسازی، صعودی یا نزولی، توسط دو دکمه رادیویی مرتبسازی تعیین میشود.
در رویه [btnExécuter_Click]، بنابراین ابتدا بررسی میکنیم که آیا صفحه معتبر است یا خیر. وقتی رویه [btnExécuter_Click] اجرا میشود، بررسیهای مربوط به کنترلهای اعتبارسنجی مختلف روی صفحه قبلاً انجام شده است. برای هر کنترل اعتبارسنجی، دو ویژگی تعیین شده است:
در صورتی که دادههای بررسیشده معتبر باشند روی true و در غیر این صورت روی false تنظیم میشود | |
پیام خطا در صورتی که دادههای بررسیشده نامعتبر تشخیص داده شوند |
برای خود صفحه، یک ویژگی [IsValid] تنظیم شده است. این مقدار تنها در صورتی روی true تنظیم میشود که تمام بررسیهای اعتبارسنجی ویژگی [IsValid] خود را روی true تنظیم کرده باشند. در غیر این صورت، نمای [formulaire] باید نمایش داده شود. این نما شامل بررسیهای اعتبارسنجی است که ویژگی [errorMessage] خود را نمایش خواهند داد. اگر صفحه معتبر باشد، از شیء از نوع [produits] که توسط [Application_Start] ایجاد شده است، برای به دست آوردن [DataSet] متناظر با اجرای پرسوجوی SELECT SQL استفاده میشود. سپس این به یک شیء [DataView] تبدیل میشود:
Dim données As DataView
Try
données = CType(Application("objProduits"), produits).getDataSet(txtSelect.Text.Trim).Tables(0).DefaultView
...
ما میتوانستیم به سادگی با [DataSet] کار کنیم و بنویسیم:
Dim données As DataSet
Try
données = CType(Application("objProduits"), produits).getDataSet(txtSelect.Text.Trim)
...
یک شیء [DataSet] اساساً مجموعهای از جداول است که توسط روابط به هم متصل شدهاند. در کاربرد خاص ما، [DataSet] مشتقشده از کلاس [produits] تنها شامل یک جدول است، یعنی جدولی که از عبارت [select] حاصل شده است. یک جدول را میتوان مرتبسازی کرد، در حالی که یک [DataSet] را نمیتوان؛ با این حال، ما به مرتبسازی دادههای بهدستآمده علاقهمند هستیم. برای کار با جدول نتیجه از [select]، میتوانستیم بنویسیم:
Dim données As DataTable
Try
données = CType(Application("objProduits"), produits).getDataSet(txtSelect.Text.Trim).Tables(0)
...
شیء [DataTable]، اگرچه یک جدول پایگاه داده را نشان میدهد، روش مرتبسازی ندارد. برای این کار، به یک نما (view) از جدول نیاز دارید. یک نما (view) شیئی از نوع [DataView] است. شما میتوانید با استفاده از فیلترها، نماهای مختلفی از یک جدول واحد داشته باشید. یک جدول دارای یک نمای پیشفرض است که همان نمایی است که در آن هیچ فیلتری تعریف نشده است. بنابراین نمای پیشفرض، کل جدول را نشان میدهد. این نمای پیشفرض از طریق [DataTable.DefaultView] به دست میآید. یک نما را میتوان با استفاده از خاصیت [sort] آن مرتبسازی کرد، که بعداً به آن باز خواهیم گشت.
اگر [DataSet] کلاس [produits] با موفقیت بازیابی شود، نمای [résultats] نمایش داده میشود؛ در غیر این صورت، نمای [erreurs] نمایش داده میشود. نما [résultats] توسط رویه [afficheRésultats] نمایش داده میشود که دو پارامتر به آن ارسال میشود:
- متنی که باید در برچسب [lblSelect] قرار گیرد
- [DataView] که باید به [DataGrid1] پیوند داده شود
این مثال انعطافپذیری فوقالعادهٔ مؤلفهٔ [DataGrid] را نشان میدهد. این مؤلفه قادر است ساختار [DataView] را که به آن متصل است تشخیص دهد و خود را با آن تطبیق دهد. در نهایت، رویه [btnExécuter_Click]، [DataView] را که بهتازگی بهدست آورده است، در جلسه کاربر ذخیره میکند تا زمانی که کاربر صفحات دیگری را از همان [DataView] درخواست کند، در دسترس باشد.
روند [DataGrid1_PageIndexChanged] زمانی اجرا میشود که کاربر روی پیوندهای [Suivant] و [Précédent] در [DataGrid] کلیک میکند. این روند دو پارامتر دریافت میکند:
Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.) Handles DataGrid1.PageIndexChanged
شیئی که رویداد را فعال کرده است – در این مورد، یکی از لینکهای [Suivant] یا [Précédent] | |
اطلاعات مربوط به رویداد. ویژگی e.NewPageIndex شماره صفحهای است که در پاسخ به درخواست مشتری نمایش داده میشود |
کد کامل برای رویدادپرداز به شرح زیر است:
Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles DataGrid1.PageIndexChanged
'تغییر صفحه
With DataGrid1
.CurrentPageIndex = e.NewPageIndex
.DataSource = CType(Session("données"), DataView)
.DataBind()
End With
End Sub
کامپوننت [DataGrid] دارای یک ویژگی [CurrentPageIndex] است که شماره صفحهای را که در حال نمایش است یا نمایش خواهد داد، نشان میدهد. این ویژگی مقدار [NewPageIndex] را از پارامتر [e] دریافت میکند. سپس [DataGrid] با [DataView] مرتبط میشود که توسط رویه [btnExécuter_Click] در جلسه ذخیره شده بود.
ممکن است این سؤال پیش بیاید که آیا [DataGrid] به ویژگی [EnableViewState=true] نیاز دارد، با توجه به اینکه محتوای آن هر بار که صفحه دوباره اجرا میشود توسط کد محاسبه میشود. ممکن است فرض کنیم که نیازی ندارد. با این حال، اگر [DataGrid] دارای ویژگی [EnableViewState=false] باشد، متوجه میشویم که رویداد [DataGrid1.PageIndexChanged] هرگز فعال نمیشود. به همین دلیل است که ما [EnableViewState=true] را حفظ کردهایم. ما میدانیم که این بدان معناست که محتوای [DataGrid] در فیلد پنهان [__VIEWSTATE] در صفحه قرار خواهد گرفت. این امر در صورتی که [DataGrid] بزرگ باشد، میتواند باعث شود صفحه به طور قابل توجهی بیش از حد بارگذاری شود. اگر این یک مشکل باشد، میتوانید بدون استفاده از پیجینیشن خودکار ارائهشده توسط [DataGrid]، خود پیجینیشن را مدیریت کنید.
روال [DataGrid1_SortCommand] زمانی اجرا میشود که کاربر روی سربرگ یکی از ستونهای نمایشدادهشده توسط [DataGrid] کلیک میکند تا درخواست مرتبسازی دادهها بر اساس آن ستون را بدهد. این روال دو پارامتر دریافت میکند:
Private Sub DataGrid1_SortCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridSortCommandEventArgs) Handles DataGrid1.SortCommand
شیءای که رویداد را تحریک کرده است – در این مورد، یکی از لینکهای [Suivant] یا [Précédent] | |
اطلاعات مربوط به رویداد. ویژگی [e.SortExpression] نام ستونی است که برای مرتبسازی کلیک شده است |
کد کامل برای رویدادپرداز به شرح زیر است:
Private Sub DataGrid1_SortCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridSortCommandEventArgs) Handles DataGrid1.SortCommand
'مرتبسازی نمای دادهها
Dim données As DataView = CType(Session("données"), DataView)
données.Sort = e.SortExpression + " " + CType(IIf(rdCroissant.Checked, "asc", "desc"), String)
' نمایش آن
With DataGrid1
.CurrentPageIndex = 0
.DataSource = données
.DataBind()
End With
End Sub
ما [DataView] را که توسط [DataGrid] در جلسهٔ جاری نمایش داده شده است، بازیابی میکنیم. این رویهٔ [btnExécuter_Click] بود که آن را آنجا قرار داد. کامپوننت [DataView] دارای خاصیت [Sort] است که عبارت مرتبسازی به آن اختصاص داده شده است. این از نحو [select ... order by expr1, expr2, ...] پیروی میکند، که در آن هر [expri] میتواند با کلمه کلیدی [asc] برای مرتبسازی صعودی یا [desc] برای مرتبسازی نزولی دنبال شود. بیان [order by] که در اینجا استفاده شده، [order by colonne asc/desc] است. ویژگی [e.SortExpression] نام ستونی را در [DataGrid] که برای مرتبسازی کلیک شده است، در اختیار ما قرار میدهد. مجموعه کاراکتری [asc/desc] بر اساس مقادیر دکمههای رادیویی در گروه [rdTri] تنظیم میشود. هنگامی که عبارت مرتبسازی برای [DataView] تنظیم شد، [DataGrid] با آن مرتبط میشود. [DataGrid] در صفحهٔ اول خود قرار دارد.
8.7. کامپوننت DataList و پیوند داده
اکنون به کامپوننت [DataList] میپردازیم. این کامپوننت گزینههای قالببندی بیشتری نسبت به [DataGrid] ارائه میدهد، اما انعطافپذیری کمتری دارد. در نتیجه، این کامپوننت نمیتواند به طور خودکار خود را با منبع دادهای که به آن متصل است وفق دهد. این تطبیق در صورت لزوم باید از طریق کد انجام شود. اگر ساختار منبع داده از قبل مشخص باشد، این کامپوننت گزینههای قالببندیای را ارائه میدهد که ممکن است آن را به [DataGrid] ترجیح دهد.
8.7.1. برنامه
برای نشان دادن نحوه استفاده از [DataList]، ما در حال ساخت یک برنامه MVC مشابه برنامه قبلی هستیم:
![]() |
سه نما در قالب کانtejنرها در کد ارائه کنترلکننده [main.aspx] گنجانده خواهند شد. در نتیجه، این برنامه دارای یک صفحه واحد است: [main.aspx].
8.7.2. کلاسهای کسبوکار
کلاس [produits] مانند قبل است.
8.7.3. ویوها
هنگامی که کاربر اولین درخواست خود را به برنامه ارسال میکند، نمای زیر، [résultats1]، به او نمایش داده میشود:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
۱ | RadioButton | EnableViewState=false | به شما امکان میدهد یکی از دو سبک را برای [DataList] انتخاب کنید | |
2 | دکمه | EnableViewState=false | دکمه [submit] | |
3 | DataList | EnableViewState=true | حوزه نمایش لیست دادهها |
اگر کاربر سبک شمارهٔ ۲ را انتخاب کند، نمای زیر به او نمایش داده میشود: [résultats2]:
![]() |
خیر | نام | نوع | ویژگیها | نقش |
1 | DataList | EnableViewState=true | حوزه نمایش لیست داده |
نما [erreurs] مشکل دسترسی به منبع داده را گزارش میدهد:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
۱ | متغیر | کد HTML برای نمایش خطاها لازم است |
سه نمای برنامه سه کانتینر (پنل) متفاوت در یک صفحه واحد، [main.aspx]، هستند. کد ارائه آن به شرح زیر است:
<%@ 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("name") %>
<br>
prix :
<%# databinder.eval(Container.DataItem,"price","{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("name") %>
, prix :
<%# databinder.eval(Container.DataItem,"price","{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]
بیایید نگاهی به ویژگیهای مختلف یک مؤلفه [DataList] بیندازیم. تعداد زیادی از آنها وجود دارد و ما در اینجا تنها نمونهای کوچک را ارائه میدهیم. تا هفت قالب نمایش را میتوان در داخل یک [DataList] تعریف کرد:
قالب سربرگ برای [DataList] | |
قالب برای خطوط نمایش آیتمها در فهرست دادههای مرتبط. تنها این قالب الزامی است. | |
برای تمایز بصری بین آیتمهای متوالی نمایش داده شده، میتوان از دو قالب استفاده کرد: ItemTemplate برای آیتم n، و AlternatingItemTemplate برای آیتم n+1 | |
قالب برای عنصر انتخابشده در [DataList] | |
قالب جداکننده بین دو عنصر در [DataList] | |
[DataList] اجازه میدهد مقادیر نمایشدادهشده توسط آن ویرایش شوند. [EditItemTemplate] قالب یک عنصر در [DataList] است که حالت «ویرایش» در آن فعال است. | |
قالب فوتر برای [DataList] |
کامپوننت [DataList1] با استفاده از [WebMatrix] ایجاد شده است. در پنجرهٔ ویژگیهای آن، لینک [Mise en forme automatique] انتخاب شده است:
![]() | 1234567 ![]() |
همانطور که در بالا نشان داده شده است، اسکیمای [Couleur 5] یک [DataList] با استایلهایی برای قالبهای زیر تولید خواهد کرد: HeaderTemplate (1)، ItemTemplate (2، 6)، AlternatingTemplate (3, 5)، SelectedItemTemplate (4)، FooterTemplate (7). کد تولیدشده به شرح زیر است:
<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>
هیچ قالبهایی تعریف نشدهاند. این وظیفه بر عهده ماست. ما قالبهای زیر را تعریف میکنیم:
| |
|
شایان ذکر است که مدل [ItemTemplate] برای نمایش عناصر منبع داده مرتبط با [DataList] استفاده میشود. این منبع داده از مجموعهای از سطرهای داده تشکیل شده است که هر یک شامل یک یا چند مقدار است. ردیف جاری منبع داده توسط شیء [Container.DataItem] نمایش داده میشود. چنین ردیفی دارای ستونها است. [Container.DataItem("col1")] مقدار ستون «col1» در ردیف جاری است. برای درج این مقدار در کد نمایش، بنویسید <%# Container.DataItem("col") %>. گاهی ممکن است بخواهید یک عنصر از ردیف جاری را در قالبی خاص نمایش دهید. در اینجا میخواهیم ستون «price» از سطر جاری را به یورو نمایش دهیم. بنابراین از تابع [DataBinder.Eval] استفاده میکنیم که سه پارامتر میگیرد:
- ردیف فعلی [Container.DataItem]
- نام ستونی که باید قالببندی شود
- رشته قالببندی به شکل {0:format}، که در آن [format] یکی از قالبهای پذیرفتهشده توسط متد [string.format] است.
بنابراین، کد <%# DataBinder.Eval(Container.DataItem,"price",{0:C}) %> ستون [prix] ردیف جاری را به صورت پولی (قالب C=Currency) نمایش خواهد داد.
بنابراین ما یک [DataList] خواهیم داشت که به این شکل به نظر میرسد:

در مثال بالا، دادهها با چهار ورودی در هر خط مرتب شدهاند. این با استفاده از ویژگیهای زیر برای [DataList] انجام میشود:
افقی | |
تعداد ستونهای مورد نیاز |
در نهایت، کد مربوط به [DataList1] همان کدی است که کمی پیشتر در کد نمایش ارائه شد. بررسی کد نمایش برای [DataList2] را به خواننده واگذار میکنیم. مانند کامپوننت [DataGrid]، بیشتر ویژگیهای [DataList] را میتوان با استفاده از یک جادوگر برای [WebMatrix] تنظیم کرد. برای این کار، از پیوند [Générateur de propriétés] در پنجرهٔ ویژگیهای [DataList] استفاده کنید:
![]() | ![]() |
8.7.5. کنترلکنندهها
کنترلکننده [global.asax, global.asax.vb] به شرح زیر است:
[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)
' ما یک شیء محصول ایجاد میکنیم
Try
Dim données As DataSet = New produits(ConfigurationSettings.AppSettings("OLEDBStringConnection")).getDataSet("select * from LISTE")
' شیء به برنامه اضافه میشود
Application("données") = données
' بدون خطا
Application("erreur") = False
Catch ex As Exception
'خطایی رخ داده است؛ این در برنامه ثبت میشود
Application("erreur") = True
Application("message") = ex.Message
End Try
End Sub
End Class
هنگامی که برنامه شروع میشود (Application_Start)، ما یک [dataset] را از کلاس تجاری [produits] ایجاد کرده و آن را در برنامه قرار میدهیم تا برای تمام درخواستها از سوی همه کلاینتها در دسترس باشد. اگر در حین این ایجاد خطایی رخ دهد، در برنامه ثبت میشود. رویه [Application_Start] تنها یک بار اجرا خواهد شد. پس از آن، کنترلکننده [global.asax] دیگر درگیر نخواهد بود. سپس کنترلکننده [main.aspx.vb] کار را انجام خواهد داد:
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
'اجزای صفحه
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
' دادههای صفحه
Protected erreursHTML As String
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'بررسی میکند که آیا برنامه با خطایی مواجه شده است
If CType(Application("erreur"), Boolean) Then
' برنامه به درستی راهاندازی نشده است
Dim erreurs As New ArrayList
erreurs.Add("Application momentanément indisponible (" + CType(Application("message"), String) + ")")
afficheErreurs(erreurs, False)
Exit Sub
End If
'اولین درخواست
If Not IsPostBack Then
' ابتداییسازی کنترلها
With DataList1
.DataSource = CType(Application("données"), DataSet)
.DataBind()
End With
With DataList2
.DataSource = CType(Application("données"), DataSet)
.DataBind()
End With
' نمایش فرم خالی
afficheRésultats(True, False)
End If
End Sub
Private Sub afficheErreurs(ByVal erreurs As ArrayList, ByVal afficheLien As Boolean)
' نمایش صفحهٔ خطاها
erreursHTML = ""
For i As Integer = 0 To erreurs.Count - 1
erreursHTML += "<li>" + erreurs(i).ToString + "</li>" + ControlChars.CrLf
Next
'نمایش نما [erreurs]
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] را نمایش میدهد
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
' سبک را تغییر میدهد
afficheRésultats(RadioButton1.Checked, RadioButton2.Checked)
End Sub
End Class
8.8. کامپوننت تکرارکننده و پیوند داده
کامپوننت [Repeater] به شما امکان میدهد کد HTML را برای هر آیتم در یک لیست داده تکرار کنید. فرض کنید میخواهید لیستی از خطاها را به شکل زیر نمایش دهید:

ما قبلاً با این مشکل مواجه شدهایم و آن را با افزودن یک متغیر در کد نمایش به شکل <% =erreursHTML %> حل کردهایم، که در آن مقدار erreursHTML توسط کنترلر محاسبه میشود. این مقدار حاوی کد HTML است که مربوط به یک لیست میشود. اشکال این روش آن است که اگر بخواهید نمایش این لیست (HTML) را تغییر دهید، مجبورید به بخش کنترلر مراجعه کنید که با اصل تفکیک کنترلر/نمایش مغایرت دارد. کامپوننت [Repeater] راهحلی ارائه میدهد. همانند [DataList]، میتوانیم قالبهای <HeaderTemplate> را برای سربرگ، <ItemTemplate> را برای آیتم فعلی در لیست دادهها و <FooterTemplate> را برای انتهای دادهها تعریف کنیم. در اینجا ممکن است تعریف زیر را برای مؤلفه [Repeater] داشته باشیم:
<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>
توجه داشته باشید که [Container.DataItem] در صورتی که منبع داده چندین ستون داشته باشد، نمایانگر یک سطر از دادهها است. اگر منبع تنها یک ستون داشته باشد، این نمایانگر یک نقطه داده واحد است. در اینجا نیز همین حالت برقرار است. بهعنوان مثال، ما در حال ساخت اپلیکیشن زیر هستیم:

کد نمایش صفحه به شرح زیر است:
<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>
کد بررسی به شرح زیر است:
<%@ Page Language="VB" %>
<script runat="server">
' روندی که هنگام بارگذاری صفحه اجرا میشود
Sub page_Load(sender As Object, e As EventArgs)
if not IsPostBack then
'یک منبع داده ایجاد میشود
with Repeater1
.DataSource=createDataSource
.DataBind
end with
end if
End Sub
function createDataSource as ArrayList
' یک ArrayList ایجاد میکند
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>
در پاسخ به اولین درخواست مشتری، ما یک شیء [ArrayList] را با مؤلفه [Repeater] مرتبط میکنیم که فرض میشود نمایانگر فهرستی از خطاها باشد.
8.9. Application
در اینجا، ما در حال بازنگری یک برنامهای هستیم که قبلاً با استفاده از کامپوننتهای سرور پیادهسازی شده است. این برنامه امکان شبیهسازی محاسبه مالیات را فراهم میکند. این برنامه به کلاسی به نام [impot] متکی است که در اینجا به آن نمیپردازیم. این کلاس به دادههایی نیاز دارد که از یک منبع داده به نام OLEDB بازیابی میکند. برای اهداف این مثال، از یک منبع داده به نام ACCESS استفاده خواهیم کرد. در این نسخه ویژگیهای جدید زیر را معرفی میکنیم:
- استفاده از کامپوننتهای اعتبارسنجی برای بررسی صحت دادهها
- استفاده از کامپوننتهای سمت سرور متصل به منابع داده برای نمایش نتایج
8.9.1. ساختار MVC برنامه
ساختار MVC برنامه به شرح زیر است:
![]() |
سه نما در قالب کانتینرها در کد ارائه کنترلکننده [main.aspx] گنجانده خواهند شد. در نتیجه، این برنامه دارای یک صفحه واحد به نام [main.aspx] است.
8.9.2. نماهای برنامه
ویوی [formulaire] فرم وارد کردن اطلاعاتی است که برای محاسبه مالیات کاربر استفاده میشود:

کاربر فرم را تکمیل میکند:

آنها با استفاده از دکمه [Envoyer] درخواست محاسبه مالیات میکنند. سپس نمای زیر، [simulations]، به آنها نمایش داده میشود:

آنها از طریق لینک بالا به فرم بازمیگردند. آنها آن را در وضعیتی مییابند که در آن وارد شده بود. ممکن است در وارد کردن دادهها خطاهایی رخ دهد:

این موارد در صفحه [formulaire] برجسته شدهاند:

سپس کاربر این خطاها را اصلاح میکند. او میتواند شبیهسازیهای بیشتری را اجرا کند:

سپس نمای [simulations] به آنها ارائه میشود که شامل یک شبیهسازی اضافی است:

در نهایت، اگر منبع داده در دسترس نباشد، کاربر در نمای [erreurs] از این موضوع مطلع میشود:

8.9.2.1. کد ارائه
به یاد داشته باشید که صفحه [main.aspx] تمام نماها را گرد هم میآورد. این یک فرم واحد با سه کانتینر است:
- [panelform] برای نما [formulaire]
- [panelerreurs] برای نما [erreurs]
- [panelsimulations] برای نمای [simulations]
اکنون اجزای این سه کانتینر را با جزئیات بررسی خواهیم کرد. کانتینر [panelform] نمای بصری زیر را دارد:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
پنل | نما فرم | |||
RadioButton | نام گروه=rdmarie | دکمههای رادیویی | ||
CustomValidator | پیام خطا=شما وضعیت تأهل خود را مشخص نکردهاید EnableClientScript=false | بررسی میکند که برنامهٔ کلاینت وضعیت تأهل مورد انتظار را ارسال کرده است | ||
TextBox | تعداد فرزندان | |||
RequiredFieldValidator | پیام خطا=لطفاً تعداد فرزندان را وارد کنید ControlToValidate=txtChildren | بررسی میکند که فیلد [txtEnfants] خالی نباشد | ||
RangeValidator | پیام خطا=یک عدد بین 1 و 30 وارد کنید ControlToValidate=txtChildren | تأیید میکند که مقدار فیلد [txtEnfants] در بازه [1,30] قرار دارد | ||
TextBox | EnableViewState=true | حقوق سالانه | ||
RequiredFieldValidator | ControlToValidate=txtSalary پیام خطا=لطفاً حقوق خود را وارد کنید | بررسی میکند که فیلد [txtSalaire] خالی نباشد | ||
RegularExpressionValidator | ControlToValidate=txtSalary پیام خطا=حقوق نامعتبر RegularExpression=\s*\d+\s* | تأیید میکند که فیلد [txtSalaire] شامل یک دنباله از اعداد است | ||
دکمه | دلایل اعتبارسنجی=true | دکمه [submit] در فرم – محاسبه مالیات را آغاز میکند | ||
دکمه | CausesValidation=false | دکمه [submit] در فرم – فرم را پاک میکند |
ممکن است از بررسی [cvMarié] که مسئول تأیید این است که کاربر واقعاً یکی از دو دکمه رادیویی را علامت زده، شگفتزده شوید. در واقع، اگر از فرم ارسالشده توسط سرور استفاده میکنند، این باید صادق باشد. از آنجایی که هیچ راهی برای اطمینان از این موضوع وجود ندارد، ما مجبوریم تمام پارامترهای ارسالشده را بررسی کنیم. همچنین به ویژگی [CausesValidation=false] دکمه [btnEffacer] توجه کنید. هنگامی که کاربر این دکمه را کلیک میکند، دادههای ارسالشده نباید بررسی شوند، زیرا نادیده گرفته خواهند شد.
تمام اجزای کانتینر دارای ویژگی [EnableViewState=false] هستند به جز [panelForm, txtEnfants, txtSalaire, rdOui, rdNon]. کانتینر [panelerreurs] نمای بصری زیر را دارد:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
پنل | EnableViewState=false | نمايش خطاها | ||
تکرارکننده | EnableViewState=false | فهرستی از خطاها را نمایش میدهد |
کامپوننت [rptErreurs] به صورت زیر تعریف شده است:
<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] یک شیء [ArrayList] خواهد بود که شامل فهرستی از پیامهای خطا است. بنابراین، همانطور که در بالا نشان داده شده است، <%# Container.Dataitem%> به پیام خطای جاری اشاره دارد. کانتینر [panelsimulations] نمایش بصری زیر را دارد:
![]() |
خیر. | نام | نوع | ویژگیها | نقش |
پنل | EnableViewState=false | نمایه شبیهسازیها | ||
LinkButton | EnableViewState=false | پیوند به فرم | ||
DataGrid | EnableViewState=false | مسئول نمایش شبیهسازیهای قرار داده شده در یک شی [DataTable] |
کامپوننت [dgSimulations] زیر [Webmatrix] به صورت زیر پیکربندی شده است. در پنجرهٔ ویژگیها برای [dgSimulations]، لینک [Mise en forme automatique] را انتخاب کرده و اسکیمای [Couleur 3] را انتخاب میکنیم:
![]() | ![]() |
سپس، همچنان در پنجرهٔ ویژگیها برای [dlgSimulations]، پیوند [Générateur de propriétés] را انتخاب میکنیم. درخواست میکنیم که سربرگهای ستون نمایش داده شوند:

ما گزینه [Colonnes] را برای تعریف چهار ستون [DataGrid] انتخاب میکنیم:

ما گزینه [Créer des colonnes automatiquement ...] را لغو انتخاب میکنیم. ما خودمان چهار ستون [DataGrid] را تعریف خواهیم کرد. این به یک شیء [DataTable] با چهار ستون به نامهای «married»، «children»، «salary» و «tax» به ترتیب متصل خواهد شد. برای ایجاد یک ستون در [DataGrid]، گزینه [Colonnes connexe] را انتخاب کرده و از دکمه create همانطور که در بالا نشان داده شده است، استفاده میکنیم. یک ستون ایجاد میشود و میتوانیم ویژگیهای آن را تعریف کنیم. ستون اول جدول شبیهسازی حاوی ستون «married» از شیء [DataTable] خواهد بود که به [DataGrid] متصل میشود. این ستون اول در [DataGrid] در ویزارد به شرح زیر تعریف میشود:

سرستون، در این مورد «متأهل» | |
نام ستون در منبع داده که توسط این ستون در [DataGrid] نمایش داده خواهد شد. در اینجا، این ستون «married» در [DataTable] است. |
ستون دوم به شرح زیر تعریف میشود:
فرزندان | |
فرزندان |
ستون سوم به شرح زیر تعریف میشود:
حقوق سالانه | |
حقوق | |
{0:C} – نمایش ارز برای دریافت نماد یورو |
ستون چهارم به شرح زیر تعریف میشود:
مبلغ مالیات | |
مالیات | |
{0:C} – نمایش ارز برای نمایش نماد یورو |
ما کد نمایش و کد کنترل را در دو فایل جداگانه قرار میدهیم. فایل اول در [main.aspx] و فایل دوم در [main.aspx.vb] قرار دارد. کد مربوط به [main.aspx] به شرح زیر است:
<%@ 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. کد کنترل برنامه
کد کنترل برنامه در فایلهای [global.asax.vb] و [main.aspx.vb] پراکنده شده است. فایل [global.asax] به شرح زیر تعریف شده است:
فایل [global.asax.vb] به شرح زیر است:
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)
' یک شیء Import ایجاد میکند
Dim objImpot As impot
Try
objImpot = New impot(New impotsOLEDB(ConfigurationSettings.AppSettings("chaineConnexion")))
' شیء به برنامه اضافه میشود
Application("objImpot") = objImpot
' بدون خطا
Application("erreur") = False
Catch ex As Exception
'خطایی رخ داده است؛ این در برنامه ثبت میشود
Application("erreur") = True
Application("message") = ex.Message
End Try
End Sub
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' آغاز جلسه – ایجاد یک لیست خالی از شبیهسازیها
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
هنگامی که برنامه اجرا میشود (اولین درخواست به برنامه ارسال میشود)، رویه [Application_Start] اجرا میگردد. این رویه تلاش میکند یک شی از نوع [impot] ایجاد کند و دادههای آن را از منبعی از نوع OLEDB دریافت نماید. به خوانندگان توصیه میشود در صورت فراموشی، به فصل ۵ که این کلاس در آن تعریف شده است مراجعه کنند. ایجاد شیء [impot] ممکن است در صورت در دسترس نبودن منبع داده با شکست مواجه شود. در این حالت، خطا در داخل برنامه ذخیره میشود تا تمام پرسوجوهای بعدی از این موضوع آگاه باشند که شیء نتوانسته است به درستی اولیه شود. اگر ایجاد شیء با موفقیت انجام شود، شیء حاصل [impot] نیز در داخل برنامه ذخیره میشود. این شیء توسط تمام پرسوجوهای محاسبه مالیات استفاده خواهد شد. هنگامی که مشتری اولین استعلام خود را انجام میدهد، یک جلسه توسط رویه [Application_Start] برای او ایجاد میشود. هدف این جلسه، ذخیره شبیهسازیهای مختلف محاسبه مالیات است که او انجام خواهد داد. این شبیهسازیها در یک شی [DataTable] که با کلید جلسه «simulations» مرتبط است، ذخیره خواهند شد. هنگامی که جلسه شروع میشود، این کلید با یک شیء خالی [DataTable] مرتبط میشود که ساختار آن از قبل تعریف شده است. اطلاعات مورد نیاز برنامه در فایل پیکربندی آن، [wenConfig]، ذخیره میشود:
<?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] به رشته اتصال منبع OLEDB اشاره دارد. بخش دیگر کد کنترل در [main.aspx.vb] یافت میشود:
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
' متغیرهای محلی
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
اولین رویدادی که توسط کد پردازش میشود [Page_Load] است:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' ابتدا وضعیت برنامه را بررسی میکنیم
If CType(Application("erreur"), Boolean) Then
' برنامه نتوانست راهاندازی شود
'نمایش نمای خطاها
Dim erreurs As New ArrayList
erreurs.Add("Application momentanément indisponible (" + CType(Application("message"), String) + ")")
afficheErreurs(erreurs)
Exit Sub
End If
' بدون خطا – در اولین درخواست، فرم را نمایش میدهیم
If Not IsPostBack Then afficheFormulaire()
End Sub
قبل از شروع پردازش درخواست، اطمینان حاصل میکنیم که برنامه به درستی راهاندازی شده است. اگر اینطور نباشد، نمای [erreurs] را با استفاده از رویه [afficheErreurs] نمایش میدهیم. اگر این اولین درخواست باشد (IsPostBack=false)، نما [formulaire] را با استفاده از [afficheFormulaire] نمایش میدهیم.
روشی که نمای [erreurs] را نمایش میدهد به شرح زیر است:
Private Sub afficheErreurs(ByRef erreurs As ArrayList)
' فهرست خطاها را بسازید
With rptErreurs
.DataSource = erreurs
.DataBind()
End With
'نمایش کانتینرها
panelerreurs.Visible = True
panelform.Visible = False
panelsimulations.Visible = False
Exit Sub
End Sub
این رویه بهعنوان پارامتر، فهرستی از پیامهای خطا در [erreurs] از نوع [ArrayList] را دریافت میکند. ما بهسادگی این منبع داده را به مؤلفه [rptErreurs] که مسئول نمایش آن است، متصل میکنیم.
روند نمایش نما [formulaire] به شرح زیر است:
Private Sub afficheFormulaire()
' فرم را نمایش میدهد
panelform.Visible = True
' بقیهٔ کانتینرها پنهان میشوند
panelerreurs.Visible = False
panelsimulations.Visible = False
End Sub
این رویه به سادگی کانتینر [panelform] را قابل مشاهده میکند. اجزا با مقدار ارسالشده یا قبلی خود (VIEWSTATE) نمایش داده میشوند.
وقتی کاربر دکمه [Calculer] را در نمای [formulaire] کلیک میکند، یک انتقال از POST به [main.aspx] انجام میشود. روند [Page_Load] اجرا میشود و پس از آن روند [btnCalculer_Click] اجرا میگردد:
Private Sub btnCalculer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculer.Click
'اعتبار دادههای واردشده بررسی میشود؛ در صورت وجود خطا، مشخص میشوند
If Not Page.IsValid Then
afficheFormulaire()
Exit Sub
End If
' بدون خطا – مالیات محاسبه میشود
Dim impot As Long = CType(Application("objImpot"), impot).calculer( _
rdOui.Checked, CType(txtEnfants.Text, Integer), CType(txtSalaire.Text, Long))
'نتیجه به شبیهسازیهای موجود اضافه میشود
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)
'شبیهسازیها به جلسه اضافه میشوند
Session.Item("simulations") = simulations
'صفحه شبیهسازیها را نمایش دهید
afficheSimulations(simulations, "Retour au formulaire")
End Sub
روند با بررسی اعتبار صفحه آغاز میشود. باید توجه داشت که وقتی رویه [btnCalculer_Click] اجرا میشود، بررسیهای اعتبارسنجی قبلاً انجام شده و ویژگی [IsValid] صفحه تنظیم شده است. اگر صفحه معتبر نباشد، نما [formulaire] مجدداً نمایش داده میشود و رویه خاتمه مییابد. کامپوننتهای اعتبارسنجی نما [formulaire]، که ویژگی [IsValid] آنها در بازه [IsValid] تا [false] است، ویژگی [ErrorMessage] خود را نمایش خواهند داد. اگر صفحه معتبر باشد، مبلغ مالیات با استفاده از شیء از نوع [impot] که هنگام راهاندازی برنامه ذخیره شده بود، محاسبه میشود. این شبیهسازی جدید به فهرست شبیهسازیهای انجامشده و ذخیرهشده در جلسه اضافه میشود.
در نهایت، نمای [simulations] توسط رویه زیر [afficheSimulations] نمایش داده میشود:
Private Sub afficheSimulations(ByRef simulations As DataTable, ByRef lien As String)
' ارتباط گرید داده با منبع شبیهسازیها
With dgSimulations
.DataSource = simulations
.DataBind()
End With
' لینک
lnkForm2.Text = lien
'نماها
panelsimulations.Visible = True
panelerreurs.Visible = False
panelform.Visible = False
End Sub
این رویه دو پارامتر دارد:
- فهرستی از شبیهسازیها در [simulations] از نوع [DataTable]
- یک متن پیوند در [lien]
منبع داده [simulations] به مؤلفهای که مسئول نمایش آن است، پیوند داده شده است. متن پیوند در خصوصیت [Text] از شیء [LinkButton] در نما ذخیره میشود.
وقتی کاربر روی دکمه [Effacer] در نمای [formulaire] کلیک میکند، رویه [btnEffacer_click] اجرا میشود (همیشه پس از [Page_Load]):
Private Sub btnEffacer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEffacer.Click
' فرم خالی را نمایش میدهد
razForm()
afficheFormulaire()
End Sub
Private Sub razForm()
' فرم را پاک میکند
rdOui.Checked = False
rdNon.Checked = True
txtEnfants.Text = ""
txtSalaire.Text = ""
End Sub
کد بالا به اندازه کافی ساده است که نیازی به هیچگونه توضیحی ندارد. اکنون باید کلیکهای روی لینکها در ویوهای [erreurs] و [simulations] را مدیریت کنیم:
Private Sub lnkForm1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lnkForm1.Click
' فرم را نمایش میدهد
afficheFormulaire()
End Sub
Private Sub lnkForm2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lnkForm2.Click
' فرم را نمایش میدهد
afficheFormulaire()
End Sub
هر دو رویه صرفاً نما [formulaire] را نمایش میدهند. ما میدانیم که فیلدهای این نما بر اساس مقدار ارسالشده برای آنها یا مقدار قبلیشان تنظیم میشوند. در این مورد، POST کلاینت هیچ مقداری برای فیلدهای فرم ارسال نمیکند، بنابراین این فیلدها به مقادیر قبلی خود بازمیگردند. در نتیجه، فرم با مقادیر واردشده توسط کاربر نمایش داده میشود.
8.9.4. آزمایشها
تمام فایلهای مورد نیاز برنامه در پوشهای به نام <مسیر-برنامه> قرار میگیرند: ![]() | پوشه [bin] حاوی DLL شامل کلاسهای [impot]، [impotsData] و [impotsOLEDB] مورد نیاز برنامه است: |
خوانندگان در صورت تمایل میتوانند به فصل ۵ مراجعه کنند که نحوه ایجاد فایل [impot.dll] مذکور را توضیح میدهد. پس از انجام این کار، سرور Cassini با پارامترهای (<application-path>,/impots6) راهاندازی میشود. URL [http://impots6/main.aspx] با استفاده از یک مرورگر وب درخواست میشود:

اگر نام فایل ACCESS [impots.mdb] را به [impots1.mdb] تغییر دهید، صفحه زیر را مشاهده خواهید کرد:

8.9.5. نتیجهگیری
ما یک برنامه به نام MVC داریم که فقط از کامپوننتهای سمت سرور استفاده میکند. استفاده از این کامپوننتها این امکان را فراهم کرده است که لایهٔ نمایش اپلیکیشن به طور کامل از لایهٔ کنترل آن جدا شود. این امر تا به حال ممکن نبود، زیرا کد نمایش قبلاً شامل متغیرهایی بود که توسط کد کنترل محاسبه میشدند و مقادیرشان حاوی کد HTML بود. دیگر اینطور نیست.






















