PDA

View Full Version : State Management در ASP. NET 2.0



aryaei2000
پنج شنبه 07 شهریور 1387, 00:50 صبح
يكی از مهمترين تفاوت های موجود بين برنامه های وب و Desktop ، مديريت state است كه در آن می بايست به اين پرسش پاسخ داده شود كه نحوه نگهداری اطلاعات در ارتباط با كاربر جاری به چه صورت است ؟
در يك برنامه سنتی ويندوز ، state بطور اتوماتيك مديريت می گردد . حافظه به حد فراوان يافت می شود و همواره در دسترس است . در برنامه های وب داستان بگونه ای ديگر است . هزاران كاربر ممكن است بطور همزمان برنامه ای مشابه را بر روی كامپيوتری يكسان ( سرويس دهنده وب ) اجراء و هر يك از آنان از طريق پروتكل HTTP ( برگرفته شده از Hypertext Transfer Protocol) كه دارای ماهيتی stateless است با سرويس دهنده وب ارتباط برقرار نمايند . مجموعه شرايط فوق باعث شده است كه نتوان برنامه های وب را با سناريوئی دقيقا" مشابه با برنامه های سنتی ويندوز طراحی و پياده سازی كرد .
هيچگونه فريمورك برنامه نويسی وب ، صرفنظر از ميزان پيشرفته بودن آن ، نمی تواند ماهيت stateless بودن پروتكل HTTP را تغيير دهد. پس از هر درخواست و پاسخ به آن ، ارتباط منطقی سرويس گيرنده با سرويس دهنده قطع خواهد شد . معماری فوق ، اين اطمينان را ايجاد می نمايد كه برنامه های وب بتوانند به هزاران كاربر بطور همزمان و بدون نگرانی در خصوص حافظه پاسخ دهند . استفاده از روش های مختلف برای ذخيره اطلاعات بين درخواست های متعدد يك كاربر و بازيابی آنها در زمانی كه به آنها نياز است از جمله مشكلات معماری فوق برای پياده كنندگان برنامه های وب محسوب می گردد .

aryaei2000
پنج شنبه 07 شهریور 1387, 00:52 صبح
آشنائی و درك مناسب نسبت به محدوديت های state ، يكی از مفاهيم كليدی در زمان ايجاد برنامه های وب كارآ و قدرتمند است .

در مجموعه مقالاتی كه در اين خصوص آماده و بتدريج بر روی سايت منتشر خواهد شد به بررسی موارد زير خواهيم پرداخت :
آشنائی با مفاهيم ، جايگاه و لزوم مديريت state در برنامه های وب

آشنائی با پتانسيل های ارائه شده در ASP. NET 2.0 برای ذخيره سازی و مديريت اطلاعات
آشنائی با گزينه های متفاوت موجود به منظور مديريت state نظير View state ، Session state ، كوكی های سفارشی
نحوه انتقال اطلاعات از يك صفحه به صفحه ديگر

aryaei2000
پنج شنبه 07 شهریور 1387, 00:55 صبح
مديريت state و مسائل در ارتباط با آن
در يك برنامه سنتی ويندوز ، كاربران با يك برنامه در حال اجراء بطور پيوسته ارتباط برقرار می نمايند . بخشی از حافظه موجود بر روی كامپيوتر Desktop برای ذخيره تنظيمات جاری اطلاعات محيط كار كاربر اختصاص داده می شود .
در يك برنامه وب ، داستان كاملا" متفاوت است . شايد از ديد كاربران يك سايت حرفه ای اينگونه برداشت شود كه يك برنامه بطور مستمر در حال اجراء است و به آنان سرويس های لازم را می دهد . علی رغم اين كه ظاهر موضوع درست بنظر می آيد ولی در پس پرده داستان بگونه ای ديگر دنبال می شود . برنامه های وب از يك الگوی دستيابی غيرمتصل كارآ استفاده می نمايند . در اين الگو ، سرويس گيرنده پس از ارتباط با سرويس دهنده از آن درخواست يك صفحه را می نمايد . پس از پاسخ به سرويس گيرنده ،ارتباط منطقی ايجاد شده قطع و سرويس دهنده بی خيال هر گونه اطلاعاتی در رابطه با سرويس گيرنده می گردد . پس از دريافت صفحه درخواستی توسط سرويس گيرنده ، برنامه اجراء خود را متوقف و ASP.NET engine اشياء مربوط به صفحه را دور می اندازد .
با توجه به اين كه سرويس گيرندگان لازم است در اكثر موارد صرفا" برای چندين ثانيه متصل باشند ، يك سرويس دهنده وب می تواند به هزاران درخواست با كارآئی مطلوب پاسخ دهد .
در صورتی كه لازم است اطلاعات بين چندين عمليات كاربر نگهداری شوند ، می بايست از راهكارهای مختلفی به منظور مديريت state استفاده كرد .

