مقدمة
طالما أن لديك القليل من الفهم لـ ViewState، ستعرف أن ViewState في صفحات Asp.net يتم تخزينها بشكل عام في حقل مخفي من الصفحة:
عندما نتصفح الملف المصدر للصفحة، نرى الكثير من الأشياء الفوضوية (خاصة عندما تحتوي الصفحة على DataGrid بكمية كبيرة من البيانات، أو GridView في ASP.NET 2.0). الوقت، وهذا هو ViewState.
المعرفة الأساسية
نظرًا لوجود بعض التغييرات الجديدة في آلية تخزين الثبات لـ ViewState في ASP.NET 2.0، سأقدم بإيجاز الأشياء ذات الصلة.
في ASP.NET 1.1، يتم توفير آلية استمرار المجال المخفي للصفحة فقط، لذلك في بعض الحالات، يتعين عليك التخلي عن استخدام ViewState. تخيل لو كان هناك عشرات الآلاف من السجلات في DataGrid (لا تفكر في ذلك). هذا غير طبيعي) ليست هناك حاجة (واجهه شخص ما). إذا تم تمكين ViewState، فهل أنت متأكد من أن خادم IIS الخاص بك يمكنه تحمله وهل يمكن للشبكة تحمله؟ بالطبع، يمكنك تغيير آلية التخزين الخاصة بك عن طريق تجاوز طريقة Page.SavePageStateToPersistenceMedium()، لكن لا تنس تجاوز Page.LoadPageStateFromPersistenceMedium()، فهما زوج.
لا تزال آلية استمرار حالة العرض الافتراضية في ASP.NET 2.0 تحتفظ بمعلومات الحالة كسلسلة مشفرة بـ Base64 في عنصر HTML مخفي على الصفحة (عنصر مع سمة النوع المعينة على "مخفي"). تستخدم صفحات ASP.NET كائن HiddenFieldPageStatePersister لتنفيذ هذا العمل ومثيل IStateFormatter لإجراء تسلسل وإلغاء تسلسل معلومات حالة الكائن. أو، بالنسبة لعملاء الأجهزة المحمولة ذوي النطاق الترددي والموارد المحدودة، يمكنك أيضًا استخدام فئة SessionPageStatePersister لتخزين حالة عرض الصفحة في كائن الجلسة على الخادم حالة الصفحة في الجلسة وليس في الصفحة، وهو توفير النطاق الترددي.
ولكن إذا كنت ترغب في الحصول على فهم أعمق لآلية استمرارية ViewState، فيجب أن تعرف عن الفئة المجردة PageStatePersister للاحتفاظ بحالة العرض على عميل لا يمكنه دعم آلية استمرارية حالة العرض الحالية، يمكنك توسيع فئة PageStatePersister وتقديم الخاص بك. طريقة العرض الخاصة، ويمكنك استخدام محولات الصفحة لتكوين تطبيقات ASP.NET لاستخدام آليات استمرار حالة العرض المختلفة بناءً على نوع العميل الذي يتم تقديم الصفحة إليه. يجب أن تتجاوز الفئات المشتقة من فئة PageStatePersister طريقة الحفظ الملخص لتخزين حالة العرض وحالة التحكم في وسط الثبات، وتجاوز طريقة التحميل لاستخراج معلومات الحالة. إذا كنت بحاجة إلى إجراء تسلسل لحالة العرض وحالة التحكم في سلاسل، فيمكنك استخدام كائن IStateFormatter الذي يتم الوصول إليه من خلال خاصية StateFormatter. يقوم بإجراء تسلسل وإلغاء تسلسل معلومات حالة الكائن بكفاءة إلى سلاسل Base64 المشفرة. يمكنك أيضًا تجاوز خاصية StateFormatter لتوفير آلية تسلسل حالة الكائن الخاصة بك، وهي موضحة في الكود الخاص بي، وسوف تفهم ذلك بعد إلقاء نظرة.
لن يتم تقديمالحقل المخفي
لآلية استمرار ViewState
، وهذا هو الحقل الافتراضي. كما جاء في المقدمة.
تحتاجالجلسة
فقط إلى تجاوز خاصية PageStatePersister في ASP.NET2.0.
تجاوز محمي PageStatePersister PageStatePersister
{
يحصل
{
إرجاع جلسة جديدة PageStatePersister(Page);
}
}
إذا كنت بحاجة إلى تجاوز هاتين الطريقتين الخاصتين بـ LoadPageStateFromPersistenceMedium في ASP.NET1.1:
كائن التجاوز المحمي LoadPageStateFromPersistenceMedium()
{
إرجاع الجلسة["ViewState"];
}
تجاوز محمي باطلة SavePageStateToPersistenceMedium (حالة عرض الكائن)
{
جلسة["ViewState"] = viewState;
RegisterHiddenField("__VIEWSTATE", "");
}
قاعدة البيانات (مثالي هو SQL Server2000)
موجودة في ASP1.1. يرجى الانتباه إلى السطر الأرجواني أدناه. لقد جعلني أشعر بالاكتئاب لعدة أيام . تم نسخ الكود التالي للتو من كود المصدر الخاص بي، وليس عليك كتابته بهذه الطريقة على الإطلاق، باستثناء ما هو ضروري.
تجاوز محمي باطلة SavePageStateToPersistenceMedium (حالة الكائن)
{
string viewStateID = "VIEWSTATE#" + Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
ClientScript.RegisterHiddenField("__VIEWSTATE_KEY"، viewStateID);
ClientScript.RegisterHiddenField("__VIEWSTATE"،"");// يرجى ملاحظة
المحاولة
{
إذا (losFormatter == فارغة)
{
losFormatter = new LosFormatter();
}
StringWriter sw = new StringWriter();
losFormatter.Serialize(sw,state);
Common.ViewStateData vsd = new ViewStateData();
vsd.ViewStateID = viewStateID;
vsd.ViewState = sw.ToString();
da = new DataAccess();
خطأ في السلسلة = da.SaveViewState(vsd);
الاستجابة. الكتابة (خطأ)؛
}
قبض (استثناء على سبيل المثال)
{
Response.Write(ex.Message);
}
}
كائن التجاوز المحمي LoadPageStateFromPersistenceMedium()
{
string viewState = string.Empty;
يحاول
{
إذا (losFormatter == فارغة)
{
losFormatter = new LosFormatter();
}
string StateID = Page.Request["__VIEWSTATE_KEY"].ToString();
da = new DataAccess();
viewState = da.LoadViewState(stateID);
}
يمسك
{}
إرجاع losFormatter.Deserialize(viewState);
}
هذا السطر من التعليمات البرمجية جيد بشكل أساسي في ASP2.0. لماذا هو أساسي؟ لأنه السطر أعلاه ClientScript.RegisterHiddenField("__VIEWSTATE"،"")؛
سواء كان هذا السطر موجودًا أم لا، فهو نفسه في Asp .net1.1 هذا ممكن. لقد أشرت أيضًا إلى كود أشخاص آخرين وأضفت هذا السطر، بعد إضافة هذا السطر، لا يوجد سوى في
الصفحة.
يوجد شيئان منهذا
القبيل في الملف المصدر للصفحة بعد التشغيل. لا بأس بإزالة هذا السطر، لذلك لا أفهم الغرض من استخدام العبارة من فضلك قل لي بوضوح. ولكنها لا تعمل في Asp.net2.0. هناك الخطأ التالي:
معلومات الحالة لهذه الصفحة غير صالحة وربما تكون تالفة.
على أية حال، كنت في حيرة من أمري في ذلك الوقت، ولم أواجه مثل هذا الخطأ من قبل. ولا يمكنني العثور على أي شيء من خلال البحث في Google، نعم، لا أعرف ما إذا كانت هذه الجملة خاطئة أم لا حفظ حالة العرض في قاعدة البيانات وقراءتها من قاعدة البيانات، لم أتمكن من العثور على الخطأ، لذلك فكرت في الكود مرارًا وتكرارًا، لكنني كنت في حيرة من أمري بشأن هذا السطر حقل "__VIEWSTATE"، لذلك علقت على هذا السطر، وقد نجح بالفعل، لذلك ما زلت لا أفهم الغرض من هذا السطر.
بالطبع، يمكننا أيضًا إكمال الوظائف المذكورة أعلاه عن طريق كتابة فئة فرعية جديدة من PageStatePersister، وهي جديدة في ASP.NET2.0:
namespace PageAdapter
{
باستخدام النظام؛
باستخدام System.IO؛
باستخدام System.Security.Permissions؛
باستخدام System.Web؛
باستخدام System.Web.UI؛
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
الفئة العامة DatabasePageStatePersister: PageStatePersister
{
DatabasePageStatePersister العامة (صفحة الصفحة): القاعدة (الصفحة)
{}
//
// تحميل حالة العرض وحالة التحكم.
//
التجاوز العام تحميل باطل ()
{
حالة عرض السلسلة؛
IStateFormatter formatter = this.StateFormatter;
DataAccess da = new DataAccess();
معرف حالة السلسلة = base.Page.Request["__VIEWSTATE_KEY"].ToString();
viewState = da.LoadViewState(stateID);
زوج الحالة زوج = (زوج)formatter.Deserialize(viewState);
ViewState =statePair.First;
ControlState =statePair.Second;
}
//
// استمر في أي حالة ViewState وControlState.
//
التجاوز العام باطل حفظ ()
{
إذا (ViewState != null || ControlState != null)
{
إذا (Page.Session ! = فارغة)
{
string viewStateID = "VIEWSTATE#" + base.Page.Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY"، viewStateID);
زوج الحالة = زوج جديد (ViewState، ControlState)؛
IStateFormatter formatter = this.StateFormatter;
// إجراء تسلسل لكائن StatePair إلى سلسلة
string serializedState = formatter.Serialize(statePair);
ViewStateData vsd = new ViewStateData();
vsd.ViewStateID = viewStateID;
vsd.ViewState = serializedState;
DataAccess da = new DataAccess();
خطأ في السلسلة = da.SaveViewState(vsd);
}
آخر
throw new InvalidOperationException("الجلسة مطلوبة لـ StreamPageStatePersister.");
}
}
}
}
ثم يمكنك تجاوز خاصية PageStatePersister:
تجاوز محمي PageStatePersister PageStatePersister
{
يحصل
{
إرجاع DatabasePageStatePersister(Page);
}
الملف
لا يختلف كثيرًا عن قاعدة البيانات، وأنا أتحدث فقط عن ASP.NET2.0، ويجب أن يكون مشابهًا في ASP.NET1.1، لكنني لم أكتب رمز التصحيح:
ما زلت أستخدم الطريقة. لكتابة فئة فرعية جديدة من PageStatePersister:
مساحة الاسم StreamPageAdapter
{
باستخدام النظام؛
باستخدام System.IO؛
باستخدام System.Security.Permissions؛
باستخدام System.Web؛
باستخدام System.Web.UI
؛
// يعد StreamPageStatePersister مثالاً لحالة العرض
// آلية الثبات التي تحافظ على العرض والتحكم
// الحالة على خادم الويب.
//
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
الفئة العامة StreamPageStatePersister: PageStatePersister
{
StreamPageStatePersister العامة (صفحة الصفحة): القاعدة (الصفحة)
{}
//
// تحميل حالة العرض وحالة التحكم.
//
التجاوز العام تحميل باطل ()
{
Stream StateStream = GetSecureStream();
// اقرأ سلسلة الحالة باستخدام StateFormatter.
قارئ StreamReader = new StreamReader(stateStream);
IStateFormatter formatter = this.StateFormatter;
سلسلة fileContents = Reader.ReadToEnd();
// يقوم Deserilize بإرجاع كائن الزوج الذي تم إجراء تسلسل فيه
// طريقة الحفظ.
زوج الحالة زوج = (زوج)formatter.Deserialize(fileContents);
ViewState =statePair.First;
ControlState =statePair.Second;
Reader.Close();
StateStream.Close();
}
//
// استمر في أي حالة ViewState وControlState.
//
التجاوز العام باطل حفظ ()
{
إذا (ViewState != null || ControlState != null)
{
إذا (Page.Session ! = فارغة)
{
Stream StateStream = GetSecureStream();
StreamWriterwriter = new StreamWriter(stateStream);
IStateFormatter formatter = this.StateFormatter;
Pair StatePair = new Pair(ViewState, ControlState);
// تسلسل كائن StatePair إلى سلسلة.
string serializedState = formatter.Serialize(statePair);
Writer.Write(serializedState);
الكاتب. إغلاق ()؛
StateStream.Close();
}
آخر
throw new InvalidOperationException("الجلسة مطلوبة لـ StreamPageStatePersister.");
}
}
// قم بإرجاع دفق آمن لبيئتك
Private Stream GetSecureStream().
{
مسار السلسلة = @"d:a.txt";
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
عودة خ م؛
}
}
}
ما عليك سوى تجاوز خاصية PageStatePersister:
تجاوز محمي PageStatePersister PageStatePersister
{
يحصل
{
إرجاع StreamPageStatePersister الجديد (Page })
;
من خلال المقدمة الموجزة أعلاه، يجب أن يكون لدينا بعض الفهم، ولكن ما نحتاج إلى فهمه هو: في ASP.NET1.1 لا يمكننا إكمال الوظائف المذكورة أعلاه إلا عن طريق إعادة كتابة age.SavePageStateToPersistenceMedium() وPage.LoadPageStateFromPersistenceMedium(); .NET1.1 في ASP.NET2.0، بالإضافة إلى ذلك، قمنا بإكمال ذلك أيضًا عن طريق كتابة فئة فرعية جديدة من PageStatePersister وتجاوز خاصية PageStatePersister بالطبع، إذا قرأت المحتوى التالي ستفهم أن كتابة فئة فرعية جديدة من PageStatePersister ذات فائدة حقيقية.
استخدام محول الصفحة
نظرًا لأن آلية استمرار الحالة مرتبطة بالعرض التكيفي والوظائف من جانب العميل، يتم توفير MyPageAdapter لتنشيط DatabasePageStatePersister لتطبيق ASP.NET. وأخيرًا، يتم توفير ملف قدرات المستعرض (.browser) لتمكين MyPageAdapter لفئة معينة من العملاء (في هذه الحالة، مستعرض الويب الافتراضي).
للاطلاع على هذه المحتويات، يرجى الاطلاع على مشروع PageAdapter في الكود المصدري الذي قدمته. سوف تفهم بعد قراءتها.
باستخدام System.Security.Permissions؛
باستخدام System.Web؛
باستخدام System.Web.UI؛
مساحة الاسم PageAdapter
{
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
الفئة العامة MyPageAdapter: System.Web.UI.Adapters.PageAdapter
{
التجاوز العام PageStatePersister GetStatePersister()
{
إرجاع PageAdapter.DatabasePageStatePersister الجديد (Page)؛
}
}
}
أخيرًا، لتمكين محول MyPageAdapter، يجب عليك إنشاء دليل يسمى App_Browsers في الدليل الجذر لتطبيق ASP.NET وتضمين ملف .browser يحتوي على معلومات التكوين (في الواقع، تتم إضافة كل هذه المعلومات عند إضافتها إلى المشروع سيتم إكمال ملف .browser لك تلقائيًا بحلول vs2005. يشير عنصر
<مرجع المتصفح='الافتراضي' >
< محولات التحكم >
< محول
controlType = "System.Web.UI.Page"
محول نوع = "PageAdapter.MyPageAdapter" />
</محولات التحكم>
</المتصفح>
</المتصفحات>
يمكن رؤية ذلك في مشروع TestPageAdapter في الكود المصدري. يتم استخدام هذا المشروع لتوضيح محول الصفحة.
الاستنتاج
بسيط نسبيًا، وقد لا يكون واضحًا جدًا، أما بالنسبة لمزايا وعيوب آليات الثبات المختلفة، فلم أختبرها على وجه التحديد، والعنصر الأخير "استخدام محول الصفحة" ليس آلية ثبات، ولكنه يستخدم محولًا. ، لذلك لن نتجاوز
سمة PageStatePersister. يبدو لي أنها ليست مفيدة جدًا، لأنه يمكننا وضع إجراء تجاوز PageStatePersister في الفئة الأساسية للصفحة، ويمكن لجميع الصفحات الأخرى أن ترث هذه الفئة الأساسية كيف هو الحال في الكود الخاص بي، من الصعب استخدام محول الصفحة هذا. بالطبع، لا أعرف الكثير عن محول الصفحة.
بالإضافة إلى ذلك، شرح موجز عن كود المصدر الخاص بي:
1. مشروع PageAdapter
DatabasePageStatePersister.cs: فئة فرعية من فئة PageStatePersister MyPageAdapter.cs: محول الصفحة DataAccess.cs والوصول إلى قاعدة بيانات ViewSate.cs، ينتمي إلى الفئة المساعدة.
2. مشروع StreamPageAdapter
مشابه للمشروع المذكور أعلاه، لذلك لن أخوض في التفاصيل
3. مشروع SaveStateToDatabase
StateInHiddenField.aspx: اختبر آلية التخزين الافتراضية، أي أنه يمكنك رؤية الكثير من الأشياء الفوضوية عندما تنظر إليها. الملف المصدر للصفحة.
StateInSession.aspx: آلية التخزين هي الجلسة
StateInDatabase.aspx: قاعدة بيانات آلية التخزين هي نوع طريقة إعادة الكتابة التي يمكن استخدامها بواسطة asp.net1.1 و2.0.
StateInDatabase2.aspx: اكتب فئة فرعية جديدة من PageStatePersister وتجاوز خاصية PageStatePersister.StateInFile.aspx
: احفظ ViewState في مجلد على الخادم.
4. مشروع TestPageAdater.
تستخدم للاختبار والمحولات.