State Management در ASP. NET 2.0 (بخش اول)
يكي از مهمترين تفاوت هاي موجود بين برنامه هاي وب و Desktop ، مديريت state است كه در آن مي بايست به اين پرسش پاسخ داده شود كه نحوه نگهداري اطلاعات در ارتباط با كاربر جاري به چه صورت است ؟
در يك برنامه سنتي ويندوز ، state بطور اتوماتيك مديريت مي گردد . حافظه به حد فراوان يافت مي شود و همواره در دسترس است . در برنامه هاي وب داستان بگونه اي ديگر است . هزاران كاربر ممكن است بطور همزمان برنامه اي مشابه را بر روي كامپيوتري يكسان ( سرويس دهنده وب ) اجراء و هر يك از آنان از طريق پروتكل HTTP ( برگرفته شده از Hypertext Transfer Protocol) كه داراي ماهيتي stateless است با سرويس دهنده وب ارتباط برقرار نمايند . مجموعه شرايط فوق باعث شده است كه نتوان برنامه هاي وب را با سناريوئي دقيقا" مشابه با برنامه هاي سنتي ويندوز طراحي و پياده سازي كرد .
هيچگونه فريمورك برنامه نويسي وب ، صرفنظر از ميزان پيشرفته بودن آن ، نمي تواند ماهيت stateless بودن پروتكل HTTP را تغيير دهد. پس از هر درخواست و پاسخ به آن ، ارتباط منطقي سرويس گيرنده با سرويس دهنده قطع خواهد شد . معماري فوق ، اين اطمينان را ايجاد مي نمايد كه برنامه هاي وب بتوانند به هزاران كاربر بطور همزمان و بدون نگراني در خصوص حافظه پاسخ دهند . استفاده از روش هاي مختلف براي ذخيره اطلاعات بين درخواست هاي متعدد يك كاربر و بازيابي آنها در زماني كه به آنها نياز است از جمله مشكلات معماري فوق براي پياده كنندگان برنامه هاي وب محسوب مي گردد .
آشنائي و درك مناسب نسبت به محدوديت هاي state ، يكي از مفاهيم كليدي در زمان ايجاد برنامه هاي وب كارآ و قدرتمند است .
در مجموعه مقالاتي كه در اين خصوص آماده و بتدريج بر روي سايت منتشر خواهد شد به بررسي موارد زير خواهيم پرداخت :
- آشنائي با مفاهيم ، جايگاه و لزوم مديريت state در برنامه هاي وب
- آشنائي با پتانسيل هاي ارائه شده در ASP. NET 2.0 براي ذخيره سازي و مديريت اطلاعات
- آشنائي با گزينه هاي متفاوت موجود به منظور مديريت state نظير View state ، Session state ، كوكي هاي سفارشي
- نحوه انتقال اطلاعات از يك صفحه به صفحه ديگر
مديريت state و مسائل در ارتباط با آن
در يك برنامه سنتي ويندوز ، كاربران با يك برنامه در حال اجراء بطور پيوسته ارتباط برقرار مي نمايند . بخشي از حافظه موجود بر روي كامپيوتر Desktop براي ذخيره تنظيمات جاري اطلاعات محيط كار كاربر اختصاص داده مي شود .
در يك برنامه وب ، داستان كاملا" متفاوت است . شايد از ديد كاربران يك سايت حرفه اي اينگونه برداشت شود كه يك برنامه بطور مستمر در حال اجراء است و به آنان سرويس هاي لازم را مي دهد . علي رغم اين كه ظاهر موضوع درست بنظر مي آيد ولي در پس پرده داستان بگونه اي ديگر دنبال مي شود . برنامه هاي وب از يك الگوي دستيابي غيرمتصل كارآ استفاده مي نمايند . در اين الگو ، سرويس گيرنده پس از ارتباط با سرويس دهنده از آن درخواست يك صفحه را مي نمايد . پس از پاسخ به سرويس گيرنده ،ارتباط منطقي ايجاد شده قطع و سرويس دهنده بي خيال هر گونه اطلاعاتي در رابطه با سرويس گيرنده مي گردد . پس از دريافت صفحه درخواستي توسط سرويس گيرنده ، برنامه اجراء خود را متوقف و ASP.NET engine اشياء مربوط به صفحه را دور مي اندازد .
با توجه به اين كه سرويس گيرندگان لازم است در اكثر موارد صرفا" براي چندين ثانيه متصل باشند ، يك سرويس دهنده وب مي تواند به هزاران درخواست با كارآئي مطلوب پاسخ دهد .
در صورتي كه لازم است اطلاعات بين چندين عمليات كاربر نگهداري شوند ، مي بايست از راهكارهاي مختلفي به منظور مديريت state استفاده كرد .
View state
همانگونه كه اطلاع داريد كنترل هاي سرويس دهنده ASP.NET از view state براي بخاطر سپردن state استفاده مي نمايند . اطلاعات view state در يك فيلد مخفي نگهداري شده و بطور اتوماتيك پس از هر postback براي سرويس دهنده ارسال مي گردد . view state محدود به كنترل هاي سرويس دهنده نمي گردد و در صورت ضرورت مي توان مجموعه اي از اطلاعات مورد نياز را مستقيما" در مجموعه view state ذخيره تا امكان بازيابي آنها پس از هر postback فراهم شود . نوع هاي مختلفي را مي توان در view state ذخيره نمود . نوع هاي داده ساده و اشياء سفارشي نمونه هائي در اين زمينه مي باشند .
خصلت ViewState صفحه، مجموعه view state را ارائه مي نمايد . اين خصلت يك نمونه از كلاس مجموعه StateBag است .براي اضافه كردن و حذف آيتم هائي در اين كلاس ، از گرامري مشابه با يك ديكشنري استفاده مي گردد كه در آن هر آيتم داراي يك نام منحصر بفرد است .
كد زير نحوه استفاده از view state را نشان مي دهد .
دستور فوق ، مقدار 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 در برنامه هاي وب به بررسي يك نمونه مثال كاربردي خواهيم پرداخت .
مثال : ثبت تعداد دفعاتي كه بر روي يك دكمه كليك مي گردد
كد زير يك برنامه ساده شمارنده را نشان مي دهد كه در آن تعداد دفعاتي كه بر روي يك دكمه كليك مي شود تشخيص داده شده و تعداد آن در خروجي نمايش داده مي شود . بدون استفاده از يك راهكار مناسب براي مديريت 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> </div> </form> </body> </html> |
در كد فوق قبل از تلاش براي بازيابي آيتم مورد نظر از view state ، وجود آن در ساختار فوق بررسي مي گردد . شكل 1 خروجي برنامه فوق را نشان مي دهد .
شكل 1 : استفاده از view state براي نگهداري مقدار counter
براي حل مسئله مديريت state در مثال فوق و نگهداري مقدار counter در بين چندين postback از روش هائي ديگر نيز مي توان استفاده كرد . به عنوان مثال ، مي توان براي كنترل سرويس دهنده label ويژگي view state را فعال و از label براي ذخيره مقدار counter استفاده نمود . هر مرتبه كه بر روي دكمه "افزايش شمارنده " كليك گردد ، مقدار جاري از طريق خصلت text كنترل label بازيابي و پس از تبديل به يك عدد صحيح در خروجي نمايش داده مي شود .
از روش فوق نمي توان همواره به عنوان يك راهكار مناسب استفاده كرد . مثلا" ممكن است قصد ايجاد برنامه اي را داشته باشيم كه تعداد دفعاتي را كه بر روي يك دكمه كليك مي گردد ثبت نمايد ولي قصد نمايش نتايج را در خروجي نداشته باشيم . در چنين مواردي مي توان همچنان اطلاعات را در يك كنترل سرويس دهنده ذخيره نمود ولي مجبور خواهيم بود كه آن را مخفي نگاه داريم .
پس از انجام تمامي اين كارها ، به چيزي مي رسيم كه view state آن را در اختيار ما قرار مي دهد . view state ، اطلاعات را بطور اتوماتيك در يك فيلد مخفي خاص در صفحه نگهداري مي نمايد . با توجه به اين كه ASP. NET با جزئيات اين كار سروكار دارد ، كد نوشته شده توسط پياده كنندگان از خوانائي بيشتري برخوردار خواهد بود .
در بخش دوم به بررسي نحوه ايمن سازي اطلاعات ذخيره شده در view state خواهيم پرداخت .
برگرفته از سايت سخا روش