aryaei2000
پنج شنبه 07 شهریور 1387, 00:56 صبح
View state
همانگونه كه اطلاع داريد كنترل های سرويس دهنده ASP.NET از view state برای بخاطر سپردن state استفاده می نمايند . اطلاعات view state در يك فيلد مخفی نگهداری شده و بطور اتوماتيك پس از هر postback برای سرويس دهنده ارسال می گردد . view state محدود به كنترل های سرويس دهنده نمی گردد و در صورت ضرورت می توان مجموعه ای از اطلاعات مورد نياز را مستقيما" در مجموعه view state ذخيره تا امكان بازيابی آنها پس از هر postback فراهم شود . نوع های مختلفی را می توان در view state ذخيره نمود . نوع های داده ساده و اشياء سفارشی نمونه هائی در اين زمينه می باشند .
خصلت ViewState صفحه، مجموعه view state را ارائه می نمايد . اين خصلت يك نمونه از كلاس مجموعه StateBag است .برای اضافه كردن و حذف آيتم هائی در اين كلاس ، از گرامری مشابه با يك ديكشنری استفاده می گردد كه در آن هر آيتم دارای يك نام منحصر بفرد است .
كد زير نحوه استفاده از view state را نشان می دهد .


ViewState("Counter") = 1

دستور فوق ، مقدار 1 را در مجموعه view state قرار داده و به آن يك نام منحصربفرد را نسبت می دهد ( Counter ) . در صورتی كه آيتم ديگری با همين نام در view state موجود نباشد ، يك آيتم جديد بطور اتوماتيك به آن اضافه می گردد . در صورتی كه يك آيتم با نام Counter در view state موجود باشد ، با مقدار فوق جايگزين می گردد .
برای بازيابی آيتم های ذخيره شده در view state از نام نسبت داده شده به هر يك از آنها استفاده می گردد . همچنين ، لازم است كه مقدار بازيابی شده را با استفاده از گرامر casting به نوع داده مناسب تبديل نمود چراكه مجموعه ViewState تمامی آينم ها را به عنوان اشياء عام ذخيره می نمايد تا بتواند با نوع های داده مختلف سرو كار داشته باشد .
كد زير نحوه بازيابی مقدار نسبت داده شده به Counter از view state و تبديل آن به يك عدد صحيح را نشان می دهد .



Dim counter As Integer
counter = CType(ViewState("Counter"), Integer)


در صورت عدم وجود اطلاعات مورد نظر در view state با يك NullReferenceException مواجه خواهيم شد . بنابراين ، لازم است كه همواره قبل از بازيابی و تبديل داده ذخيره شده در view state از وجود آن در ساختار فوق اطمينان حاصل نمود .
برای آشنائی بيشتر با نحوه بكارگيری view state در برنامه های وب به بررسی يك نمونه مثال كاربردی خواهيم پرداخت .

aryaei2000
پنج شنبه 07 شهریور 1387, 00:57 صبح
مثال : ثبت تعداد دفعاتی كه بر روی يك دكمه كليك می گردد
كد زير يك برنامه ساده شمارنده را نشان می دهد كه در آن تعداد دفعاتی كه بر روی يك دكمه كليك می شود تشخيص داده شده و تعداد آن در خروجی نمايش داده می شود . بدون استفاده از يك راهكار مناسب برای مديريت state ، شمارنده بطور دائم عدد 1 را در خروجی نشان خواهد داد .
برای ايجاد خروجی مورد نظر ، می بايست از يك راهكار مناسب (view state ) جهت مديريت state استفاده گردد .



