نویسنده : |
www.srco.ir |
|
86.10.03 |
|
912 بار مشاهده |
|
يكی از مهمترين محدوديت های view state ، شعاع استفاده از اطلاعات ذخيره شده در آن توسط ساير صفحات وب است . اطلاعات ذخيره شده در view state صرفا" توسط صفحه ای كه آنها را ايجاد كرده است قابل استفاده می باشند و ساير صفحات نمی توانند از اطلاعات فوق استفاده نمايند . به عنوان مثال ، در صورتی كه كاربر به صفحه ای ديگر حركت و يا هدايت شود ، اطلاعات ذخيره شده در view state قابل دستيابی نبوده و عملا" از بين خواهند رفت . برای غلبه بر محدوديت فوق ( انتقال اطلاعات از يك صفحه به صفحه ديگر )، از روش های متعدد ديگری می توان استفاده كرد .
در اين بخش ، با روش انتقال اطلاعات از يك صفحه به صفحه ای ديگر با استفاده از cross-page posting آشنا خواهيم شد . يكی از امكانات جديد ارائه شده در ASP. NET 2.0 ، امكان postback يك صفحه به صفحه ای ديگر است ( برخلاف گزينه پيش فرض كه هر صفحه به خود postback می گردد ) .
بدين منظور خصلت جديد PostBackUrl در كنترل هائی نظير ImageButton ، LinkButton و Button پيش بينی شده است . برای استفاده از ويژگی فوق كافی است مقدار PostBackUrl برابر با آدرس صفحه مقصد در نظر گرفته شود . بدين ترتيب ، پس از كليك بر روی دكمه موجود بر روی فرم ، صفحه به همراه تمامی مقادير كنترل های ورودی موجود بر روی آن برای آدرس مشخص شده ارسال می گردد .
مثال
در اين مثال بر روی فرم وب از دو كنترل text box و يك كنترل button استفاده شده است ( صفحه Crosspage1.aspx ) . پس از كليك بر روی دكمه موجود بر روی فرم ، اطلاعات موجود بر روی فرم برای صفحه ای با نام Crosspage2.aspx ارسال می گردد .
صفحه Crosspage1.aspx
<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
<head id="Head1" runat="server">
<title>صفحه اول </title>
</head>
<body style="font-family: Tahoma">
<form id="form1" runat="server" >
<div>
نام <asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox><br /><br />
نام خانوادگی <asp:TextBox ID="txtLastName" runat="server"></asp:TextBox> <br />
<br />
<asp:Button runat="server" ID="cmdPost"
PostBackUrl="CrossPage2.aspx"
Text="ارسال به صفحه ديگر" Font-Names="Tahoma" /><br />
</div>
</form>
</body>
</html>
صفحه Crosspage1.aspx شامل هيچگونه كدی نمی باشد .
پس از اجرای كد فوق و كليك بر روی دكمه "ارسال به صفحه ديگر" ، صفحه برای CrossPage2.aspx ارسال می گردد . صفحه Crosspage2.aspx با استفاده از خصلت Page.PreviousPage قادر به برقراری ارتباط با صفحه Crosspage1.aspx خواهد بود .
كد زير نحوه دريافت و نمايش عنوان صفحه قبلی را در صفحه Crosspage2.aspx نشان می دهد .
صفحه Crosspage2.aspx
<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
If PreviousPage IsNot Nothing Then
lblInfo.Text = "شما از صفحه ای با عنوان " & _
"<b>" & PreviousPage.Header.Title & "</b>" & _
" به اين صفحه آمده ايد" & "<br />"
End If
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
<head id="Head1" runat="server">
<title>صفحه دوم</title>
</head>
<body style="font-family: Tahoma">
<form id="form1" runat="server" >
<div>
<asp:Label ID="lblInfo" runat="server" Font-Size="Small"></asp:Label>
</div>
</form>
</body>
</html>
شكل 1 ، نحوه انتقال اطلاعات از يك صفحه به صفحه ديگر را نشان می دهد .
شكل 1 : نحوه انتقال اطلاعات از يك صفحه به صفحه ديگر
در صفحه Crosspage2.aspx قبل از تلاش برای دستيابی به شی PreviousPage ، مقدار آن با null بررسی می گردد . در صورتی كه مقدار آن معادل null باشد ، cross-page postback محقق نشده است . اين بدان معنی است كه صفحه Crosspage2.aspx مستقيما" درخواست شده است و يا به خود postback شده است . در چنين مواردی شی PreviousPage قابل دسترس نخواهد بود .
نحوه دريافت اطلاعات از صفحه مبداء
در مثال ارائه شده در بخش چهارم با نحوه عملكرد cross-page postback آشنا شديم و با بررسی يك مثال كاربردی ، عنوان صفحه مبداء در صفحه مقصد استخراج و در خروجی نمايش داده شد. شايد برای بسياری از خوانندگان اين سوال مطرح شده باشد كه چگونه می توان اطلاعاتی ديگر نظير مقادير درج شده در text boxes موجود بر روی صفحه مبداء ( CrossPage1.aspx ) را در صفحه مقصد ( CrossPage2.aspx ) بازيابی و از آنها استفاده كرد؟
در زمان پيكربندی يك صفحه برای عمليات cross-page posting ، اغلب پياده كنندگان تمايل به دريافت اطلاعات از صفحه مبداء را دارند . اين اطلاعات می تواند شامل كنترل های موجود بر روی صفحه مبداء و يا خصلت های عمومی صفحه مبداء باشد .
دريافت مقادير كنترل ها
كلاس Page دارای يك خصلت با نام PreviousPage است . در صورتی كه صفحه مبداء و مقصد در يك برنامه مشابه ASP.NET باشند ، خصلت PreviousPage در صفحه مقصد شامل يك مرجع به صفحه مبداء خواهد بود .
در صورتی كه صفحات مبداء و مقصد در برنامه های متفاوتی باشند ، خصلت PreviousPage مقداردهی اوليه نخواهد شد و نمی توان از طريق صفحه مقصد مستقيما" به مقادير كنترل های موجود بر روی صفحه مبداء دستيابی داشت . در چنين مواردی می توان با استفاده از ديكشنری Form اقدام به خواندن داده ارسال شده نمود . همچنين ، در چنين مواردی امكان خواندن مقادير ذخيره شده در view state صفحه مبداء وجود نخواهد داشت . در صورتی كه بخواهيم مقاديری را در صفحه مبداء ذخيره نمائيم و آنها را برای يك صفحه مقصد و در يك برنامه ديگر قابل دسترس نمائيم ، می توان مقادير مورد نظر را به عنوان رشته درون فيلدهای مخفی بر روی صفحه مبداء ذخيره و در صفحه مقصد از طريق Request.Form به آنها دستيابی داشت .
با استفاده از مرجع در خصلت PreviousPage می توان عمليات جستجو بر روی صفحه مبداء را به منظور بازيابی و استخراج مقادير مورد نظر توسط متد FindControl انجام داد .
كد زير نحوه بازيابی مقادير درج شده در كنترل های Textbox موجود بر روی صفحه مبداء (CrossPage1.aspx) را نشان می دهد .
بازيابی مقادير كنترل های موجود در صفحه مبداء
(Script section صفحه مقصد )
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
If PreviousPage IsNot Nothing Then
Dim txtSourceFirstName As TextBox
Dim txtSourceLastName As TextBox
txtSourceFirstName = CType(PreviousPage.FindControl("txtFirstName"), TextBox)
txtSourceLastName = CType(PreviousPage.FindControl("txtLastName"), TextBox)
lblInfo.Text = " نام و نام خانوادگی دريافت شده از صفحه مبداء " & _
txtSourceFirstName.Text & " " & txtSourceLastName.Text
End If
End Sub
</script>
متد FindControl ، كنترل های مورد نظر را در فهرست جاری نام جستجو می نمايد . در صورتی كه قصد جستجوی كنترل موجود در كنترل ديگر را داشته باشيم ( نظير يك تمپليت ) ، می بايست در ابتدا يك مرجع به آْن را ايجاد و عمليات جستجو را در آن فهرست انجام داد .
دريافت مقادير خصلت های عمومی
در صفحه مقصد يك cross-page posting ، می توان مقادير فيلدهای عمومی موجود در صفحه مبداء را دريافت كرد . بدين منظور صفحه مبداء خصلت هائی عمومی را با توجه به اهداف عملياتی برنامه تعريف می نمايد تا در ادامه صفحه مقصد بتواند به آنها دستيابی داشته باشد ( به عنوان يك توصيه امنيتی پيشنهاد شده است كه حجم اين گونه اطلاعات عمومی كمتر در نظر گرفته شود تا آسيب پذيری كد در مقابل حملات كاهش يابد ) .
برای دريافت فيلدهای عمومی صفحه مبداء ، در ابتدا می بايست يك مرجع به صفحه مبداء را تعريف كرد . بدين منظور می توان از روش های مختلفی استفاده كرد . استفاده از دايركتيو PreviousPageType @ در صفحه مقصد كه به كمك آن صفحه مبداء مشخص می گردد ، يكی از روش های موجود در اين زمينه است .
كد زير نحوه انجام اين كار را مشخص می نمايد .
<%@ PreviousPageType VirtualPath="~/CrossPage1.aspx" %>
پس از استقرار دايركتيو فوق در صفحه مقصد ، خصلت PreviousPage به كلاس صفحه مبداء اشاره خواهد داشت ( به عنوان يك مرجع ) . در ادامه می توان مستقيما" به اعضاء عمومی موجود در صفحه مبداء دستيابی داشت .
به عنوان مثال، در صورتی كه قصد داشته باشيم از مقادير موجود در دو text box صفحه مبداء استفاده نمائيم (صفحه CrossPage1.aspx)، می توان خصلت هائی را به منظور استفاده از متغيرهای كنترل به آن اضافه كرد .
در نمونه كد زير دو خصلت به كلاس CrossPage1 اضافه شده است تا بتوان از مقادير كنترل های Textbox در صفحه مقصد استفاده كرد .
Public ReadOnly Property FirstNameTextBox() As TextBox
Get
Return txtFirstName
End Get
End Property
Public ReadOnly Property LastNameTextBox() As TextBox
Get
Return txtLastName
End Get
End Property
در صورتی كه صفحه مقصد شامل دايركتيو PreviousPageType باشد كه توسط آن به صفحه مبداء اشاره می گردد ، می توان به خصلت های عمومی صفحه مبداء دستيابی داشت .
مثال
برای بازنويسی مثال ارائه شده در بخش چهارم مراحل زير را انجام می دهيم .
مرحله اول: بازنويسی صفحه CrossPage1.aspx . كد فوق مشابه كد نوشته شده در بخش چهارم است با اين تفاوت كه برای دستيابی به نام و نام حانوادگی درج شده در هر Textbox يك خصلت عمومی با نام FullName تعريف شده است تا نام و نام خانوادگی ورودی را در خود نگهداری نمايد .
صفحه Crosspage1.aspx
<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %> <script runat="server">
Public ReadOnly Property FullName() As String
Get
Return txtFirstName.Text & " " & txtLastName.Text
End Get
End Property
</script>
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
<head id="Head1" runat="server">
<title>صفحه اول </title>
</head>
<body style="font-family: Tahoma">
<form id="form1" runat="server" >
<div>
نام <asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox><br /><br />
نام خانوادگی <asp:TextBox ID="txtLastName" runat="server"></asp:TextBox> <br />
<br />
<asp:Button runat="server" ID="cmdPost"
PostBackUrl="CrossPage2.aspx"
Text="ارسال به صفحه ديگر" Font-Names="Tahoma" /><br />
</div>
</form>
</body>
</html>
بدين ترتيب ، ارتباط بين دو صفحه واضح و ساده بوده و نگهداری آنها نيز آسان خواهد شد . همچنين ، می توان كنترل ها را در صفحه مبداء ( CrossPage1 ) بدون نياز به تغيير ساير بخش های برنامه تغيير داد . مثلا" ، در صورتی كه تصميم داشته باشيم از كنترل های مختلفی برای درج نام در صفحه CrossPage1.aspx استفاده نمائيم ، می بايست بر روی كد مربوط به خصلت FullName متمركز گرديد . تغيير فوق صرفا" در صفحه CrossPage1.aspx اعمال می گردد و ضرورتی به تغيير صفحه CrossPage2.aspx وجود نخواهد داشت .
مرحله دوم : بازنويسی صفحه CrossPage2.aspx . در بازنويسی صفحه فوق در اولين اقدام از دايركتيو PreviousPageType @ برای معرفی كلاس صفحه مبداء استفاده شده است تا به كمك آن بتوان به اعضاء عمومی تعريف شده در صفحه مبداء دستيابی داشت . برای دستيابی به خصلت عمومی FullName ، از PreviousPage.FullName استفاده شده است .
صفحه Crosspage2.aspx
<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>
<%@ PreviousPageType VirtualPath="~/crossPage1.aspx" %> <script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
If PreviousPage IsNot Nothing Then
lblInfo.Text = "شما از صفحه ای با عنوان " & _
"<b>" & PreviousPage.Header.Title & "</b>" & _
" به اين صفحه آمده ايد" & "<br />"
lblInfo.Text &= "نام و نام خانوادگی دريافت شده از صفحه مبداء " & _
& "<b>" & PreviousPage.FullName & "<br />"
End If
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
<head id="Head1" runat="server">
<title>صفحه دوم</title>
</head>
<body style="font-family: Tahoma">
<form id="form1" runat="server" >
<div>
<asp:Label ID="lblInfo" runat="server" Font-Size="Small"></asp:Label>
</div>
</form>
</body>
</html>
شكل 1 ، خروجی برنامه فوق را نشان می دهد .
شكل 1 : دستيابی به مقادير كنترل ها در صفحه مقصد
ASP. NET از ويژگی جالبی برای كاركرد بهتر فرآيند cross-page postbacks استفاده می نمايد . اولين مرتبه ای كه صفحه مقصد به Page.PreviousPage دستيابی پيدا می نمايد ، ASP. NET شی صفحه قبلی ( مبداء) را ايجاد نمايد . برای انجام اين كار ، ASP. NET پردازش صفحه را آغاز ولی آن را قبل از رسيدن به مرحله PreRender با وقفه متوقف نموده و اجازه نمی دهد كه صفحه خروجی HTML را توليد نمايد .
روش فوق دارای اثرات جانبی جالبی است ، مثلا" تمامی رويدادهای صفحه مربوط به صفحه قبل ( نظير Page.Load و Page.Init ) به همراه رويداد Button.Click كه باعث cross-page postback شده است ، فعال می گردند . علت فعال شدن رويدادهای فوق ، مقدار دهی صفحه مبداء توسط ASP.NET است .
بررسی PostBack در صفحه مقصد
در حين فرآيند cross-page postback ، محتويات كنترل های موجود بر روی صفحه مبداء برای صفحه مقصد ارسال و مرورگر يك عمليات HTTP POST را انجام می دهد ( نه عمليات GET ) . در صفحه مقصد و بلافاصله پس از عمليات postback ، مقدار خصلت IsPostBack برابر با false خواهد شد . با اين كه ماهيت عمليات در واقع يك POST را نشان می دهد ، ولی cross-posting بيانگر يك Postback به صفحه مقصد نمی باشد .
در برخی موارد لازم است كه در يك برنامه تشخيص دهيم كه آيا يك cross-page post واقع شده است. در چنين مواردی می توان مقدار خصلت IsCrossPagePostBack را بر روی صفحه مقصد كه توسط خصلت PreviousPage صفحه مقصد برگردانده شده است ، بررسی كرد .
كد زير نحوه انجام اين كار را نشان می دهد .
If PreviousPage IsNot Nothing Then
If PreviousPage.IsCrossPagePostBack = True Then
Label1.Text = "Cross-page post."
End If
Else
Label1.Text = "Not a cross-page post."
End If