Skip to content

5. مدیریت رابط کاربری

5.1. Introduction

در رابطه کلاینت-سرور در وب، کلاینت اطلاعات را به صورت یک رشته پارامتر [param1=val1&param2=val2&...] برای سرور ارسال می‌کند. در مثال‌های قبلی، ما معمولاً این رشته را به صورت دستی با درخواست کردن آدرس‌های URL از نوع [http://localhost/appli? param1=val1&param2=val2&...]. ساخته‌ایم. در عمل، اطلاعاتی که کلاینت به سرور ارسال می‌کند از فرم‌هایی می‌آید که کاربر آن‌ها را پر کرده است. ما در این فصل بررسی می‌کنیم که چگونه این فرم‌ها را بسازیم. همچنین ابزار WebMatrix را معرفی می‌کنیم که به ما امکان طراحی رابط‌های کاربری را می‌دهد. دستورالعمل‌های نصب این ابزار در ضمیمه‌ها ارائه شده است.

5.2. زبان HTML

5.2.1. یک مثال

بیایید مثال زیر را در نظر بگیریم که با استفاده از [Web Matrix] ایجاد شده و نمایش می‌دهد:

  • یک جدول
  • یک تصویر
  • یک لینک

Image

بیایید [WebMatrix] را اجرا کرده و سپس گزینه [File/New File] را انتخاب کنیم:

Image

ما انتخاب می‌کنیم که صفحه‌ای به نام HTML ایجاد کنیم. اطلاعات بالا فایلی به نام [d:\data\devel\aspnet\chap4\exemple1\exemple1.htm] ایجاد خواهد کرد. [WebMatrix] دو روش برای ویرایش این فایل ارائه می‌دهد: حالت [Design] و حالت [HTML]:

Image

حالت [Design] به شما امکان می‌دهد از پالت کامپوننت HTML که توسط [WebMatrix] ارائه شده است، استفاده کنید:

Image

برای درج یک عنصر از این پالت، کافی است روی آن دوبار کلیک کرده و سپس آن را در پنجره [Design] قرار دهید. حالت [HTML] به شما امکان می‌دهد سند HTML را با استفاده از یک ویرایشگر متن بسازید. برای انجام این کار، باید با نحو زبان HTML آشنا باشید. در برگه [HTML]، یک قالب سند ایجاد شده است:

Image

پنجره [HTML] برای هر کسی که با زبان HTML آشنایی ندارد بسیار مفید است. آنها می‌توانند سند خود را در پنجره [Design] ایجاد کنند و کد تولیدشده در پنجره HTML را بررسی کنند. به این ترتیب، آنها به تدریج در HTML مهارت پیدا می‌کنند و می‌توانند به سرعت تنها با استفاده از ویرایشگر متن و بدون کمک حالت [Design] کار کنند. اکنون نشان خواهیم داد چگونه سند HTML ارائه‌شده در ابتدای این بخش را ایجاد کنیم. ما در پنجره [Design] کار می‌کنیم. ابتدا، اولین خط متن را مستقیماً وارد می‌کنیم:

Image

  • ما کامپوننت [Horizontal Rule] را از پالت کامپوننت اضافه می‌کنیم:

Image

  • ما کامپوننت [Table] را اضافه می‌کنیم:

Image

  • ما مکان‌نما را روی سطر سوم جدول قرار می‌دهیم تا آن را با استفاده از گزینه [HTML/Edit Table/Delete Table Row] حذف کنیم. سپس متن مورد نظر را در هر سلول وارد می‌کنیم:

Image

  • ما مکان‌نما را در یکی از سلول‌های جدول قرار می‌دهیم و ویژگی‌های آن را بررسی می‌کنیم. پنجرهٔ ویژگی‌ها در پایین سمت راست فضای کاری نمایش داده می‌شود:

Image

  • این سلول با تگ HTML <TD> نمایش داده می‌شود. بنابراین، ویژگی‌های تگ <TD> به ما نشان داده می‌شود. ما روی جدول تمرکز می‌کنیم که یک شیء حاوی سلول است. روی لیست کشویی (برای مشاهده عناصر والد HTML کلیک کنید) در بالا کلیک می‌کنیم تا عنصر <TABLE> را انتخاب کنیم:

Image

  • شیء <TABLE> دارای یک ویژگی به نام [border] است که عرض حاشیه دور سلول‌های جدول را تعیین می‌کند. در اینجا، ما border=1 را تنظیم می‌کنیم.

Image

  • اکنون در حال ویرایش ویژگی‌های شیء <TD> در سلول (1,2) هستیم تا `align=Center` و `width=200` (پیکسل) را تنظیم کنیم. متن در داخل سلول مرکزدهی می‌شود (align=center) و عرض سلول ۲۰۰ پیکسل خواهد بود. برای مشاهده تغییر، گاهی ممکن است لازم باشد زبانه [HTML] را انتخاب کرده و سپس به زبانه [Design] بازگردید:

Image

  • اکنون متنی را که قبل از تصویر قرار دارد، قرار می‌دهیم:

Image

  • سپس با دوبار کلیک کردن روی کامپوننت [image] در پالت، تصویر را قرار دهید:

Image

  • تصویر را برای ویرایش ویژگی‌های آن انتخاب می‌کنیم:

Image

  • در ویژگی [src]، نام فایلی را که حاوی تصویر است وارد کنید، در این مورد [univ01.gif]:

Image

  • متنی را که قبل از لینک نمایش داده می‌شود وارد می‌کنیم:

Image

  • متن [ici] را به یک لینک به URL [http://istia.univ-angers.fr] تبدیل می‌کنیم. برای این کار، آن را انتخاب کرده و سپس گزینه [HTML/Insert Hyperlink] را انتخاب می‌کنیم:

Image

  • نتیجهٔ زیر را به دست می‌آوریم:

Image

  • ما تقریباً به هدف رسیده‌ایم. بیایید نگاهی به کد HTML که در زبانه [HTML] تولید شده است بیندازیم:
<html>
<head>
</head>
<body>
    <p>
        Le langage HTML - 1 
    </p>
    <hr />
    <table border="1">
        <tbody>
            <tr>
                <td>
                    cellule(1,1)</td>
                <td align="middle" width="200">
                    cellule(1,2)</td>
                <td>
                    cellule(1,3)</td>
            </tr>
            <tr>
                <td>
                    cellule(2,1)</td>
                <td>
                    cellule(2,2)</td>
                <td>
                    cellule(2,3)</td>
            </tr>
        </tbody>
    </table>
    <p>
        Une image <img src="univ01.gif" /> 
    </p>
    <p>
        Le site de l'istia <a href="http://istia.univ-angers.fr">ici</a>
    </p>
</body>
</html>

ما هنوز چند جزئیات باقی مانده داریم که باید مرتب کنیم. اول از همه، می‌خواهیم به سندمان یک عنوان بدهیم. [WebMatrix] اجازه نمی‌دهد این کار در حالت [Design] انجام شود. در برگه [HTML]، توالی <head>..</head> را با توالی زیر جایگزین می‌کنیم:

<head>
    <title>HTML1</title>
</head>

علاوه بر این، ما می‌خواهیم متن [Le langage HTML - 1] با فونت بزرگتری نمایش داده شود. توالی <Hi>text</Hi> به شما امکان می‌دهد اندازه متن را تنظیم کنید، با «i» که از ۱ تا ۶ متغیر است، از بزرگترین تا کوچکترین. در اینجا، ما از H2 استفاده خواهیم کرد. توالی

    <p>
        Le langage HTML - 1 
    </p>

به صورت زیر درمی‌آید:

<h2>Le langage HTML - 1</h2>

پنجره [Design] تغییرات ما را منعکس می‌کند:

Image

تنها کاری که باقی مانده این است که آن را با استفاده از گزینه [View/Start] یا [F5] آزمایش کنید. [WebMatrix] برای راه‌اندازی سرور وب [Cassini] به برخی اطلاعات نیاز دارد:

Image

می‌توانیم مقادیر پیش‌فرض را بپذیریم. سرور [Cassini] راه‌اندازی می‌شود و صفحه ما در یک مرورگر نمایش داده می‌شود:

Image

از روی کنجکاوی، می‌توانیم پارامترهای مورد استفاده برای راه‌اندازی [Cassini] را بررسی کنیم:

Image

ما اصول اولیه ساخت یک صفحه HTML را با استفاده از [WebMatrix] تشریح کردیم. از خوانندگان دعوت می‌شود تا صفحات HTML دیگری بسازند و هر بار کد تولید شده HTML را بررسی کنند. به تدریج قادر خواهید بود صفحه‌ای را بدون کمک حالت [Design] ایجاد کنید. یک سند HTML معمولاً شکل زیر را دارد:

<html>
    <head>
        <title>Un titre</title>
        ...
    </head>
    <body attributs>
        ...
    </body>
</html>

کل سند در برچسب‌های <html>...</html> قرار گرفته است. این سند از دو بخش تشکیل شده است:

<head>...</head>: این بخش غیرقابل نمایش سند است. این بخش اطلاعاتی را در اختیار مرورگری که سند را نمایش می‌دهد قرار می‌دهد. این بخش اغلب شامل تگ <title>...</title> است که متنی را برای نمایش در نوار عنوان مرورگر تعیین می‌کند. همچنین ممکن است شامل تگ‌های دیگری باشد، به‌ویژه آن‌هایی که کلمات کلیدی سند را تعریف می‌کنند و بعداً توسط موتورهای جستجو استفاده می‌شوند. این بخش همچنین ممکن است حاوی اسکریپت‌ها باشد، که معمولاً به زبان جاوااسکریپت یا وی‌بی‌اسکریپت نوشته می‌شوند و توسط مرورگر اجرا خواهند شد.

<body attributes>...</body>: این بخشی است که توسط مرورگر نمایش داده می‌شود. تگ‌های موجود در این بخش، چیدمان بصری «دلخواه» سند را به مرورگر اطلاع می‌دهند. هر مرورگر این تگ‌ها را به شیوه خود تفسیر خواهد کرد. بنابراین ممکن است دو مرورگر یک سند وب را به شکل متفاوتی نمایش دهند. این معمولاً یکی از سردردهای طراحان وب است.

کد HTML برای سند قبلی به شرح زیر بود:

<html>
<head>
    <title>HTML1</title>
</head>
<body>
    <h2>Le langage HTML - 1 
    </h2>
    <hr />
    <table border="1">
        <tbody>
            <tr>
                <td>
                    cellule(1,1)</td>
                <td align="middle" width="200">
                    cellule(1,2)</td>
                <td>
                    cellule(1,3)</td>
            </tr>
            <tr>
                <td>
                    cellule(2,1)</td>
                <td>
                    cellule(2,2)</td>
                <td>
                    cellule(2,3)</td>
            </tr>
        </tbody>
    </table>
    <p>
        Une image <img src="univ01.gif" /> 
    </p>
    <p>
        Le site de l'istia <a href="http://istia.univ-angers.fr">ici</a> 
    </p>
</body>
</html>
عنصر
برچسب‌ها و مثال‌ها HTML
titre du document
<title>HTML1</title>
HTML1 در نوار عنوان مرورگری که سند را نمایش می‌دهد، ظاهر خواهد شد
barre horizontale
<hr>: یک خط افقی نمایش می‌دهد
tableau
<table attributes>....</table>: برای تعریف جدول
<tr attributes>...</tr>: برای تعریف یک سطر
<td attributes>...</TD>: برای تعریف یک سلول
مثال‌ها:
<table border="1">...</table>: ویژگی border ضخامت حاشیه جدول را مشخص می‌کند
<td align="center" width="200">سلول(1,2)</td>: یک سلول را تعریف می‌کند که محتوای آن cellule(1,2) خواهد بود. این محتوا به صورت افقی در مرکز قرار می‌گیرد (align="center"). عرض سلول 200 پیکسل خواهد بود (width="200")
image
<img src="univ01.gif" />: تصویری را تعریف می‌کند که فایل منبعی آن univ01.gif روی سرور وب (src="univ01.gif") است. این لینک در یک سند وب تولیدشده با استفاده از URL http://localhost/exemple1.htm ظاهر می‌شود. بنابراین، مرورگر برای دریافت تصویر مورد اشاره، http://localhost/univ01.gif را از URL درخواست خواهد کرد.
lien
<a href="http://istia.univ-angers.fr">اینجا: باعث می‌شود متن ici به‌عنوان پیوندی به URL http://istia.univ-angers.fr عمل کند.

این مثال ساده نشان می‌دهد که برای نمایش کامل سند، مرورگر باید دو درخواست به سرور ارسال کند:

http://localhost/exemple1.htm برای بازیابی منبع HTML سند

http://localhost/univ01.gif برای بازیابی تصویر univ01.gif

5.2.2. ایجاد یک فرم

یک فرم HTML برای ارائه صفحه‌ای به کاربر جهت وارد کردن اطلاعات طراحی شده است، مشابه فرم‌های ورودی موجود در ویندوز. فرم ورودی به صورت یک سند HTML به مرورگر ارسال می‌شود. مرورگر فرم را به کاربر نمایش می‌دهد، که سپس آن را پر کرده و با استفاده از دکمه‌ای که برای این منظور طراحی شده است، ارسال می‌کند. سپس مرورگر مقادیر وارد شده را برای پردازش به سرور منتقل می‌کند. شایان ذکر است که این کار کل فرم را به سرور بازنمی‌فرستد، بلکه فقط مقادیر وارد شده را ارسال می‌کند. مثال زیر یک فرم وب را نشان می‌دهد که همچنین با استفاده از WebMatrix ایجاد شده است:

Image

کد HTML که توسط [WebMatrix] تولید شده است، به شرح زیر است:


<html>
    <head>
        <title>Formulaire</title>
        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        </script>
    </head>
    <body>
        <p>
            Gestion d'un formulaire
        </p>
        <hr />
        <form name="formulaire" method="post">
            <table border="1">
                <tr>
                    <td>
                        Etes-vous marié(e)</td>
                    <td>
                        <p align="center">
                            <input type="radio" value="oui" name="rdMarie" />Oui 
                            <input type="radio" checked value="non" name="rdMarie" />Non
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Cases à cocher
                    </td>
                    <td>
                        <p align="center">
                            <input type="checkbox" value="un" name="C1" />1
                            <input type="checkbox" checked value="deux" name="C2" />2
                            <input type="checkbox" value="trois" name="C3" />3
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Champ de saisie</td>
                    <td>
                        <p align="center">
                            <input type="text" maxlength="30" value="qqs mots" name="txtSaisie" />
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Mot de passe</td>
                    <td>
                        <p align="center">
                            <input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" />
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Boîte de saisie</td>
                    <td>
                        <p align="center">
                        </p>
                        <textarea name="areaSaisie">ligne1
ligne2</textarea>
                    </td>
                </tr>
                <tr>
                    <td>
                        ComboBox</td>
                    <td>
                        <p align="center">
                        </p>
                        <select name="cmbValeurs">
                            <option value="1">choix1</option>
                            <option value="2" selected>choix2</option>
                            <option value="3">choix3</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td>
                        Liste à choix simple</td>
                    <td>
                        <p align="center">
                        </p>
                        <select size="3" name="lstSimple">
                            <option value="1" selected>liste1</option>
                            <option value="2">liste2</option>
                            <option value="3">liste3</option>
                            <option value="4">liste4</option>
                            <option value="5">liste5</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td>
                        Liste à choix multiple</td>
                    <td>
                        <p align="center">
                        </p>
                        <select multiple size="3" name="lstMultiple">
                            <option value="1" selected>multiple1</option>
                            <option value="2">multiple2</option>
                            <option value="3" selected>multiple3</option>
                            <option value="4">multiple4</option>
                            <option value="5">multiple5</option>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton simple</td>
                    <td>
                        <p align="center">
                            <input onclick="effacer()" type="button" value="Effacer" name="btnEffacer" />
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton submit</td>
                    <td>
                        <p align="center">
                            <input type="submit" value="Envoyer" name="btnEnvoyer" />
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton reset</td>
                    <td>
                        <p align="center">
                            <input type="reset" value="Rétablir" name="btnRetablir" runat="server" />
                        </p>
                    </td>
                </tr>
            </table>
            <input type="hidden" name="secret" value="uneValeur" />
        </form>
    </body>
</html>

بررسی بصری تگ <--> HTML به شرح زیر است:

تأیید
برچسب HTML
formulaire
<form name="form" method="post">
champ de saisie
<input type="text" maxlength="30" value="a few words" name="txtSaisie" />
champ de saisie cachée
<input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" />
champ de saisie multilignes
<textarea name="areaSaisie">line1
line2</textarea>
boutons radio
<input type="radio" value="yes" name="rdMarie" />بله
<input type="radio" checked value="no" name="rdMarie" />خیر
cases à cocher
<input type="checkbox" value="one" name="C1" />1
<input type="checkbox" checked value="two" name="C2" />2
<input type="checkbox" value="three" name="C3" />3
Combo
<select name="cmbValeurs">
<option value="1">گزینهٔ 1</option>
<option value="2" selected>گزینه 2</option>
<option value="3">گزینه ۳</option>
</select>
liste à sélection unique
<select size="3" name="lstSimple">
<option value="1" selected>list1</option>
<option value="2">list2</option>
<option value="3">list3</option>
<option value="4">list4</option>
<option value="5">list5</option>
</select>
liste à sélection multiple
<select multiple size="3" name="lstMultiple">
<option value="1" selected>multiple1</option>
<option value="2">multiple2</option>
<option value="3" selected>multiple3</option>
<option value="4">multiple4</option>
<option value="5">چندگانه۵</option>
</select>
champ caché
<input type="hidden" name="secret" value="uneValeur" />
bouton de type submit
<input type="submit" value="ارسال" name="btnEnvoyer" />
bouton de type reset
<input type="reset" value="Reset" name="btnRetablir" runat="server" />
bouton de type button
<input onclick="clear()" type="button" value="Clear" name="btnEffacer" />

بیایید این کنترل‌های مختلف را بررسی کنیم.

5.2.2.1. فرم

formulaire
<form name="form" method="post">
balise HTML
<form name="..." method="..." action="...">...</form>
attributs
name="exampleform": نام فرم
method="..." : متدی که توسط مرورگر برای ارسال مقادیر جمع‌آوری‌شده در فرم به سرور وب استفاده می‌شود.
action="..." : URL که مقادیر جمع‌آوری‌شده در فرم به آن ارسال می‌شوند.
یک فرم وب در میان تگ‌های <form>...</form> قرار می‌گیرد. این فرم ممکن است یک نام (name="xx") داشته باشد. این موضوع برای تمام کنترل‌های موجود در یک فرم صدق می‌کند. این نام زمانی مفید است که سند وب حاوی اسکریپت‌هایی باشد که نیاز به ارجاع به عناصر فرم داشته باشند. هدف یک فرم جمع‌آوری اطلاعاتی است که کاربر از طریق صفحه‌کلید یا ماوس وارد می‌کند و ارسال آن به URL وب‌سرور. کدام یک؟ همان که در ویژگی action="URL" اشاره شده است. اگر این ویژگی وجود نداشته باشد، اطلاعات به سرور وبی که سند حاوی فرم را میزبانی می‌کند، ارسال خواهد شد. یک کلاینت وب چگونه اطلاعات (داده‌های موجود در فرم) را به یک سرور وب ارسال می‌کند؟ ما این موضوع را به تفصیل بررسی کرده‌ایم. این کلاینت می‌تواند از دو روش مختلف به نام‌های POST و GET استفاده کند. ویژگی method="méthode"، که در آن روش روی GET یا POST تنظیم می‌شود، در تگ <form> به مرورگر می‌گوید که از کدام روش برای ارسال اطلاعات جمع‌آوری‌شده در فرم به URL که توسط ویژگی action="URL" مشخص شده است، استفاده کند. وقتی ویژگی method مشخص نشده باشد، روش GET به‌صورت پیش‌فرض استفاده می‌شود.

5.2.2.2. میدان ورودی

Image

champ de saisie
<input type="text" maxlength="30" value="a few words" name="txtSaisie" />
<input type="password" maxlength="12" size="12" value="unMotDePasse" name="txtMdp" />
balise HTML
<input type="..." name="..." size=".." value="..">
برچسب `input` برای کنترل‌های مختلف استفاده می‌شود. این ویژگی `type` است که این کنترل‌های مختلف را از یکدیگر متمایز می‌کند.
attributs
type="text": مشخص می‌کند که این یک فیلد ورودی متنی است
type="password": کاراکترهای داخل فیلد ورودی با ستاره (*) جایگزین می‌شوند. این تنها تفاوت آن با یک فیلد ورودی معمولی است. این نوع کنترل برای وارد کردن رمزهای عبور مناسب است.
size="12": تعداد کاراکترهای قابل مشاهده در فیلد – مانع از وارد کردن کاراکترهای بیشتر نمی‌شود
maxlength="30": حداکثر تعداد کاراکترها را روی ۳۰ تنظیم می‌کند – مرورگر مسئول اجرای این ویژگی است
name="txtSaisie": نام کنترل
value="چند کلمه": متنی که در فیلد ورودی نمایش داده می‌شود.

5.2.2.3. میدان ورودی چندخطی

Image

champ de saisie multilignes
<textarea name="areaSaisie">line1
line2</textarea>
balise HTML
<textarea ...>text</textarea>
یک فیلد ورودی چندخطی را با متنی که از قبل در آن قرار دارد نمایش می‌دهد
attributs
rows="2": تعداد خطوط
cols="'20" : تعداد ستون‌ها
name="areaSaisie": نام کنترل

5.2.2.4. دکمه‌های رادیویی

Image

boutons radio
<input type="radio" value="yes" name="rdMarie" />بله
<input type="radio" checked value="no" name="rdMarie" />خیر
balise HTML
<input type="radio" attribute2="value2" ..../>متن
یک دکمه رادیویی را همراه با متن در کنار آن نمایش می‌دهد.
attributs
name="rdMarie": نام کنترل. دکمه‌های رادیویی با نام یکسان یک گروه انحصاری متقابل را تشکیل می‌دهند: تنها یکی از آن‌ها می‌تواند انتخاب شود.
value="value": مقداری که به دکمهٔ رادیویی اختصاص داده می‌شود. این مقدار نباید با متنی که در کنار دکمهٔ رادیویی نمایش داده می‌شود اشتباه گرفته شود. مورد دوم صرفاً برای نمایش است.
checked: اگر این کلیدواژه وجود داشته باشد، دکمهٔ رادیویی انتخاب‌شده است؛ در غیر این صورت، انتخاب‌شده نیست.

5.2.2.5. کادرهای تیک

cases à cocher
<input type="checkbox" value="one" name="C1" />1
<input type="checkbox" checked value="two" name="C2" />2
<input type="checkbox" value="three" name="C3" />3

Image

balise HTML
<input type="checkbox" attribute2="value2" ..../>متن
یک چک‌باکس را همراه با متنی در کنار آن نمایش می‌دهد.
attributs
name="C1": نام کنترل. چک‌باکس‌ها ممکن است نام یکسانی داشته باشند یا نداشته باشند. چک‌باکس‌هایی که نام یکسانی دارند، یک گروه از چک‌باکس‌های مرتبط را تشکیل می‌دهند.
value="value": مقداری که به چک‌باکس اختصاص داده می‌شود. این مقدار نباید با متنی که در کنار دکمه رادیویی نمایش داده می‌شود اشتباه گرفته شود. مورد دوم صرفاً برای اهداف نمایشی است.
checked: اگر این کلمه کلیدی وجود داشته باشد، دکمه رادیویی انتخاب شده است؛ در غیر این صورت، انتخاب نشده است.

5.2.2.6. لیست کشویی (کادر ترکیبی)

Combo
<select name="cmbValeurs">
<option value="1">انتخاب۱</option>
<option value="2" selected>option2</option>
<option value="3">گزینه ۳</option>
</select>

Image

balise HTML
<select size=".." name="..">
<option [selected="selected"] [value="valeur"]>text</option>
...
</select>
متن بین تگ‌های <option>...</option> را در یک لیست نمایش می‌دهد
attributs
name="cmbValeurs": نام کنترل.
size="1": تعداد موارد قابل مشاهده لیست. size="1" لیست را معادل یک کادر ترکیبی می‌کند. این مقدار پیش‌فرض است اگر ویژگی [size] وجود نداشته باشد.
selected="selected": اگر این ویژگی برای یک آیتم لیست وجود داشته باشد، آن آیتم در لیست به‌صورت انتخاب‌شده نمایش داده می‌شود. در مثال بالا، آیتم لیست choix2 هنگام اولین نمایش در لیست کشویی به‌عنوان آیتم انتخاب‌شده ظاهر می‌شود.
value="value": مقداری را که در صورت انتخاب آیتم باید به سرور ارسال شود، تعیین می‌کند. اگر این ویژگی وجود نداشته باشد، متنی که با گزینه مرتبط است به سرور ارسال می‌شود.

5.2.2.7. فهرست تک‌انتخابی

liste à sélection unique
<select size="3" name="lstSimple">
<option value="1" selected>list1</option>
<option value="2">list2</option>
<option value="3">list3</option>
<option value="4">list4</option>
<option value="5">list5</option>
</select>

Image

balise HTML
<select size=".." name="..">
<option [selected] [value="valeur"]>...</option>
...
</select>
متن بین تگ‌های <option>...</option> را در یک لیست نمایش می‌دهد
attributs
همانند لیست کشویی که فقط یک مورد را نمایش می‌دهد. این کنترل تنها در ویژگی size>1 با لیست کشویی قبلی متفاوت است.

5.2.2.8. فهرست چندگزینه‌ای

liste à sélection multiple
<select multiple size="3" name="lstMultiple">
<option value="1" selected>multiple1</option>
<option value="2">multiple2</option>
<option value="3" selected>multiple3</option>
<option value="4">multiple4</option>
<option value="5">multiple5</option>
</select>

Image

balise HTML
<select size=".." name=".." multiple>
<option [selected] ] [value="valeur"]>...</option>
...
</select>
متن بین تگ‌های <option>...</option> را در یک لیست نمایش می‌دهد
attributs
multiple: امکان انتخاب چندین آیتم از لیست را فراهم می‌کند. در مثال بالا، آیتم‌های liste1 و liste3 هر دو انتخاب شده‌اند.

5.2.2.9. دکمه

bouton de type button
<input onclick="clear()" type="button" value="Clear" name="btnEffacer" />

Image

balise HTML
<input type="button" value="..." name="..." onclick="clear()" ....>
attributs
type="button": یک کنترل دکمه را تعریف می‌کند. دو نوع دیگر دکمه وجود دارد: submit و reset.
value="Clear": متنی که روی دکمه نمایش داده می‌شود
onclick="function()": به شما امکان می‌دهد تابعی را تعریف کنید که هنگام کلیک کاربر روی دکمه اجرا شود. این تابع بخشی از اسکریپت‌های تعریف‌شده در سند وب نمایش‌داده‌شده است. سینتکس نشان‌داده‌شده در بالا، سینتکس javascript است. اگر اسکریپت‌ها به زبان VBScript نوشته شده باشند، باید onclick="function" را بدون پرانتز بنویسید. اگر نیاز باشد پارامترها به تابع ارسال شوند، نحو به شکل زیر باقی می‌ماند: onclick="function(val1, val2,...)"
در مثال ما، کلیک بر روی دکمه Effacer، تابع جاوااسکریپت زیر effacer را فراخوانی می‌کند:

        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        </script>
توابع effacer یک پیام را نمایش می‌دهد:

5.2.2.10. دکمه ارسال

bouton de type submit
<input type="submit" value="ارسال" name="btnEnvoyer" />

Image

balise HTML
<input type="submit" value="Send" name="btnEnvoyer">
attributs
type="submit": دکمه را به عنوان دکمه‌ای برای ارسال داده‌های فرم به سرور وب تعریف می‌کند. هنگامی که کاربر روی این دکمه کلیک می‌کند، مرورگر داده‌های فرم را با استفاده از متدی که توسط ویژگی method همان تگ تعریف شده است، به URL که در ویژگی action تگ <form> تعریف شده است، ارسال می‌کند.
value="Submit": متنی که روی دکمه نمایش داده می‌شود

5.2.2.11. دکمه ریست

bouton de type reset
<input type="reset" value="Reset" name="btnRetablir" runat="server" />

Image

balise HTML
<input type="reset" value="Reset" name="btnRetablir">
attributs
type="reset": دکمه‌ را به‌عنوان دکمهٔ بازنشانی فرم تعریف می‌کند. وقتی کاربر روی این دکمه کلیک کند، مرورگر فرم را به حالتی که دریافت شده بود بازمی‌گرداند.
value="Reset": متنی که روی دکمه نمایش داده می‌شود.

5.2.2.12. میدان مخفی

champ caché
<input type="hidden" name="secret" value="uneValeur" />
balise HTML
<input type="hidden" name="..." value="...">
attributs
type="hidden": مشخص می‌کند که این یک فیلد پنهان است. فیلد پنهان بخشی از فرم را تشکیل می‌دهد اما به کاربر نمایش داده نمی‌شود. با این حال، اگر کاربر از مرورگر خود بخواهد کد منبع را نمایش دهد، وجود تگ <input type="hidden" value="..."> را مشاهده کرده و در نتیجه مقدار فیلد پنهان را خواهد دید.
value="aValue": مقدار فیلد مخفی.
هدف از یک فیلد مخفی چیست؟ این فیلد به سرور وب اجازه می‌دهد تا اطلاعات را در طول درخواست‌های یک مشتری حفظ کند. یک اپلیکیشن خرید آنلاین را در نظر بگیرید. مشتری در صفحه اول کاتالوگ، یک قلم اولیه به نام art1 را به تعداد q1 خریداری می‌کند، سپس به صفحه جدیدی در کاتالوگ می‌رود. برای اینکه به خاطر بسپارد که مشتری کالاهای q1 و art1 را خریداری کرده است، سرور می‌تواند این دو قطعه اطلاعات را در یک فیلد مخفی در فرم وب صفحه جدید قرار دهد. در این صفحهٔ جدید، مشتری اقلام q2 و art2 را خریداری می‌کند. هنگامی که داده‌های این فرم دوم به سرور ارسال می‌شود، سرور نه تنها اطلاعات را دریافت خواهد کرد (q2, art2) بلکه همچنین (q1, art1)، که این مورد نیز به عنوان یک فیلد پنهان که کاربر نمی‌تواند آن را تغییر دهد، بخشی از فرم است. سپس وب‌سرور اطلاعات (q1,art1) و (q2,art2) را در یک فیلد مخفی جدید قرار داده و یک صفحه کاتالوگ جدید ارسال می‌کند. و به همین ترتیب.

5.3. ارسال مقادیر فرم به سرور وب از طریق مرورگر

ما از فصل قبلی می‌دانیم که یک کلاینت چگونه اطلاعات را به سرور ارسال می‌کند. این کار را به یکی از دو روش زیر انجام می‌دهد:

  • یک درخواست مانند HTTP GET url?param1=va1&param2=val2&....
  • یک درخواست به شکل HTT POST url که به دنبال آن یک سند حاوی رشتهٔ پارامتر param1=va1&param2=val2&.... می‌آید.

مرورگر بسته به اینکه ویژگی [method] تگ [form] برابر GET یا POST باشد، از یکی از این دو روش استفاده خواهد کرد. این چیزی است که اکنون نشان خواهیم داد. صفحه بررسی‌شدهٔ قبلی یک صفحهٔ ایستا است. برای دسترسی به هدرهای HTTP ارسال‌شده توسط مرورگری که این سند را درخواست می‌کند، آن را به یک صفحهٔ پویا برای یک سرور وب .NET (IIS یا Cassini) تبدیل می‌کنیم. کد ایستا قبلی در فایلی به نام [formulaire_get.aspx] قرار می‌گیرد و محتویات آن به شرح زیر است:


<%@ Page src="formulaire_get.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="formulaire_get" %>
<html>
    <head>
        <title>Formulaire</title>
        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        </script>
    </head>
    <body>
.....
    </body>
</html>

صفحهٔ نمای کلی بالا مربوط به کنترل‌کنندهٔ [formulaire_get.aspx.vb] است:


Public Class formulaire_get
    Inherits System.Web.UI.Page

    Private Sub Page_Init(ByVal Sender As Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'درخواست فعلی را در request.txt در پوشه صفحه ذخیره می‌کند
        Dim requestFileName As String = Me.MapPath(Me.TemplateSourceDirectory) + "\request.txt"
        Me.Request.SaveAs(requestFileName, True)
    End Sub
End Class

هر بار که سند [formulaire_get.aspx] فراخوانی می‌شود، درخواست مشتری توسط رویه Page_Init در فایلی به نام [request.txt] ذخیره خواهد شد. ما قبلاً با این شیوهٔ کار آشنا شده‌ایم، بنابراین دیگر در مورد کنترل‌کننده توضیحی نخواهیم داد.

5.3.1. روش GET

بیایید یک تست اولیه انجام دهیم که در آن، در کد سند HTML، تگ FORM به صورت زیر تعریف شده است:


        <form name="formulaire" method="get">

ما فایل‌های [formulaire_get.aspx] و [formulaire_get.aspx.vb] را در پوشه‌ای به نام <application-path> قرار می‌دهیم و سرور Cassini را با پارامترهای (<application-path>,/form2) راه‌اندازی می‌کنیم. ما به URL http://localhost/form2/formulaire_get.aspx دسترسی پیدا می‌کنیم:

Image

مرورگر همین حالا درخواستی ارسال کرده و می‌دانیم که این درخواست در فایل [request.txt] ذخیره شده است. بیایید محتویات آن را بررسی کنیم:

GET /form2/formulaire_get.aspx HTTP/1.1
Cache-Control: max-age=0
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316

مرورگر از درخواست HTTP GET برای درخواست URL [http://localhost/form2/formulaire_get.aspx] استفاده کرد. این همیشه زمانی اتفاق می‌افتد که URL توسط کاربر ارائه شود. ما فرم را به شرح زیر پر می‌کنیم:

Image

ما از دکمه [Envoyer] بالا استفاده می‌کنیم. کد آن، HTML، به شرح زیر است:

<form method="get">
    ...
    <input type="submit" value="Envoyer">
    ...
</form>

هنگامی که دکمه‌ای از نوع [Submit] کلیک می‌شود، مرورگر پارامترهای فرم (برچسب <form>) را به URL مشخص‌شده در ویژگی [action] برچسب <form action="URL">، در صورت وجود، ارسال می‌کند. اگر این ویژگی وجود نداشته باشد، پارامترهای فرم به URL که فرم را ارائه کرده است ارسال می‌شوند. در اینجا نیز همین‌طور است. دکمه [Envoyer] باید در نتیجه، درخواستی را از مرورگر به URL [http://localhost/form2/formulaire_get.aspx] ارسال کند و پارامترهای فرم را به آن بفرستد. از آنجایی که صفحه [formulaire_get.aspx] درخواست دریافت‌شده را ذخیره می‌کند، باید بتوانیم ببینیم که کلاینت این پارامترها را چگونه ارسال کرده است. بیایید امتحانش کنیم. ما روی دکمه [Envoyer] کلیک می‌کنیم. پاسخ زیر را از مرورگر دریافت می‌کنیم:

Image

این صفحهٔ اولیه است، اما می‌توانیم ببینیم که مقدار «URL» در فیلد «[Adresse]» مرورگر تغییر کرده است. اکنون به این صورت درآمده است:

http://localhost/form2/formulaire_get.aspx?rdMarie=yes&C1=one&C2=two&txtSaisie=programming+asp.net&txtMdp=unMotDePasse&areaSaisie=the+basics+of+0D%0Aweb+programming%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Send&secret=uneValeur

می‌توانیم ببینیم که انتخاب‌های انجام‌شده در فرم در URL منعکس شده است. بیایید نگاهی به محتویات فایل [request.txt] بیندازیم که درخواست کلاینت را ذخیره کرده است:

GET /form2/formulaire_get.aspx?rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=ceciestsecre&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/form2/formulaire_get.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316

یک درخواست، HTTP، وجود دارد که تقریباً مشابه درخواستی است که مرورگر در ابتدا هنگام درخواست سند بدون ارسال هیچ پارامتری ارسال کرده بود. دو تفاوت وجود دارد:

GET URL HTTP/1.1
پارامترهای فرم به URL سند در قالب ؟param1=val1&param2=val2&... ضمیمه شده‌اند.
Referer
با این هدر، HTTP، کلاینت URL مستندی را که هنگام ارسال درخواست مشاهده می‌کرد، مشخص می‌کند

بیایید نگاهی دقیق‌تر بیندازیم که پارامترها چگونه در دستور GET URL?param1=value1&param2=value2&... ارسال شده‌اند؟ HTTP/1.1، که در آن parami نام کنترل‌های فرم وب و valeuri مقادیر مرتبط با آن‌ها هستند. در زیر جدولی با سه ستون آمده است:

  • ستون ۱: تعریف یک کنترل HTML را از مثال نشان می‌دهد
  • ستون ۲: نشان می‌دهد که این کنترل چگونه در یک مرورگر نمایش داده می‌شود
  • ستون ۳: مقدار ارسال‌شده توسط مرورگر به سرور برای کنترل در ستون ۱ را، در شکلی که در درخواست GET از مثال دارد، نشان می‌دهد.
کنترل HTML
نمایش پیش‌اعتبارسنجی
مقادیر بازگشتی
<input type="radio" value="yes" name="rdMarie" />بله
<input type="radio" checked
value="no" name="rdMarie" />خیر
rdMarie=yes
- مقدار ویژگی value دکمه
انتخاب‌شده توسط کاربر.
<input type="checkbox"
value="one" name="C1" />1
<input type="checkbox"
checked value="two" name="C2" />2
<input type="checkbox"
value="three" name="C3" />3
C1=one
C2=two
- مقادیر ویژگی‌های value چک‌باکس‌ها
تیک‌خورده توسط کاربر
<input type="text" maxlength="30" value="some
کلمات" name="txtSaisie" />
txtInput=asp.net+programming
- متنی که توسط کاربر در
میدان متن. فاصله‌ها جایگزین شده‌اند
با علامت + جایگزین شده‌اند
<input type="password"
maxlength="12" size="12"
value="aPassword"
name="txtMdp" />
txtMdp=thisIsSecret
- متنی که توسط کاربر در
میدان ورودی متن. متنی که در واقع تایپ شد
"thisissecret". آخرین کاراکتر بود
گم شد زیرا
maxlength="12" تعداد را محدود کرد
نویز در فیلدinput وارد شده توسط کاربر. متن واقعاً تایپ شده"ceciestsecret" بود. آخرین کاراکتراز دست رفت زیرا ویژگیmaxlength="12" تعداد کاراکترها را به 12 محدود کرد.
<textarea name="areaSaisie">
line1
line2</textarea>
input-area=مبانی+
the%0D%0A
برنامه‌نویسی+وب
- متنی که توسط کاربر در
میدان ورودی متن. %OD%OA است
نقطه‌گذاری پایان خط. فاصله‌ها
با علامت + جایگزین شده‌اند
<select name="cmbValeurs">
<option value="1">انتخاب۱
</option></select>
<option value="2" selected>option2
</option></select><select name="cmbValeurs"><option value="1">option1
<option value="3">گزینه ۳
</option>
</select>
cmbValues=3
- مقداری که توسط کاربر از ... انتخاب شده است
فهرست تک‌انتخابی
<select size="3"
name="lstSimple">
<option value="1"
selected>list1</option></select></select></select></select></select></select></select></select></select></select></select></select></select></select>
<option value="2">list2
</option></select> ```
<option value="3">list3
</option>
<option value="4">لیست۴
</option>
<option value="5">list5
</option>
</select>
lstSimple=3
- مقداری که توسط کاربر از ... انتخاب شده است
فهرست تک‌انتخابی
<select multiple size="3"
name="lstMultiple">
<option value="1" selected>multiple1
</option></select></select> - مقداری که توسط کاربر در لیست انتخاب تک انتخابیانتخاب شده است - مقداری که توسط کاربر در لیست انتخاب
<option value="2">multiple2
</option></select>
<option value="3" selected>multiple3
</option>
<option value="4">multiple4
</option>
<option value="5">multiple5
</option>
</select>
lstMultiple=2
lstMultiple=4
- مقادیری که توسط کاربر از ... انتخاب شده‌اند
فهرست انتخاب چندگانه
<input type="submit"
value="ارسال"
name="btnSubmit" />
btnEnvoyer=ارسال
- نام و ویژگی value دکمه مورد استفاده
برای ارسال داده‌های فرم استفاده شد
به سرور
<input type="hidden"
name="secret"
value="aValue" />
 
secret=aValue
- ویژگی value از فیلد مخفی

ممکن است این سؤال پیش بیاید که سرور با پارامترهای ارسال‌شده به آن چه کرد. در واقع، هیچ کاری انجام نداد. پس از دریافت فرمان

GET /form2/formulaire_get.aspx?rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=ceciestsecre&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=1&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur HTTP/1.1

سرور وب پارامترها را برای اسناد URL و c.a.d که ما در ابتدا ایجاد کردیم، به URL ارسال کرده است. ما هیچ کدی برای بازیابی و پردازش پارامترهای ارسال‌شده توسط کلاینت ننوشته‌ایم. بنابراین، گویی درخواست کلاینت صرفاً به این صورت است:

GET http://localhost/form2/formulaire_get.aspx

به همین دلیل، در پاسخ به دکمه [Envoyer] ما، همان صفحه‌ای دریافت شد که در ابتدا با درخواست URL و [http://localhost/form2/formulaire_get.aspx] بدون هیچ پارامتری به دست آمده بود.

5.3.2. روش POST

سند HTML اکنون طوری پیکربندی شده است که مرورگر از روش POST برای ارسال مقادیر فرم به سرور وب استفاده کند. برای این کار، فایل [formulaire_get.aspx] را به [formulaire_post.aspx] کپی کرده و تنها تگ <form> در [formulaire_post.aspx] را تغییر می‌دهیم:


<%@ Page src="formulaire_get.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="formulaire_get" %>
<html>
    <head>
        ...
    </head>
    <body>
        <p>
            Gestion d'un formulaire
        </p>
        <hr />
        <form name="formulaire" method="post">
            <table border="1">

نیازی به تغییر کنترلر [formulaire_get.aspx.vb] نیست، بنابراین آن را همان‌طور که هست باقی می‌گذاریم. ما سند جدید را از طریق URL [http://localhost/form2/formulaire_post.aspx] درخواست می‌کنیم، فرم را مانند روش GET پر می‌کنیم و پارامترها را با استفاده از دکمه [Envoyer] به سرور ارسال می‌کنیم. ما صفحه پاسخ زیر را از سرور دریافت می‌کنیم:

Image

بنابراین همان نتیجه را مانند روش‌های GET و c.a.d دریافت می‌کنیم: صفحهٔ اولیه. یک تفاوت قابل توجه وجود دارد: در فیلد [Adresse] مرورگر، پارامترهای ارسال‌شده نمایش داده نمی‌شوند. اکنون، بیایید به درخواست ارسال‌شده توسط کلاینت که در فایل [request.txt] ذخیره شده است، نگاهی بیندازیم:

POST /form2/formulaire_post.aspx HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Content-Length: 222
Content-Type: application/x-www-form-urlencoded
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/form2/formulaire_post.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7b) Gecko/20040316

rdMarie=oui&C1=un&C2=deux&txtSaisie=programmation+asp.net&txtMdp=ceciestsecre&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web%0D%0A&cmbValeurs=3&lstSimple=3&lstMultiple=2&lstMultiple=4&btnEnvoyer=Envoyer&secret=uneValeur

ورودی‌های جدیدی در پرس‌وجوی مشتری HTTP ظاهر شده‌اند:

POST URL HTTP/1.1
پرس‌وجوی GET با پرس‌وجوی POST جایگزین شده است. پارامترها دیگر در این خط اول پرس‌وجو حضور ندارند. مشاهده می‌شود که اکنون آن‌ها پس از پرس‌وجو HTTP و پس از یک خط خالی قرار گرفته‌اند. رمزگذاری آن‌ها با پرس‌وجو GET یکسان است.
Content-Length
تعداد کاراکترهای «ارسال‌شده»، c.a.d. تعداد کاراکترهایی که وب‌سرور باید پس از دریافت سربرگ‌ها HTTP بخواند تا سند ارسال‌شده توسط کلاینت را بازیابی کند. سند مورد نظر در اینجا فهرست مقادیر فرم است.
Content-type
نوع سندی را مشخص می‌کند که کلاینت پس از سربرگ‌های HTTP ارسال خواهد کرد. نوع [application/x-www-form-urlencoded] نشان می‌دهد که این سند حاوی مقادیر فرم است.

دو روش برای ارسال داده‌ها به یک سرور وب وجود دارد: GET و POST. آیا یکی از این روش‌ها بهتر از دیگری است؟ ما دیده‌ایم که اگر مقادیر یک فرم توسط مرورگر با استفاده از روش GET ارسال شوند، مرورگر مقدار درخواستی URL را در فیلد Adresse در فرم URL?param1=val1&param2=val2&.... نمایش می‌دهد؟ این می‌تواند به‌عنوان یک مزیت یا یک معایب در نظر گرفته شود:

  • یک مزیت اگر می‌خواهید به کاربر اجازه دهید این URL پیکربندی‌شده را به نشانک‌های خود اضافه کند
  • یک معایب اگر نمی‌خواهید کاربر به اطلاعات خاصی در فرم، مانند فیلدهای پنهان، دسترسی داشته باشد، برای مثال

از این پس، ما تقریباً منحصراً در فرم‌هایمان از روش POST استفاده خواهیم کرد.

5.4. پردازش سمت سرور مقادیر فرم

5.4.1. مروری بر مثال

اکنون که ارتباط بین تگ HTML <form method="GET/POST" ...> و نحوه ارسال مقادیر فرم توسط مرورگر را برقرار کرده‌ایم، می‌دانیم چگونه آن‌ها را در سمت سرور بازیابی کنیم. فصل قبلی پاسخ را ارائه داد:

  • اگر متد تگ <form> برابر GET باشد، مقادیر پارامترها از مجموعه [Request.QueryString] بازیابی خواهند شد
  • اگر روش تگ <form> POST باشد، مقادیر پارامترهای «ارسال‌شده» از مجموعه [Request.Form] بازیابی می‌شوند. در اینجا به یک توضیح نیاز است. برچسب <form> می‌تواند از ویژگی [action] برای مشخص کردن URL مقصد GET یا POST استفاده کند. این URL را می‌توان به راحتی، چه برای GET و چه برای POST، در قالب action="url?param1=val1&param2=val2&.." پیکربندی کرد. این پارامترها سپس به پارامترهای موجود بین تگ‌های <form> و </form> اضافه می‌شوند که از طریق یک GET یا یک POST به سرور منتقل خواهند شد. از آنجا که این پارامترها بخشی از URL مقصد را تشکیل می‌دهند، صرف‌نظر از اینکه با یک GET یا یک POST سروکار داشته باشیم، در مجموعه [Request.QueryString] بازیابی خواهند شد.

ما اکنون در حال نوشتن یک برنامه MVC با دو نما هستیم:

  • نمای اول، فرم نشان داده شده در بالا است. ما آن را [vue_formulaire] نام خواهیم برد.
  • دید دوم یک صفحهٔ اطلاعاتی است که مقادیر واردشده در صفحهٔ اول را فهرست می‌کند. یک لینک به کاربر امکان بازگشت به فرم را می‌دهد. این نما را [vue_confirmation] می‌نامیم.

نما [vue_formulaire] برای کاربر ارسال می‌شود، که آن را پر کرده و ارسال می‌کند. ممکن است درست قبل از ارسال به این شکل باشد:

Image

کاربر برای ارسال ورودی‌های خود روی دکمه [Envoyer] کلیک می‌کند. در مقابل، نمای زیر را دریافت می‌کند، [vue_validation]:

Image

5.4.2. کنترل‌کنندهٔ برنامه

همان‌طور که در فصل قبل دیدیم، می‌توانیم نقش کنترلر را برای برنامه MVC به فایل [global.asax] اختصاص دهیم، فایلی که تمام درخواست‌های کلاینت از آن عبور می‌کنند. ما قبلاً یک برنامه MVC را که به این روش ساخته شده است ارائه کرده‌ایم و در اینجا از مدل توسعه ارائه‌شده در آن زمان پیروی می‌کنیم. فایل [global.asax] به شرح زیر خواهد بود:

<%@ Application src="Global.asax.vb" Inherits="Global" %>

این شامل یک خط واحد است که به کنترلری در فایل [global.asax.vb] ارجاع می‌دهد:


Imports System
Imports System.Web
Imports System.Web.SessionState

Public Class Global
    Inherits System.Web.HttpApplication

    Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' عمل انجام‌شدنی را بازیابی کنید
        Dim action As String
        If Request.QueryString("action") Is Nothing Then
            action = "init"
        Else
            action = Request.QueryString("action").ToString.ToLower
        End If
        ' اجرای اقدام
        Select Case action
            Case "init"
                Server.Transfer("formulaire.aspx", False)
            Case "validation"
                Server.Transfer("validation.aspx", True)
            Case Else
                Server.Transfer("formulaire.aspx", True)
        End Select
    End Sub
End Class

کنترل‌کننده به شرح زیر عمل می‌کند:

  • این کنترل‌کننده URL مقصد را برای یک رشته پارامتر حاوی پارامتر [action] بررسی می‌کند. اگر این پارامتر وجود نداشته باشد، سیستم طوری رفتار می‌کند که گویی [action=init] در رشته پارامتر موجود است.
  • تنها دو اقدام شناخته می‌شوند:
    • init: فرم از پیش پرشده به کلاینت ارسال می‌شود
    • validation: صفحه تأیید ورودی‌های کاربر برای مشتری ارسال می‌شود
  • اگر اقدام یکی از موارد فوق نباشد، سیستم آن را طوری پردازش می‌کند که گویی پارامتر [action=init] ارائه شده است. همچنین ممکن است یک صفحه خطا بازگردانده شود.

5.4.3. پردازش اقدام 'init'

وقتی کنترل‌کننده اقدام «init» را پردازش می‌کند، باید یک فرم از پیش پرشده تولید کند. این وظیفه بر عهده صفحه [formulaire.aspx] است. کد آن به شرح زیر است:


<HTML>
    <HEAD>
        <title>Formulaire</title>
        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        function raz(liste){
            liste.selectedIndex=-1
        }
        </script>
    </HEAD>
    <body>
        <p>
            Gestion d'un formulaire
        </p>
        <hr>
        <form name="formulaire" method="post" action="?action=validation">
            <table border="1">
                <tr>
                    <td>
                        Etes-vous marié(e)</td>
                    <td>
                        <p align="center">
                            <input type="radio" value="oui" name="rdMarie">Oui <input type="radio" checked value="non" name="rdMarie">Non
                        </p>
                    </td>
                </tr>
....
                    <td>
                        <select size="3" name="lstSimple">
                            <option value="1" selected>liste1</option>
                            <option value="2">liste2</option>
                            <option value="3">liste3</option>
                            <option value="4">liste4</option>
                            <option value="5">liste5</option>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazSimple" onclick="raz(lstSimple)">
                    </td>
....
                    <td>
                        <select multiple size="3" name="lstMultiple">
                            <option value="1" selected>multiple1</option>
                            <option value="2">multiple2</option>
                            <option value="3" selected>multiple3</option>
                            <option value="4">multiple4</option>
                            <option value="5">multiple5</option>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazMultiple" onclick="raz(lstMultiple)">
                    </td>
...

            </table>
            <input type="hidden" name="secret" value="uneValeur">
        </form>
    </body>
</HTML>

ما کد HTML را از فرم بررسی‌شده قبلاً پیدا می‌کنیم، با چند تفاوت. کد تگ <form> تغییر کرده است:


        <form name="formulaire" method="post" action="?action=validation">
  • post: مقادیری که توسط کاربر وارد شده و سپس هنگام استفاده از دکمه با نوع [submit] به سرور ارسال می‌شوند، از طریق روش HTTP POST ارسال خواهند شد.
  • action: از دستوری با سینتکس action="url" برای مشخص کردن URL مقصد ارسال مقادیر فرم استفاده می‌شود. این URL می‌تواند شامل رشته‌ای از پارامترها به شکل param1=val1&param2=val2&... باشد. این کاری است که در اینجا انجام می‌شود، جایی که ما پارامتر [action=validation] را ارسال می‌کنیم تا به کنترلر بگوییم چه اقدامی انجام دهد. باید توجه داشت که این رشته پارامتر با یک آدرس وب شروع نمی‌شود. بنابراین مرورگر پارامترهای فرم را به آدرسی ارسال می‌کند که این فرم را در اختیار آن قرار داده است. در مثال بالا، این آدرس [http://localhost/mvcform1] است. بنابراین، مرورگر از ماشین [localhost]، درخواستی به آدرس [POST /mvcform1?action=validation] ارسال خواهد کرد.

دکمه‌هایی اضافه شده‌اند تا کاربر بتواند موارد را از لیست‌های [lstSimple] و [lstMultiple] حذف کند:

Image

این منجر به کد زیر در HTML می‌شود:


                    <td>
                        <select size="3" name="lstSimple">
                            <option value="1" selected>liste1</option>
                            <option value="2">liste2</option>
                            <option value="3">liste3</option>
                            <option value="4">liste4</option>
                            <option value="5">liste5</option>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazSimple" onclick="raz(lstSimple)">
                    </td>
....
                    <td>
                        <select multiple size="3" name="lstMultiple">
                            <option value="1" selected>multiple1</option>
                            <option value="2">multiple2</option>
                            <option value="3" selected>multiple3</option>
                            <option value="4">multiple4</option>
                            <option value="5">multiple5</option>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazMultiple" onclick="raz(lstMultiple)">
                    </td>

کلیک روی دکمه [Raz]، همه آیتم‌های فهرستی را که با آن مرتبط است، غیرفعال می‌کند. بیایید لیست [lstMultiple] را به‌عنوان مثال در نظر بگیریم. کلیک روی دکمهٔ متناظر [Raz] باعث اجرای تابع JavaScript [raz(lstMultiple)] می‌شود. شایان ذکر است که کد جاوااسکریپت در یک سند HTML که توسط مرورگر نمایش داده می‌شود، توسط خود مرورگر اجرا می‌شود، نه توسط سرور. جاوااسکریپت یک زبان بسیار جامع است که امکان پویا کردن صفحات را بدون دخالت سرور فراهم می‌کند. تابع [raz] به شرح زیر است:

        function raz(liste){
            liste.selectedIndex=-1
        }

این تابع پارامتری را می‌پذیرد که یک شیء جاوااسکریپت است و نمایانگر یک لیست HTML می‌باشد. این شیء دارای ویژگی‌ها و متدهایی است. یکی از ویژگی‌های آن [selectedIndex] است که مقدار آن شماره اولین گزینه‌ای است که از لیست HTML انتخاب شده است. اگر هیچ گزینه‌ای انتخاب نشده باشد، مقدار این خاصیت روی -1 تنظیم می‌شود. برعکس، تنظیم یک مقدار برای این خاصیت معادل انتخاب یک آیتم جدید از لیست HTML است، در حالی که تنظیم آن روی -1 معادل عدم انتخاب هیچ آیتمی است. این کاری است که در اینجا انجام شده است.

در نهایت، باید توجه داشت که کد ارائه [formulaire.aspx] به یک کنترلر [formulaire.aspx.vb] همراه نیست. این به آن دلیل است که در سند HTML هیچ بخش پویا تولید شده توسط سرور وجود ندارد، بنابراین نیازی به کنترلر نیست.

5.4.4. پردازش اقدام «اعتبارسنجی»

وقتی کنترل‌کننده اقدام «validation» را پردازش می‌کند، باید صفحه‌ای تولید کند که مقادیر واردشده توسط کاربر را فهرست نماید. این وظیفه بر عهده صفحه [validation.aspx] است. از نظر بصری، صفحه به شکل زیر ظاهر می‌شود:

Image

کد HTML آن به شرح زیر است:


<%@ Page src="validation.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="validation" %>
<HTML>
    <HEAD>
        <title>validation</title>
    </HEAD>
    <body>
        <P>Valeurs saisies</P>
        <HR width="100%" SIZE="1">
        <TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
            <TR>
                <TD width="84">rdMarie</TD>
                <TD><% =rdMarie%></TD>
            </TR>
            <TR>
                <TD width="84">C1</TD>
                <TD><%=C1%></TD>
            </TR>
            <TR>
                <TD width="84">C2</TD>
                <TD><%=C2%></TD>
            </TR>
            <TR>
                <TD width="84">C3</TD>
                <TD><%=C3%></TD>
            </TR>
            <TR>
                <TD width="84">txtSaisie</TD>
                <TD><%=txtSaisie%></TD>
            </TR>
            <TR>
                <TD width="84">txtMdp</TD>
                <TD><%=txtMdp%></TD>
            </TR>
            <TR>
                <TD width="84">areaSaisie</TD>
                <TD><%=areaSaisie%></TD>
            </TR>
            <TR>
                <TD width="84">cmbValeurs</TD>
                <TD><%=cmbValeurs%></TD>
            </TR>
            <TR>
                <TD width="84">lstSimple</TD>
                <TD><%=lstSimple%></TD>
            </TR>
            <TR>
                <TD width="84">lstMultiple</TD>
                <TD><%=lstMultiple%></TD>
            </TR>
            <TR>
                <TD width="84">secret</TD>
                <TD><%=secret%></TD>
            </TR>
        </TABLE>
    </body>
</HTML>

بخش‌های پویا <%=variable%> سند توسط کنترلر مرتبط [validation.aspx.vb] محاسبه می‌شوند:


Imports System.Text.RegularExpressions

Public Class validation
    Inherits System.Web.UI.Page

    Protected rdMarie As String
    Protected C1 As String
    Protected C2 As String
    Protected C3 As String
    Protected txtSaisie As String
    Protected txtMdp As String
    Protected areaSaisie As String
    Protected cmbValeurs As String
    Protected lstSimple As String
    Protected lstMultiple As String
    Protected secret As String
    Protected delimiteur As New Regex("\r\n")

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'پارامترهای ارسال‌شده را بازیابی می‌کند
        rdMarie = getValue("rdMarie")
        C1 = getValue("C1")
        C2 = getValue("C2")
        C3 = getValue("C3")
        txtSaisie = getValue("txtSaisie")
        txtMdp = getValue("txtMdp")
        areaSaisie = String.Join(",", delimiteur.Split(getValue("areaSaisie")))
        cmbValeurs = getValue("cmbValeurs")
        lstSimple = getValue("lstSimple")
        lstMultiple = getValue("lstMultiple")
        secret = getValue("secret")
    End Sub

    Private Function getValue(ByVal champ As String) As String
        'مقدار فیلد [champ] را از درخواست ارسال‌شده بازیابی می‌کند
        ' چیزی؟
        If Request.Form(champ) Is Nothing Then Return ""
        'مقدار(ها) فیلد را بازیابی می‌کند
        Dim valeurs() As String = Request.Form.GetValues(champ)
        Dim valeur As String = ""
        Dim i As Integer
        For i = 0 To valeurs.Length - 1
            valeur += "[" + valeurs(i) + "]"
        Next
        Return valeur
    End Function

End Class

مقادیر قابل نمایش در رویه [Form_Load] محاسبه می‌شوند. مقدار یک فیلد «منتشرشده» با استفاده از تابع getValue(C) به دست می‌آید، که در آن C نام فیلد است. نکات کلیدی این تابع به شرح زیر است:

  • اگر C در رشته پارامتر ارسال‌شده (posted) وجود نداشته باشد، یک رشته خالی به‌عنوان مقدار C بازگردانده می‌شود
  • در غیر این صورت، آرایه مقادیر برای فیلد C با استفاده از [Request.Form.GetValues(C)] بازیابی می‌شود. این مقادیر در یک رشته کاراکتری به شکل [val1][val2]... با هم متصل می‌شوند.[valn]، که در آن [vali] مقدار i-ام میدان C است

میدان [areaSaisie] به شیوه‌ای خاص پردازش می‌شود. مقدار آن توسط مرورگر به شکل areaSaisie=line1\r\nline2\r\n... ارسال می‌شود. که در آن \r کاراکتری با کد ASCII 13 (بازگشت carriage) و \n کاراکتری با کد ASCII 10 (تغذیه خط) است. بنابراین، تابع getValue(areaSaisie) رشته «line1\r\nline2\r\n...» را برمی‌گرداند. این رشته با استفاده از روش [Regex.Split] به خطوط تقسیم می‌شود. این کار منجر به ایجاد یک آرایه از رشته‌ها {line1,line2,...} می‌شود. این آرایه توسط متد [String.Join] به رشته "line1,line2,..." تبدیل می‌شود. این رشته نهایی است که به عنوان مقدار فیلد [areaSaisie] نمایش داده خواهد شد. هدف در اینجا نشان دادن نحوه بازیابی خطوط مختلف یک فیلد HTML از نوع [TextArea] بود.

5.4.5. آزمایش‌ها

ما تمام فایل‌ها (global.asax, global.asax.vb, formulaire.aspx, validation.aspx, validation.aspx.vb) را در پوشه‌ای به نام <application-path> قرار می‌دهیم. سرور Cassini را با پارامترهای (<application-path>,/mvcform1) راه‌اندازی می‌کنیم. یک فایل خالی با نام [default.aspx] در پوشه <application-path> ایجاد می‌کنیم، سپس URL [http://localhost/mvcform1] را درخواست می‌کنیم. از آنجایی که [/mvcform1] یک مسیر مجازی به یک پوشه است و نه یک سند، سرور وب در صورت وجود، سند [default.aspx] را نمایش خواهد داد. به همین دلیل است که آن را ایجاد کردیم. پیش از نمایش آن، اسکریپت [global.asax] اجرا شده و در نهایت صفحه [formulaire.aspx] را نمایش می‌دهد. به همین دلیل است که فایل [default.aspx] می‌تواند خالی باشد.

فرض کنید فرم معتبر به صورت زیر است:

Image

کلیک روی دکمه [Envoyer] صفحه زیر را بازمی‌گرداند:

Image

ابتدا، به URL پاسخ توجه کنید: [http://localhost/mvcform1/?action=validation]. این همان URL از ویژگی [action] تگ <form> در فرم [formulaire.aspx] است:


        <form name="formulaire" method="post" action="?action=validation">

بیایید مقادیر به‌دست‌آمده برای فیلدهای مختلف فرم را یکی‌یکی بررسی کنیم:

میدان
ارزش
HTML
نظرات
rdMarie
بله
<input type="radio" value="yes"
name="rdMarie">بله
<input type="radio" checked
value="no" name="rdMarie">خیر
مقدار به‌دست‌آمده، ویژگی [value] دکمهٔ تیک‌خورده است
C1
a
<input type="checkbox"
value="one" name="C1">1
همان
C2
دو
<input type="checkbox"
تیک خورده value="two" name="C2">2
همان
C3
 
<input type="checkbox"
value="three" name="C3">3
این دکمه توسط کاربر تیک‌خورده نشده بود. بنابراین مقدار آن توسط مرورگر ارسال نشد. در کد، شرط [Request.Form("C3") is Nothing] به همین دلیل درست بود.
txtSaisie
برنامه‌نویسی
asp.net
<input type="text"
... name="txtSaisie">
مقدار بازگشتی، متن موجود در فیلد ورودی در زمان اعتبارسنجی است.
txtMdp
رمز عبور
<input type="password"
...name="txtMdp">
همان
areaSaisie
مبانی
برنامه‌نویسی وب
<textarea name="areaSaisie">
...</textarea>
به همین ترتیب
cmbValeurs
۳
<select name="cmbValeurs">
...
<option value="3">گزینه ۳</option>
</select>
مقدار بازگشتی، ویژگی [value] برای گزینهٔ انتخاب‌شده است
lstSimple
۳
<select size="3" name="lstSimple">
....
<option value="3">list3</option>
...
</select>
همان
lstMultiple
۲ ۴
<select multiple size="3" name="lstMultiple">
...
<option value="2">چندگانه2
</option>
...
<option value="4">multiple4
</option>
...
</select>
مقادیر بازگشتی، مقادیر ویژگی‌های [value] برای گزینه‌های انتخاب‌شده هستند.
مخفی
uneValeur
<input type="hidden"
name="secret" value="aValue">
مقدار به‌دست‌آمده، ویژگی [value] فیلد مخفی است

حالا بیایید به لیست‌ها نگاه کنیم. فرض کنید در زمان اعتبارسنجی، وضعیت فرم به شرح زیر است:

Image

  • گزینه [choix1] در comboBox انتخاب شده است
  • و در دو لیست دیگر هیچ گزینه‌ای انتخاب نشده است. ما برای این کار از دکمه‌های [Raz] استفاده کردیم.

در اینجا صفحه‌ای که پس از اعتبارسنجی بازگردانده می‌شود، آورده شده است:

Image

وقتی هیچ مقداری در یک لیست انتخاب نشده باشد، مرورگر پارامتری برای آن لیست ارسال نمی‌کند. بنابراین، در کد مربوط به [validation.aspx.vb]، عبارت‌های [Request.Form("lstSimple")] و [Request.Form("lstMultiple")] با ثابت [Nothing] برابر هستند و در نتیجه، خروجی فوق نمایش داده می‌شود.

5.5. حفظ وضعیت یک صفحه

5.5.1. حفظ وضعیت یک صفحه با استفاده از یک جلسه

ما کل برنامه قبلی را در یک پوشه جدید کپی می‌کنیم. ما یک لینک به صفحه [validation.aspx] اضافه می‌کنیم تا کاربر بتواند به فرم بازگردد:

Image

تغییری که باید در صفحه [validation.aspx] انجام شود، افزودن لینک است:


.....
            <TR>
                <TD width="84">secret</TD>
                <TD><%=secret%></TD>
            </TR>
        </TABLE>
        <P>
            <a href="?action=formulaire">Retour au formulaire</a>
        </P>
    </body>
</HTML>

ویژگی [href] لینک دارای مقداری است که شامل یک URL با یک پارامتر واحد، [action=formulaire]، می‌باشد که به سرور می‌گوید فرم را دقیقاً همان‌طور که هنگام ارسال بود، نمایش دهد. این امر با اکشن [init] که یک فرم از پیش تعریف‌شده را نمایش می‌دهد، متفاوت است. URL پارامتریک [?action=formulaire] در واقع یک URL ندارد. بنابراین، این URL با آنی که برای نمایش صفحه ارسال استفاده می‌شود، یکسان خواهد بود. اگر بخش قبلی را به یاد بیاوریم، این URL پوشهٔ برنامه است. بنابراین درخواست از طریق کنترلر عبور خواهد کرد. کنترلر اکنون باید اقدام [formulaire] را پردازش کند. کد [global.asax.vb] به شرح زیر تغییر یافته است:


    Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' عمل را بازیابی کنید تا انجام شود
        Dim action As String
        If Request.QueryString("action") Is Nothing Then
            action = "init"
        Else
            action = Request.QueryString("action").ToString.ToLower
        End If
        ' اقدام انجام می‌شود
        Select Case action
            Case "init"
                Server.Transfer("formulaire.aspx", False)
            Case "validation"
                Server.Transfer("validation.aspx", True)
            Case "formulaire"
                Server.Transfer("formulaire.aspx", True)
            Case Else
                Server.Transfer("formulaire.aspx", True)
        End Select
    End Sub

اگر اکشن «form» باشد، ما به سادگی درخواست را به صفحه [formulaire.aspx] ارسال می‌کنیم. می‌دانیم که این صفحه یک فرم از پیش تعریف‌شده را نمایش می‌دهد که هیچ فیلد متغیری ندارد. بنابراین این صفحه نمی‌تواند فرم را با مقادیری که هنگام ارسال داشت، نمایش دهد. هدف در اینجا تأکید بر این نکته است. اگر تمام فایل‌های برنامه در <application-path> قرار داده شده باشند، Cassini را با پارامترها (<application-path>,/mvcform2) راه‌اندازی کرده و سپس URL [http://localhost/mvcform2] را درخواست می‌کنیم. صفحه زیر (نمای جزئی) را دریافت می‌کنیم:

Image

ما فرم را به شرح زیر پر کرده و سپس آن را ارسال می‌کنیم:

Image

صفحه تأیید زیر به ما نمایش داده می‌شود:

Image

ما از لینک [Retour au formulaire] که در صفحه بالا موجود است (اما نمایش داده نمی‌شود) استفاده می‌کنیم. ما پاسخ زیر را از سرور دریافت می‌کنیم:

Image

ما متوجه می‌شویم که:

  • URL درخواستی در واقع حاوی پارامتر `action=form` است، همان‌طور که پیش‌بینی شده بود
  • فرم نمایش‌داده‌شده مقادیر واردشده را از دست داده است.

ما می‌دانیم چرا نمی‌توانیم مقادیر وارد شده را بازیابی کنیم. اگر به کد سند [formulaire.aspx] نگاه کنیم، می‌بینیم که همه چیز ایستا است و بنابراین مجبور است هر بار همان صفحه را نمایش دهد. واضح است که باید این کد را پویا کنیم. این کد باید مقادیر تأییدشده توسط کاربر را نمایش دهد. اما این مقادیر باید کجا ذخیره شوند؟

بیایید قانون آهنین پروتکل بدون حالت HTTP را به یاد بیاوریم:

  • URL [http://localhost/mvcform2] درخواست می‌شود – یک پاسخ دریافت می‌شود. یک اتصال TCP-IP در ابتدای درخواست بین کلاینت و سرور برقرار و در پایان پاسخ قطع شد.
  • کاربر داده‌ها را وارد و سپس ارسال می‌کند. URL [http://localhost/mvcform2/?action=validation] درخواست می‌شود – یک پاسخ دریافت می‌شود. یک اتصال جدید، TCP-IP، بین دو طرف باز و سپس بسته شد.
  • کاربر روی لینک [Retour au formulaire] کلیک می‌کند. URL [http://localhost/mvcform2/?action=formulaire] درخواست می‌شود – یک پاسخ دریافت می‌شود. یک اتصال جدید، TCP-IP، بین دو طرف باز و سپس بسته می‌شود.

چرخه‌های درخواست-پاسخ از یکدیگر مستقل هستند زیرا هر یک از آن‌ها از یک اتصال جدید، TCP-IP، استفاده می‌کنند. هنگامی که یک برنامه کاربردی کلاینت-سرور از یک اتصال واحد TCP-IP برای یک سری تبادل اطلاعات استفاده می‌کند، سرور می‌تواند کلاینت را از طریق اتصال آن شناسایی کند. بنابراین می‌تواند اطلاعاتی را ذخیره کند که به یک اتصال خاص مرتبط است و بدین ترتیب تبادل اطلاعات را پیگیری نماید. هنگامی که تبادل اطلاعات از طریق اتصالات مختلف انجام می‌شود، سرور نمی‌تواند کلاینت را از طریق اتصال شناسایی کند. روش دیگری لازم است. ما در فصل قبلی یکی از این روش‌ها را معرفی کردیم: مکانیزم جلسه. این مکانیزم به چرخه‌های درخواست-پاسخ اجازه می‌دهد تا اطلاعاتی را در یک شیء [Session] ذخیره کنند که برای تمام چرخه‌های بعدی قابل دسترسی است.

اکنون که یک برنامه MVC با یک جلسه (session) داریم، دیگر نمی‌توانیم از فایل [global.asax] به عنوان یک کنترل‌کننده (controller) استفاده کنیم، همانطور که در فصل قبلی نشان داده شد. نقش کنترل‌کنندهٔ برنامه باید توسط یک صفحهٔ خاص که به این منظور اختصاص داده شده است، ایفا شود. در این مورد، این صفحه [main.aspx] خواهد بود. ما به شرح زیر عمل خواهیم کرد:

  • هنگامی که کاربر داده‌های خود را ارسال می‌کند (action=validation)، کنترل‌کننده [main.aspx.vb] آن را در جلسه جاری ذخیره می‌کند و سپس صفحه اعتبارسنجی را نمایش می‌دهد.
  • هنگامی که فرم نیاز به نمایش با مقادیر وارد شده دارد (action=form)، کنترلر [main.aspx.vb] آن‌ها را از جلسه بازیابی کرده و قبل از نمایش فرم، آن‌ها را در زمینه قرار می‌دهد.

5.5.2. کنترل‌کنندهٔ جدید برنامه

کنترل‌کنندهٔ برنامه از دو فایل [main.aspx, main.aspx.vb] تشکیل شده است:

[main.aspx]

<%@ Page src="main.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="main" %>

[main.aspx.vb]


Imports System.Collections.Specialized
Imports Microsoft.VisualBasic

Public Class main
    Inherits System.Web.UI.Page

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'بازیابی اقدام قابل اجرا
        Dim action As String
        If Request.QueryString("action") Is Nothing Then
            action = "init"
        Else
            action = Request.QueryString("action").ToString.ToLower
        End If
        ' اجرای اقدام
        Select Case action
            Case "init"
                'نمایش فرم از پیش پرشده
                Context.Items("formulaire") = initForm()
                Server.Transfer("formulaire.aspx", True)
            Case "validation"
                ' نمایش صفحه تأیید پس از ذخیره مقادیر ارسال‌شده در جلسه
                Session.Item("formulaire") = Request.Form
                Server.Transfer("validation.aspx", True)
            Case "formulaire"
                'نمایش فرم با مقادیر بازیابی‌شده از جلسه
                Context.Items("formulaire") = Session.Item("formulaire")
                Server.Transfer("formulaire.aspx", True)
            Case Else
                'فرم از پیش پرشده را نمایش می‌دهد
                Context.Items("formulaire") = initForm()
                Server.Transfer("formulaire.aspx", True)
        End Select
    End Sub

    Private Function initForm() As NameValueCollection
        'فرم اولیه می‌شود
        Dim form As New NameValueCollection
        form.Set("rdMarie", "non")
        form.Set("C2", "deux")
        form.Set("txtSaisie", "qqs mots")
        form.Set("txtMdp", "ceciestsecret")
        form.Set("areasaisie", "ligne1" + ControlChars.CrLf + "ligne2" + ControlChars.CrLf)
        form.Set("cmbValeurs", "2")
        form.Set("lstSimple", "1")
        form.Set("lstMultiple", "1")
        form.Add("lstMultiple", "3")
        Return form
    End Function
End Class

این بازتاب‌دهندهٔ ماهیت ساختار کنترل‌کنندهٔ برنامه است که قبلاً مورد بحث قرار گرفت، با تفاوت‌های زیر:

  • پردازش کنترل‌کننده در رویه [Form_Load] انجام می‌شود
  • در مورد اکشن [validation]، مقادیر فرم موجود در [Request.Form] در سشن مرتبط با کلید "form" ذخیره می‌شوند. سپس اجرای کد به صفحه [validation.aspx] منتقل می‌شود که این مقادیر را نمایش خواهد داد.
  • برای سایر عملیات، اجرای برنامه همیشه به صفحه [formulaire.aspx] منتقل می‌شود. این صفحه در زمینه خود منتظر یک کلید «form» است که با یک شی از نوع [Request.formc.a.d یا [NameValueCollection] مرتبط خواهد بود. این شی باید حاوی مجموعه مقادیر برای فیلدهای فرم باشد.
  • اگر عمل [init] یا یک عمل ناشناخته باشد، مجموعه مقادیر به صورت دلخواه توسط تابع [initForm] ساخته می‌شود.
  • اگر عمل [formulaire] باشد، این مجموعه همان مجموعه [Request.Form] است که توسط عمل [validation] در جلسه قرار داده شده است

5.5.3. فرم جدید

از آنجا که برنامه دیگر همان محتوا را در فرم نمایش نمی‌دهد، باید به‌صورت پویا تولید شود. صفحه جدید [formulaire.aspx] به شرح زیر است:


<%@ Page src="formulaire.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="formulaire" %>
<HTML>
    <HEAD>
        <title>Formulaire</title>
        <script language="javascript">
        function effacer(){
            alert("Vous avez cliqué sur le bouton [Effacer]");
        }
        function raz(liste){
            liste.selectedIndex=-1
        }
        </script>
    </HEAD>
    <body>
        <p>
            Gestion d'un formulaire
        </p>
        <hr>
        <form name="formulaire" method="post" action="main.aspx?action=validation">
            <table border="1">
                <tr>
                    <td>
                        Etes-vous marié(e)</td>
                    <td>
                        <p align="center">
                            <INPUT type="radio" value="oui" name="rdMarie" <%=rdouichecked%>>Oui
                         <INPUT type="radio" value="non" name="rdMarie" <%=rdnonchecked%>>Non
                        </p>
                    </td>
                </tr>
                <TR>
                    <TD>Cases à cocher
                    </TD>
                    <TD>
                        <P align="center">
                            <INPUT type="checkbox" value="un" name="C1" <%=c1checked%>>1
                             <INPUT type="checkbox" value="deux" name="C2" <%=c2checked%>>2
                            <INPUT type="checkbox" value="trois" name="C3" <%=c3checked%>>3
                        </P>
                    </TD>
                </TR>
                <TR>
                    <TD>Champ de saisie</TD>
                    <TD>
                        <P align="center">
                            <INPUT type="text" maxLength="30" value="<%=txtSaisie%>" name="txtSaisie">
                        </P>
                    </TD>
                </TR>
                <tr>
                    <td>
                        Mot de passe</td>
                    <td>
                        <p align="center">
                            <input type="password" maxlength="12" size="12" value="<%=txtMdp%>" name="txtMdp">
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Boîte de saisie</td>
                    <td>
                        <textarea name="areaSaisie"><%=areaSaisie%></textarea>
                    </td>
                </tr>
                <tr>
                    <td>
                        ComboBox</td>
                    <td>
                        <select name="cmbValeurs">
                            <%=cmbValeursOptions%>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td>
                        Liste à choix simple</td>
                    <td>
                        <select size="3" name="lstSimple">
                            <%=lstSimpleOptions%>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazSimple" onclick="raz(lstSimple)">
                    </td>
                </tr>
                <tr>
                    <td>
                        Liste à choix multiple</td>
                    <td>
                        <select multiple size="3" name="lstMultiple">
                            <%=lstMultipleOptions%>
                        </select>
                        <INPUT type="button" value="Raz" name="btnRazMultiple" onclick="raz(lstMultiple)">
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton simple</td>
                    <td>
                        <p align="center">
                            <input onclick="effacer()" type="button" value="Effacer" name="btnEffacer">
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton submit</td>
                    <td>
                        <p align="center">
                            <input type="submit" value="Envoyer" name="btnEnvoyer">
                        </p>
                    </td>
                </tr>
                <tr>
                    <td>
                        Bouton reset</td>
                    <td>
                        <p align="center">
                            <input type="reset" value="Rétablir" name="btnRetablir" runat="server">
                        </p>
                    </td>
                </tr>
            </table>
            <input type="hidden" name="secret" value="uneValeur">
        </form>
    </body>
</HTML>

بیایید درباره متغیرهای پویایی که در کد HTML ظاهر می‌شوند، نظر دهیم:

متغیر
نقش
rdouichecked
اگر دکمه رادیویی [oui] انتخاب شود، مقدار «checked» خواهد داشت و در غیر این صورت مقدار «».
rdnonchecked
همین امر در مورد دکمه رادیویی [non] نیز صدق می‌کند
c1checked
همین امر در مورد کادر تیک [C1] نیز صدق می‌کند
c2checked
همین امر در مورد چک‌باکس [C2] نیز صدق می‌کند
c3checked
همین موضوع در مورد کادر تیک [C3] نیز صدق می‌کند.
txtSaisie
متنی که باید در فیلد [txtSaisie] قرار گیرد
txtMdp
متنی که باید در فیلد [txtMdp] قرار گیرد
areaSaisie
متن برای قرار دادن در فیلد [areaSaisie]
cmbValeursOptions
متن HTML از میان گزینه‌های موجود در لیست کشویی [cmbValeurs]
lstSimpleOptions
متن HTML از گزینه‌های لیست کشویی [lstSimple]
lstMultipleOptions
متن HTML از گزینه‌های لیست انتخاب [lstMultiple]
  

مقادیر این متغیرها توسط کنترل‌کننده برای صفحه [formulaire.aspx.vb] محاسبه می‌شوند:


Imports Microsoft.VisualBasic
Imports System.Collections.Specialized

Public Class formulaire
    Inherits System.Web.UI.Page

    ' میدان‌های ثابت در فرم
    Private libellésCmbValeurs() As String = {"choix1", "choix2", "choix3"}
    Private valeursCmbValeurs() As String = {"1", "2", "3"}
    Private libellésLstSimple() As String = {"liste1", "liste2", "liste3"}
    Private valeursLstSimple() As String = {"1", "2", "3"}
    Private libellésLstMultiple() As String = {"multiple1", "multiple2", "multiple3", "multiple4", "multiple5"}
    Private valeursLstMultiple() As String = {"1", "2", "3", "4", "5"}

    ' fields پویا فرم
    Protected rdouichecked As String
    Protected rdnonchecked As String
    Protected c1checked As String
    Protected c2checked As String
    Protected c3checked As String
    Protected txtSaisie As String
    Protected txtMdp As String
    Protected areaSaisie As String
    Protected cmbValeursOptions As String
    Protected lstSimpleOptions As String
    Protected lstMultipleOptions As String

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'بازیابی درخواست قبلی از جلسه
        Dim form As NameValueCollection
        If Not Context.Items("formulaire") Is Nothing Then
            form = Context.Items("formulaire")
        Else
            form = New NameValueCollection
        End If
        'آماده‌سازی صفحه برای نمایش
        ' دکمه‌های رادیویی
        rdouichecked = ""
        rdnonchecked = "checked"
        If isEqual(form("rdMarie"), "oui") Then
            rdouichecked = "checked"
            rdnonchecked = ""
        End If
        ' تیک‌باکس‌ها
        c1checked = ""
        If isEqual(form("C1"), "un") Then c1checked = "checked"
        c2checked = ""
        If isEqual(form("C2"), "deux") Then c2checked = "checked"
        c3checked = ""
        If isEqual(form("C3"), "trois") Then c3checked = "checked"
        ' میدان‌های ورودی
        txtSaisie = ""
        If Not form("txtSaisie") Is Nothing Then txtSaisie = form("txtSaisie").ToString
        txtMdp = ""
        If Not form("txtMdp") Is Nothing Then txtMdp = form("txtMdp").ToString
        areaSaisie = ""
        If Not form("areaSaisie") Is Nothing Then areaSaisie = form("areaSaisie").ToString
        ' فهرست‌ها
        Dim sélections() As String = {}
        If Not form("cmbValeurs") Is Nothing Then sélections = form.GetValues("cmbValeurs")
        cmbValeursOptions = getOptions(valeursCmbValeurs, libellésCmbValeurs, sélections)
        sélections = New String() {}
        If Not form("lstSimple") Is Nothing Then sélections = form.GetValues("lstSimple")
        lstSimpleOptions = getOptions(valeursLstSimple, libellésLstSimple, sélections)
        sélections = New String() {}
        If Not form("lstMultiple") Is Nothing Then sélections = form.GetValues("lstMultiple")
        lstMultipleOptions = getOptions(valeursLstMultiple, libellésLstMultiple, sélections)
    End Sub

    Private Function getOptions(ByRef valeurs() As String, ByRef libelles() As String, ByRef sélections() As String) As String
        'کد HTML را برای گزینه‌های تگ <select> بازمی‌گرداند
        'مقادیر: آرایه مقادیر گزینه‌ها برای تگ
        ' برچسب‌ها: آرایهٔ برچسب‌های گزینه‌های تگ
        ' انتخاب‌ها: گزینه‌های قابل انتخاب
        Dim iValeur As Integer
        Dim iSelection As Integer
        Dim selected As String
        Dim toString As String = ""
        ' حلقه زدن روی لیست مقادیر گزینه
        For iValeur = 0 To valeurs.Length - 1
            'بررسی می‌کند که آیا مقدار فعلی باید انتخاب شود
            selected = "" : iSelection = 0
            Do While iSelection < sélections.Length And selected = ""
                If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
                iSelection += 1
            Loop
            ' کد گزینه را درج کنید HTML
            toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
            + libelles(iValeur) + "</option>" + ControlChars.CrLf
        Next
        ' نتیجه را بازمی‌گرداند
        Return toString
    End Function

    Private Function isEqual(Byval champ As Object, ByVal valeur As String) As Boolean
        ' در صورتی که فیلد با مقدار برابر باشد، مقدار true را برمی‌گرداند
        If champ Is Nothing OrElse champ.ToString <> valeur Then
            Return false
        Else
            Return true
        End If
    end function
End Class

وقتی صفحه [formulaire.aspx] اجرا می‌شود، در زمینهٔ خود کلید «form» را که با مجموعه مقادیر فیلدهایی که باید نمایش دهد مرتبط است، پیدا خواهد کرد.


         ' پرس‌وجوی قبلی را از جلسه بازیابی می‌کند
        Dim form As NameValueCollection
        If Not Context.Items("formulaire") Is Nothing Then
            form = Context.Items("formulaire")
        Else
            form = New NameValueCollection
        End If

ممکن است این سؤال پیش بیاید که چرا سیستم بررسی می‌کند آیا [Context.Items("formulaire")] وجود دارد یا خیر. در واقع، کنترلر در همهٔ موارد برای این شیء مقداری را تعیین می‌کند. با این حال، هیچ چیزی مانع از آن نمی‌شود که کلاینت مستقیماً صفحهٔ [formulaire.aspx] را بدون عبور از کنترلر درخواست کند. اگر این اتفاق بیفتد، کد بالا با یک مجموعهٔ خالی از مقادیر کار خواهد کرد، اما از کار نخواهد افتاد.

این کد برای محاسبه تمام متغیرهای پویا برای صفحه مرتبط HTML، روی مجموعه مقادیری که دریافت کرده است، تکرار (iterate) می‌کند. اگرچه این کد طولانی است، اما به خصوص پیچیده نیست و برای اینکه این توضیح بیش از حد طولانی نشود، بررسی دقیق آن را به خواننده واگذار می‌کنیم. با این حال، ما بر روی نحوه تولید کد HTML از سه لیست از نوع [select] تمرکز خواهیم کرد. این کد توسط تابع زیر تولید می‌شود:

    Private Function getOptions(ByRef valeurs() As String, ByRef libelles() As String, ByRef sélections() As String) As String
         'کد HTML را از گزینه‌های تگ <select> برمی‌گرداند
         'مقادیر: آرایه مقادیر گزینه‌های تگ
         ' برچسب‌ها: آرایهٔ برچسب‌های گزینه‌های تگ
         ' انتخاب‌ها: گزینه‌های قابل انتخاب
        Dim iValeur As Integer
        Dim iSelection As Integer
        Dim selected As String
        Dim toString As String = ""
         ' حلقه زدن روی لیست مقادیر گزینه
        For iValeur = 0 To valeurs.Length - 1
             'بررسی می‌کند که آیا مقدار فعلی باید انتخاب شود
            selected = "" : iSelection = 0
            Do While iSelection < sélections.Length And selected = ""
                If valeurs(iValeur) = sélections(iSelection) Then selected = "selected"
                iSelection += 1
            Loop
             ' کد گزینه را درج کنید HTML
            toString += "<option " + selected + " value='" + valeurs(iValeur) + "'> " _
            + libelles(iValeur) + "</option>" + ControlChars.CrLf
        Next
         'نتیجه را بازمی‌گرداند
        Return toString
    End Function

توجه داشته باشید که گزینه‌های تگ <select> با کد زیر مطابقت دارند: HTML

<option [selected] value="...">texte</option>

برای هر گزینه، بنابراین سه مورد اطلاعات باید تولید شوند:

  • مقدار گزینه در ویژگی [value]
  • متن گزینه بین تگ‌های <option> و </option>
  • کلمه کلیدی [selected] اگر گزینه باید از لیست انتخاب شود

برای تولید این سه بخش اطلاعات برای هر گزینه، تابع [getOptions] سه مقدار را می‌گیرد:

  1. آرایه مقادیر گزینه‌ها در [valeurs]
  2. آرایهٔ متن‌های گزینه در [libelles]
  3. مجموعه مقادیری که باید در [sélections] انتخاب شوند

5.5.4. صفحه اعتبارسنجی

صفحه اعتبارسنجی بدون تغییر باقی می‌ماند:

[validation.aspx]


<%@ Page src="validation.aspx.vb" Language="vb" AutoEventWireup="false" Inherits="validation" %>
<HTML>
    <HEAD>
        <title>validation</title>
    </HEAD>
    <body>
        <P>Valeurs saisies</P>
        <HR width="100%" SIZE="1">
        <TABLE id="Table1" cellSpacing="1" cellPadding="1" width="300" border="1">
            <TR>
                <TD width="84">rdMarie</TD>
                <TD><% =rdMarie%></TD>
            </TR>
            <TR>
                <TD width="84">C1</TD>
                <TD><%=C1%></TD>
            </TR>
            <TR>
                <TD width="84">C2</TD>
                <TD><%=C2%></TD>
            </TR>
            <TR>
                <TD width="84">C3</TD>
                <TD><%=C3%></TD>
            </TR>
            <TR>
                <TD width="84">txtSaisie</TD>
                <TD><%=txtSaisie%></TD>
            </TR>
            <TR>
                <TD width="84">txtMdp</TD>
                <TD><%=txtMdp%></TD>
            </TR>
            <TR>
                <TD width="84">areaSaisie</TD>
                <TD><%=areaSaisie%></TD>
            </TR>
            <TR>
                <TD width="84">cmbValeurs</TD>
                <TD><%=cmbValeurs%></TD>
            </TR>
            <TR>
                <TD width="84">lstSimple</TD>
                <TD><%=lstSimple%></TD>
            </TR>
            <TR>
                <TD width="84">lstMultiple</TD>
                <TD><%=lstMultiple%></TD>
            </TR>
            <TR>
                <TD width="84">secret</TD>
                <TD><%=secret%></TD>
            </TR>
        </TABLE>
        <P>
            <a href="main.aspx?action=formulaire">Retour au formulaire</a>
        </P>
    </body>
</HTML>

[validation.aspx.vb]


Imports Microsoft.VisualBasic
Imports System.Text.RegularExpressions

Public Class validation
    Inherits System.Web.UI.Page

    Protected rdMarie As String
    Protected C1 As String
    Protected C2 As String
    Protected C3 As String
    Protected txtSaisie As String
    Protected txtMdp As String
    Protected areaSaisie As String
    Protected cmbValeurs As String
    Protected lstSimple As String
    Protected lstMultiple As String
    Protected secret As String
    Protected delimiteur As New Regex("\r\n")

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'پارامترهای ارسال‌شده را بازیابی می‌کند
        rdMarie = getValue("rdMarie")
        C1 = getValue("C1")
        C2 = getValue("C2")
        C3 = getValue("C3")
        txtSaisie = getValue("txtSaisie")
        txtMdp = getValue("txtMdp")
        areaSaisie = String.Join(",", delimiteur.Split(getValue("areaSaisie")))
        cmbValeurs = getValue("cmbValeurs")
        lstSimple = getValue("lstSimple")
        lstMultiple = getValue("lstMultiple")
        secret = getValue("secret")
        ' آنها را در جلسه ذخیره می‌کند
        'Session("form") = Request.Form
    End Sub

    Private Function getValue(ByVal champ As String) As String
        'مقدار فیلد [champ] را از درخواست POST بازیابی می‌کند
        'چیزی؟
        If Request.Form(champ) Is Nothing Then Return ""
        'مقدار(ها) فیلد را بازیابی می‌کند
        Dim valeurs() As String = Request.Form.GetValues(champ)
        Dim valeur As String = ""
        Dim i As Integer
        For i = 0 To valeurs.Length - 1
            valeur += "[" + valeurs(i) + "]"
        Next
        Return valeur
    End Function
End Class

5.5.5. آزمایش

فایل‌های [main.aspx, main.aspx.vb,formulaire.aspx,formulaire.aspx.vb, validation.aspx, validation.aspx.vb] در <application-path> قرار می‌گیرند و Casini با پارامترها (<application-path>,/mvcform3) راه‌اندازی می‌شود. سپس ما URL [http://localhost/mvcform3/main.aspx] را درخواست می‌کنیم. ما فرم پیش‌تکمیل‌شده را دریافت می‌کنیم:

Image

ما فرم را به شرح زیر پر می‌کنیم:

Image

روی دکمه [Envoyer] در بالا کلیک می‌کنیم. پاسخ زیر را از سرور دریافت می‌کنیم:

Image

ما از لینک [Retour au formulaire] بالا برای بازگشت به فرم استفاده می‌کنیم. پاسخ جدید زیر را دریافت می‌کنیم:

Image

می‌توانیم ببینیم که فرم دقیقاً همان‌طور است که ارسالش کردیم.

5.5.6. نتیجه‌گیری

مثال قبلی به ما نشان داد که می‌توان وضعیت یک صفحه را در طول چرخه‌های درخواست-پاسخ بین کلاینت و سرور حفظ کرد. با این حال، این کار ساده‌ای نیست. در فصل بعدی خواهیم دید که با استفاده از ASP.NET می‌توان به سرور اجازه داد تا وضعیت یک صفحه را به طور خودکار بازیابی کند.