<%@ Page Language="VB" Culture="fa-IR" UICulture="fa-IR" %>

<script runat="server">
Sub cmdIncrement_Click(ByVal sender As Object,ByVal e As EventArgs) Handles cmdIncrement.Click
Dim Counter As Integer
If ViewState("Counter") Is Nothing Then
Counter = 1
Else
Counter = CType(ViewState("Counter"), Integer) + 1
End If
ViewState("Counter") = Counter
lblCount.Text = "مقدار شمارنده برابر است با : " & Counter.ToString()
End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
<head id="Head1" runat="server">
<title>تست view state </title>
</head>
<body style="font-family: Tahoma">
<form id="form1" runat="server">
<div>
<asp:Button ID="cmdIncrement" runat="server"
Text="افزايش شمارنده" Font-Names="Tahoma" /><br /><br />
<asp:Label ID="lblCount" runat="server"
Font-Names="Tahoma"></asp:Label>&nbsp;
</div>
</form>
</body>
</html>

aryaei2000
پنج شنبه 07 شهریور 1387, 00:58 صبح
برای حل مسئله مديريت state در مثال فوق و نگهداری مقدار counter در بين چندين postback از روش هائی ديگر نيز می توان استفاده كرد . به عنوان مثال ، می توان برای كنترل سرويس دهنده label ويژگی view state را فعال و از label برای ذخيره مقدار counter استفاده نمود . هر مرتبه كه بر روی دكمه "افزايش شمارنده " كليك گردد ، مقدار جاری از طريق خصلت text كنترل label بازيابی و پس از تبديل به يك عدد صحيح در خروجی نمايش داده می شود .
از روش فوق نمی توان همواره به عنوان يك راهكار مناسب استفاده كرد . مثلا" ممكن است قصد ايجاد برنامه ای را داشته باشيم كه تعداد دفعاتی را كه بر روی يك دكمه كليك می گردد ثبت نمايد ولی قصد نمايش نتايج را در خروجی نداشته باشيم . در چنين مواردی می توان همچنان اطلاعات را در يك كنترل سرويس دهنده ذخيره نمود ولی مجبور خواهيم بود كه آن را مخفی نگاه داريم .
پس از انجام تمامی اين كارها ، به چيزی می رسيم كه view state آن را در اختيار ما قرار می دهد . view state ، اطلاعات را بطور اتوماتيك در يك فيلد مخفی خاص در صفحه نگهداری می نمايد . با توجه به اين كه ASP. NET با جزئيات اين كار سروكار دارد ، كد نوشته شده توسط پياده كنندگان از خوانائی بيشتری برخوردار خواهد بود .
در بخش دوم به بررسی نحوه ايمن سازی اطلاعات ذخيره شده در view state خواهيم پرداخت .

aryaei2000
پنج شنبه 07 شهریور 1387, 01:03 صبح
نحوه ايمن سازی اطلاعات ذخيره شده در view state
اطلاعات view state در يك رشته درهم آميخته مشابه زير ذخيره می گردد .

<input type="hidden"
name="__VIEWSTATE"
value="/wEPDwUKMTUyMzMyNzc3NGRklXVE/6qqfC5AWkr1Yw0Xu5IpHg0="
/>

به موازات اضافه كردن اطلاعات بيشتر به view state ، طول اين رشته طولانی تر خواهد شد . با توجه به اين كه مقدار ذخيره شده در رشته فوق به صورت متن شفاف نمی باشد ، بسياری از برنامه نويسان ASP.NET بر اين باور هستند كه داده ذخيره شده در view state به صورت رمز شده است .ولی واقعيت اينچنين نيست . در واقع ، اطلاعات view state به سادگی در حافظه به يكديگر متصل شده و به يك رشته Base64 تبديل می شوند .يك هكر باهوش می تواند با استفاده از مهندسی معكوس رشته فوق ، view state را بررسی و از اطلاعات ذخيره شده در آن به سرعت آگاه گردد .
كد زير نحوه رمز كردن يك رشته معمولی را به يك رشته Base64 نشان می دهد .



Private Function EncodeBase64(ByVal input As String) As String
Dim strBytes() As Byte = System.Text.Encoding.UTF8.GetBytes(input)
Return System.Convert.ToBase64String(strBytes)
End Function

aryaei2000
پنج شنبه 07 شهریور 1387, 01:05 صبح
كد زير نحوه رمز گشائی يك رشته Base64 را به يك رشته معمولی نشان می دهد .



Private Function DecodeBase64(ByVal input As String) As String
Dim strBytes() As Byte = System.Convert.FromBase64String(input)
Return System.Text.Encoding.UTF8.GetString(strBytes)
End Function

aryaei2000
پنج شنبه 07 شهریور 1387, 01:06 صبح
در صورتی كه لازم است اطلاعات ذخيره شده در view state دارای ايمنی بيشتری باشند از دو گزينه مختلف می توان استفاده كرد :
گزينه اول : به ASP. NET اعلام شود كه از يك hash code استفاده نمايد. برخی اوقات از hash code به عنوان يك checksum قدرتمند پنهانی نيز ياد می شود . در چنين مواردی ، ASP. NET تمامی داده ذخيره شده در view state را بررسی و يك الگوريتم hashing را بر روی آن اعمال می نمايد . الگوريتم فوق يك سگمنت كوتاه از داده را ايجاد می نمايد كه در واقع همان hash code است . در ادامه ، كد فوق به انتهای داده ذخيره شده در view state اضافه می گردد .
زمانی كه صفحه post back می گردد ، ASP. NET داده موجود در view state را بررسی و مجددا" hash code را با استفاده از فرآيندی مشابه توليد می نمايد . در ادامه مقدار محاسبه شده با مقدار موجود در رشته مقايسه می گردد تا اين اطمينان حاصل شود كه داده ذخيره شده در view state تغيير نكرده باشد .
در صورتی كه يك كاربر بدانديش بخشی از داده موجود در view state را تغيير دهد ، ASP. NET يك hash code را توليد خواهد كرد كه با كد ذخيره شده در انتهای view state مطابقت نخواهد كرد . در صورت تحقق چنين شرايطی ، postback بطور كامل ناديده گرفته خواهد شد .
شايد در ذهن شما اين موضوع مطرح شده باشد كه يك كاربر باهوش می تواند با بكارگيری ترفندهائی بر مشكل اشاره شده غلبه كرده و علاوه بر توليد اطلاعات نادرست ، يك hash code مناسب و منطبق بر اطلاعات ذخيره شده در view state را نيز توليد نمايد . در پاسخ می بايست به اين نكته اشاره كرد كه كاربران بدانديش قادر به توليد hash code صحيح نخواهند بود چراكه آنان دارای كليد رمزنگاری مشابه ASP. NET نمی باشند . اين بدان معنی است كه hash code توليد شده با وضعيت موجود نمی تواند مطابقت نمايد .
hash code بطور پيش فرض فعال است . بنابراين در صورت تمايل به استفاده از پتانسيل فوق ، لازم نيست كه مراحل اضافه ای را دنبال نمود . در برخی موارد پياده كنندگان ويژگی فوق را غيرفعال می نمايند تا از مشكلات احتمالی موجود در يك web farm پيشگيری نمايند . در چنين وضعيتی ، سرويس دهندگان مختلف دارای كليدهای مختلفی می باشند و مشكل زمانی اتفاق می افتد كه پس از post back صفحه ، يك سرويس دهنده جديد آن را دريافت نمايد .
در يك محيط web farm كليد می بايست در بين تمامی سرويس دهندگان يكسان باشد . در صورتی كه كليد يكسان نباشد و صفحه برای يك سرويس دهنده متفاوت با سرويس دهنده ای كه صفحه را ايجاد كرده است ، post back گردد ، يك خطاء ايجاد خواهد شد .بنابراين در يك محيط web farm ، می بايست پياده كنندگان يك كليد را در فايل Machine.config مشخص نمايند ( در مقابل اين كه به ASP.NET اجازه داده شود كه اين كليد را بطور اتوماتيك ايجاد نمايد) .
برای غيرفعال كردن hash codes ، می بايست از خصلت enableViewStateMac عنصر <pages> در فايل web.config و يا machine.config به صورت زير استفاده كرد .



<configuration >
<system.web>
<pages enableViewStateMac="false" />
...
</system.web>
</configuration>

aryaei2000
پنج شنبه 07 شهریور 1387, 01:07 صبح
گزينه دوم : با ايجاد يك كد hash ، فريمورك ASP. NET اين موضوع را بررسی خواهد كرد كه آيا داده ذخيره شده در view state دستكاری شده است ؟ علی رغم ايجاد اين لايه امنيتی ، داده موجود در view state همچنان قابل مشاهده توسط كاربران بدانديش خواهد بود .
در صورتی كه بر روی داده ذخيره شده در view state حساسيت زيادی وجود داشته باشد و بخواهيم امنيت آن را افزايش دهيم ، می بايست رمزنگاری view state را فعال كرد . برای فعال كردن ويژگی فوق از خصلت ViewStateEncryptionMode به همراه دايركتيو page استفاده می گردد .



<%@Page ViewStateEncryptionMode="Always" %>


در صورت تمايل می توان از خصلت فوق در فايل پيكربندی نيز استفاده كرد .



<configuration >
<system.web>
<pages viewStateEncryptionMode="Always" />
...
</system.web>
</configuration>


به خصلت ViewStateEncryptionMode يكی از مقادير زير را می توان نسبت داد :
<LI dir=rtl>Always : همواره رمزنگاری انجام می شود .
<LI dir=rtl>Never : رمزنگاری انجام نخواهد شد .
Auto : رمزنگاری صرفا" در مواردی كه يك كنترل با صراحت آن را درخواست نمايد ، انجام خواهد شد .
گزينه پيش فرض Auto است . اين بدان معنی است كه يك كنترل با فراخوانی متد Page.RegisterRequiresViewStateEncryption رمزنگاری را درخواست می نمايد . در صورتی كه يك كنترل به دليل عدم داشتن اطلاعات حساس از متد فوق استفاده نكند ، view state رمز نخواهد شد و عمليات بيشتری جهت رمزنگاری به سيستم تحميل نخواهد شد . به عبارت ديگر ، يك كنترل زمانی می تواند دل خود را به خدمات ارائه شده توسط متد فوق خوش نمايد كه مقدار خصلت viewStateEncryptionMode ، معادل Auto در نظر گرفته شده باشد . در صورتی كه مقدار خصلت فوق Never در نظر گرفته شده باشد ، به درخواست كنترل ها جهت رمزنگاری پاسخ داده نخواهد شد.
با توجه به اين كه رمزنگاری عمليات بيشتری را به سرويس دهنده وب تحميل می نمايد ( هم در زمان رمزنگاری و هم در زمان رمزگشائی پس از هر post back ) در صورت عدم نياز به پتانسيل فوق و به منظور عدم تاثيرگذاری آن بر روی كارآئی برنامه های وب ، ضرورتی به فعال كردن آن وجود ندارد .
در بخش سوم بحث بر روی State Management را ادامه داده و بررسی نحوه نگهداری Member Variables و اشياء سفارشی در view state خواهيم پرداخت .

aryaei2000
پنج شنبه 07 شهریور 1387, 01:08 صبح
انواع متغيرها
پس از ايجاد ساختار اوليه يك كلاس ، می بايست عناصر داده پايه را به آن اضافه نمود .
در كد زير ، سه member variable تعريف شده است كه اطلاعاتی را در ارتباط با product ( شامل نام ، قيمت و URL آن كه به يك فايل image اشاره می نمايد ) در خود نگهداری می نمايند .



Public Class Product
Private name As String
Private price As Decimal
Private imageUrl As String
End Class

aryaei2000
پنج شنبه 07 شهریور 1387, 01:09 صبح
يك متغير محلی صرفا" تا زمانی وجود خواهد داشت كه فعاليت متد جاری ادامه داشته باشد . به عبارت ديگر ، يك member variable ( و يا فيلد ) به عنوان بخشی از كلاس تعريف می شود و برای تمامی متدهای موجود در كلاس قابل دسترس و استفاده است . اين نوع متغيرها ، پس از ايجاد شی ، ايجاد خواهند شد و تا زمانی كه شی مورد نظر به فعاليت خود ادامه می دهد ، آنها نيز فعال و به حيات خود ادامه خواهند داد .
زمانی كه يك member variable تعريف می گردد ، می بايست با صراحت قابليت دستيابی به آن مشخص گردد . قابليت دستيابی پذيری مشخص می نمايد كه چه بخش هائی از كد قادر به خواندن و تغيير اين متغير می باشند . مثلا" اگر شی A شامل يك متغير خصوصی (Private ) باشد ، شی B قادر به خواندن و تغيير آن نخواهد بود و صرفا" شی A قادر به انجام اين كار خواهد بود . به عبارت ديگر ، اگر شی A دارای يك متغير عمومی ( public ) باشد ، هر شی ديگر موجود در برنامه اين آزادی عمل را خواهد داشت كه اقدام به خواندن و تغيير اطلاعات ذخيره شده در آن نمايد . متغيرهای محلی از هيچگونه كليد واژه قابليت دستيابی پذيری حمايت نمی نمايند چراكه اين نوع متغيرها هرگز نمی توانند برای ساير كد های موجود در خارج از متد جاری در دسترس باشند .
در يك برنامه ساده ASP. NET ، اكثر member variables خصوصی خواهند بود چراكه اكثر كد نوشته شده توسط پياده كنندگان در يك كلاس صفحه وب قرار می گيرد .
به موازات تلاش جهت ايجاد عناصر نرم افزاری با قابليت استفاده مجدد ، اهميت قابليت دستيابی پذيری افزايش خواهد يافت .

aryaei2000
پنج شنبه 07 شهریور 1387, 01:10 صبح
توجه داشته باشيد كه كليد واژه " قابليت دستيابی پذيری " ، صرفا" در ارتباط با member variable بكار گرفته نمی شود و از آن در ارتباط با متدها ، خصلت ها و رويدادها نيز استفاده می گردد.
ذخيره Member variables در view state
هر گونه اطلاعاتی كه در يك member variable صفحه ASP. NET ذخيره می گردد ، بطور اتوماتيك و پس از اتمام پردازش و ارسال صفحه برای سرويس گيرنده از بين می رود ( به عنوان نمونه متغير counter در مثال ارائه شده در بخش اول (http://srco.ir/Articles/DocView.asp?ID=529) ) .
برای حل مشكلاتی اين چنين می توان تمامی member variables را در زمان بروز رويداد Page.PreRender در view state ذخيره و زمانی كه رويداد Page.Load ايجاد می گردد آنها را بازيابی كرد . رويداد Load هر مرتبه كه صفحه ايجاد می شود ، محقق می گردد . در زمان postback ، در ابتدا رويداد Load محقق شده و در ادامه ساير رويدادهای مرتبط با كنترل ها ايجاد خواهند شد .

aryaei2000
پنج شنبه 07 شهریور 1387, 01:10 صبح
مثال
در كد زير از روش فوق در ارتباط با متغيری با نام Contents ، استفاده شده است . در اين صفحه يك text box به همراه دو button ارائه شده است . كاربر در خصوص ذخيره و يا بازيابی داده از view state تصميم می گيرد . روتين های مربوط به رويداد كليك هر يك از دكمه های موجود بر روی فرم ، مسئوليت ذخيره و بازيابی داده در متغير Contents را برعهده دارند . در روتين های فوق ضرورتی به ذخيره و بازيابی مقدار متغير contents در view state وجود ندارد چراكه اين مسئوليت به روتين های رويدادهای Load و PreRender واگذار شده است تا در زمان آغاز و اتمام پردازش صفحه ، وظايف اشاره شده ( ذخيره و بازيابی ) را انجام دهند .



<%@ Page Language="VB" Culture="fa-IR" UICulture="fa" %>
<script runat="server">

Private Contents As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Me.IsPostBack Then
Contents = CType(ViewState("Text"), String)
End If
End Sub

Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
ViewState("Text") = Contents
End Sub

Protected Sub cmdSave_Click(ByVal sender As Object, ByVal e As EventArgs)Handles cmdSave.Click
Contents = txtValue.Text
txtValue.Text = ""
End Sub

Protected Sub cmdLoad_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cmdLoad.Click
txtValue.Text = Contents
End Sub

</script>
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
<head id="Head1" runat="server">
<title>ذخيره member variable</title>
</head>
<body style="font-family: Tahoma">
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtValue" runat="server" Height="153px" TextMode="MultiLine" Width="341px"
Font-Names="Tahoma" >نحوه ذخيره و بازيابی متغيرهای member در view state</asp:TextBox><br />
<br />
<asp:Button ID="cmdSave" runat="server" Text="ذخيره " Font-Names="Tahoma" />
<asp:Button ID="cmdLoad" runat="server" Text="بازيابی" Font-Names="Tahoma" />
</div>
</form>
</body>
</html>

aryaei2000
پنج شنبه 07 شهریور 1387, 01:12 صبح
ذخيره اشياء سفارشی
پياده كنندگان می توانند اشياء خود را در view state ذخيره نمايند . برای ذخيره يك آيتم در view state ، می بايست امكان تبديل آن به مجموعه ای از بايت ها وجود داشته باشد تا بتوان آن را در يك فيلد ورودی مخفی ذخيره كرد . به فرآيند فوق serialization می گويند . در صورتی كه اشياء تعريف شده توسط پياده كنندگان قابليت تبديل به مجموعه ای از بايت ها را نداشته باشند ( به صورت پيش فرض اين قابليت وجود ندارد ) ، در زمان استقرار آنها در view state يك پيام خطاء مواجه خواهيم شد.
برای ايجاد قابليت serializable در اشياء تعريف شده ، می بايست خصلت [Serializable] را به تعريف كلاس اضافه كرد .
كد زير نحوه انجام اين كار را نشان می دهد .


<Serializable()> _
Public Class Customer
Public FirstName As String
Public LastName As String
Public Sub New(ByVal firstName As String, ByVal lastName As String)
Me.FirstName = firstName
Me.LastName = lastName
End Sub
End Class
با توجه به اين كه در كلاس Customer خصلت serializable تعريف شده است ،‌ امكان ذخيره آن در view state وجود خواهد داشت .


Dim customer1 As New Customer("MyFirstName","MyLastName")
ViewState("CurrentCustomer") = customer1

در زمان استفاده از اشياء سفارشی ، پس از بازيابی داده از view state می بايست آنها را تبديل ( cast ) كرد.


Dim customer1 As Customer
customer1 = CType(ViewState("CurrentCustomer"), Customer)

aryaei2000
پنج شنبه 07 شهریور 1387, 01:13 صبح
آيا تمامی اشياء دات نت را می توان در view state ذخيره كرد ؟
پس از بررسی مستندات يك كلاس و با مشاهده خصلت [Serializable] ، امكان ذخيره شی مورد نظر در view state وجود خواهد داشت . در صورتی كه شی مورد نظر فاقد خصلت فوق باشد ، امكان ذخيره آن در view state وجود نخواهد داشت . در چنين مواردی می توان از روش های ديگر state management كه در بخش های بعدی به آنها اشاره خواهيم كرد، استفاده كرد.
يكی از مهمترين محدوديت های view state ، شعاع استفاده از اطلاعات ذخيره شده در آن توسط ساير صفحات وب است . اطلاعات ذخيره شده در view state صرفا" توسط صفحه ای كه آنها را ايجاد كرده است قابل استفاده خواهند بود و ساير صفحات قادر به استفاده از اطلاعات نخواهند بود . به عنوان مثال ، در صورتی كه كاربر به صفحه ای ديگر حركت و يا هدايت شود ، اطلاعات ذخيره شده در view state قابل دستيابی نبوده و عملا" از بين خواهند رفت . برای غلبه بر محدوديت فوق ، از روش های متعدد ديگری می توان استفاده كرد .