国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > .NET > 正文

ASP.NET2.0的控件狀態(tài)和視圖狀態(tài)探討

2024-07-10 13:10:30
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

商業(yè)源碼熱門(mén)下載www.html.org.cn

  基本概念

  控件狀態(tài)-為了讓控件正常工作,有時(shí)需要存儲(chǔ)控件狀態(tài)數(shù)據(jù)。例如,如果編寫(xiě)了一個(gè)自定義控件,其中具有顯示不同信息的不同選項(xiàng)卡,為使該控件如預(yù)期一樣工作,控件需要知道在往返過(guò)程中選擇的是哪個(gè)選項(xiàng)卡。viewstate 屬性可用于此目的,但開(kāi)發(fā)人員可能在頁(yè)級(jí)別關(guān)閉了視圖狀態(tài),從而有效地中斷控件。為解決此問(wèn)題,asp.net 頁(yè)框架在 asp.net 2.0 版中公開(kāi)了一種稱(chēng)為控件狀態(tài)的新功能。
controlstate 屬性允許保持特定于控件的屬性信息,不像 viewstate 屬性一樣可以關(guān)閉。若要使用控件狀態(tài),控件必須在初始化過(guò)程中調(diào)用 registerrequirescontrolstate 方法,然后重寫(xiě) savecontrolstate 和 loadcontrolstate 方法。

  視圖狀態(tài)-視圖狀態(tài)是 asp.net 頁(yè)框架默認(rèn)情況下用于保存往返過(guò)程之間的頁(yè)和控件值的方法。當(dāng)呈現(xiàn)頁(yè)的 html 形式時(shí),需要在回發(fā)過(guò)程中保留的頁(yè)的當(dāng)前狀態(tài)和值將被序列化為 base64 編碼的字符串,并輸出到視圖狀態(tài)的隱藏字段中。通過(guò)實(shí)現(xiàn)自定義的 pagestatepersister 類(lèi)以存儲(chǔ)頁(yè)數(shù)據(jù),您可以更改默認(rèn)行為并將視圖狀態(tài)存儲(chǔ)到另一個(gè)位置(如 sql server 數(shù)據(jù)庫(kù))。有關(guān)將頁(yè)狀態(tài)存儲(chǔ)到流上而不是隱藏的頁(yè)字段中的示例,請(qǐng)參見(jiàn) 視圖狀態(tài)持久性機(jī)制的示例。

  您可以通過(guò)使用頁(yè)的 viewstate 屬性將往返過(guò)程中的數(shù)據(jù)保存到 web 服務(wù)器來(lái)利用自己的代碼訪(fǎng)問(wèn)視圖狀態(tài)。viewstate 屬性是一個(gè)包含密鑰/值對(duì)(其中包含視圖狀態(tài)數(shù)據(jù))的字典。

  各自的優(yōu)勢(shì)與劣勢(shì)

  視圖狀態(tài)

  使用視圖狀態(tài)的優(yōu)點(diǎn):

  ·不需要任何服務(wù)器資源 視圖狀態(tài)包含在頁(yè)代碼內(nèi)的結(jié)構(gòu)中。

  ·實(shí)現(xiàn)簡(jiǎn)單 視圖狀態(tài)無(wú)需使用任何自定義編程。默認(rèn)情況下對(duì)控件啟用狀態(tài)數(shù)據(jù)的維護(hù)。

  ·增強(qiáng)的安全功能 視圖狀態(tài)中的值經(jīng)過(guò)哈希計(jì)算和壓縮,并且針對(duì) unicode 實(shí)現(xiàn)進(jìn)行編碼,其安全性要高于使用隱藏域。

  使用視圖狀態(tài)的缺點(diǎn)

  ·性能注意事項(xiàng) 由于視圖狀態(tài)存儲(chǔ)在頁(yè)本身,因此如果存儲(chǔ)較大的值,用戶(hù)顯示頁(yè)和發(fā)送頁(yè)時(shí)的速度可能會(huì)減慢。尤其是對(duì)移動(dòng)設(shè)備,其帶寬通常是有限的。

  ·設(shè)備限制 移動(dòng)設(shè)備可能沒(méi)有足夠的內(nèi)存容量來(lái)存儲(chǔ)大量的視圖狀態(tài)數(shù)據(jù)。

  ·潛在的安全風(fēng)險(xiǎn) 視圖狀態(tài)存儲(chǔ)在頁(yè)上的一個(gè)或多個(gè)隱藏域中。雖然視圖狀態(tài)以哈希格式存儲(chǔ)數(shù)據(jù),但它可以被篡改。如果直接查看頁(yè)輸出源,可以看到隱藏域中的信息,這導(dǎo)致潛在的安全性問(wèn)題。

  控件狀態(tài)

  使用控件狀態(tài)的優(yōu)點(diǎn):

  ·不需要任何服務(wù)器資源 默認(rèn)情況下,控件狀態(tài)存儲(chǔ)在頁(yè)上的隱藏域中。

  ·可靠性 因?yàn)榭丶顟B(tài)不像視圖狀態(tài)那樣可以關(guān)閉,控件狀態(tài)是管理控件的狀態(tài)的更可靠方法。

  ·通用性 可以編寫(xiě)自定義適配器來(lái)控制如何存儲(chǔ)控件狀態(tài)數(shù)據(jù)和控件狀態(tài)數(shù)據(jù)的存儲(chǔ)位置。

  使用控件狀態(tài)的缺點(diǎn):

  ·需要一些編程 雖然 asp.net 頁(yè)框架為控件狀態(tài)提供了基礎(chǔ),但是控件狀態(tài)是一個(gè)自定義的狀態(tài)保持機(jī)制。為了充分利用控件狀態(tài),您必須編寫(xiě)代碼來(lái)保存和加載控件狀態(tài)。

  控件狀態(tài)與視圖狀態(tài)示例

  此示例演示如何創(chuàng)建一個(gè)名為 indexbutton 的自定義控件,該控件使用控件狀態(tài)在多個(gè)頁(yè)請(qǐng)求間維護(hù)關(guān)鍵狀態(tài)信息。在 asp.net 2.0 版中引入的控件狀態(tài)與視圖狀態(tài)類(lèi)似,但功能上獨(dú)立于視圖狀態(tài)。網(wǎng)頁(yè)開(kāi)發(fā)人員可能會(huì)出于性能原因而禁用整個(gè)頁(yè)面或單個(gè)控件的視圖狀態(tài),但他們不能禁用控件狀態(tài)。控件狀態(tài)是專(zhuān)為存儲(chǔ)控件的重要數(shù)據(jù)(如一個(gè)頁(yè)面控件的頁(yè)數(shù))而設(shè)計(jì)的,回發(fā)時(shí)必須用到這些數(shù)據(jù)才能使控件正常工作(即便禁用視圖狀態(tài)也不受影響)。默認(rèn)情況下,asp.net 頁(yè)框架將控件狀態(tài)存儲(chǔ)在頁(yè)的一個(gè)隱藏元素中,視圖狀態(tài)也同樣存儲(chǔ)在此隱藏元素中。即使禁用視圖狀態(tài),或是使用 session 管理狀態(tài)時(shí),頁(yè)面中的控件狀態(tài)仍會(huì)傳輸至客戶(hù)端,然后返回到服務(wù)器。在回發(fā)時(shí),asp.net 會(huì)對(duì)隱藏元素的內(nèi)容進(jìn)行反序列化,并將控件狀態(tài)加載到每個(gè)注冊(cè)過(guò)控件狀態(tài)的控件中。

  此示例闡釋了一個(gè)同時(shí)在控件狀態(tài)和視圖狀態(tài)中保存狀態(tài)的自定義控件。在此示例中,indexbutton 控件派生自 button 類(lèi),還定義了一個(gè) index 屬性,并將該屬性保存在控件狀態(tài)中。為了進(jìn)行比較,indexbutton 還定義了一個(gè) indexinviewstate 屬性,該屬性存儲(chǔ)在 viewstate 字典中。為了了解控件狀態(tài)和視圖狀態(tài)之間的差異,請(qǐng)使用本文附帶的程序來(lái)演示 indexbutton 控件。

  indexbutton控件源碼

using system;
using system.componentmodel;
using system.security.permissions;
using system.web;
using system.web.ui;
using system.web.ui.webcontrols;

namespace customercontrols
{
 [
  aspnethostingpermission(securityaction.demand, level = aspnethostingpermissionlevel.minimal),
  aspnethostingpermission(securityaction.inheritancedemand, level = aspnethostingpermissionlevel.minimal),
  toolboxdata("<{0}:indexbutton runat=/"server/"> </{0}:indexbutton>")
 ]

 public class indexbutton : button
 {
  private int indexvalue;
  [
   bindable(true),
   category("behavior"),
   defaultvalue(0),
   description("the index stored in control state.")
  ]

 public int index
 {
  get
  {
   return indexvalue;
  }
  set
  {
   indexvalue = value;
  }
 }

 [
  bindable(true),
  category("behavior"),
  defaultvalue(0),
  description("the index stored in view state.")
 ]

 public int indexinviewstate
 {
  get
  {
   object obj = viewstate["indexinviewstate"];
   return (obj == null) ? 0 : (int)obj;
  }
  set
  {
   viewstate["indexinviewstate"] = value;
  }
 }

 protected override void oninit(eventargs e)
 {
  base.oninit(e);
  page.registerrequirescontrolstate(this);
 }

 protected override object savecontrolstate()
 {
  //調(diào)用基類(lèi)的方法,從基類(lèi)得到控件狀態(tài)的基值
  //如果indexvalue不等于并且基類(lèi)的控件狀態(tài)不為null
  //使用pair作為便利的數(shù)據(jù)結(jié)構(gòu)來(lái)高效保存(和在loadcontrolstate方法中還原)
  //由兩部分組成的控件狀態(tài)
  object obj = base.savecontrolstate();
  if (indexvalue != 0)
  {
   if (obj != null)
   {
    return new pair(obj, indexvalue);
   }
   else
   {
    return (indexvalue);
   }
  }
  else
  {
   return obj;
  }
 }

 protected override void loadcontrolstate(object state)
 {
  if (state != null)
  {
   pair p = state as pair;
   if (p != null)
   {
    base.loadcontrolstate(p.first);
    indexvalue = (int)p.second;
   }
   else
   {
    if (state is int)
    {
     indexvalue = (int)state;
    }
    else
    {
     base.loadcontrolstate(state);
    }
   }
  }
 }
}
}

  代碼討論

  indexbutton 控件的實(shí)現(xiàn)闡釋了三個(gè)任務(wù),必須執(zhí)行這三個(gè)任務(wù)才能使控件參與控件狀態(tài):

  · 重寫(xiě) oninit 方法并調(diào)用 registerrequirescontrolstate 方法向頁(yè)面注冊(cè),以參與控件狀態(tài)。必須針對(duì)每個(gè)請(qǐng)求完成此任務(wù)。

  · 重寫(xiě) savecontrolstate 方法,以在控件狀態(tài)中保存數(shù)據(jù)。

  · 重寫(xiě) loadcontrolstate 方法,以從控件狀態(tài)加載數(shù)據(jù)。此方法調(diào)用基類(lèi)方法,并獲取基類(lèi)對(duì)控件狀態(tài)的基值。如果 indexvalue 字段不為零,而且基類(lèi)的控件狀態(tài)也不為空,pair 類(lèi)便可作為方便的數(shù)據(jù)結(jié)構(gòu)使用,用來(lái)保存和還原由兩部分組成的控件狀態(tài)。

  分析總結(jié)

  從msdn上的一系列的技術(shù)參考來(lái)看,controlstate應(yīng)該是主要在自定義控件上使用,“asp.net 頁(yè)框架提供了 controlstate 屬性作為在服務(wù)器往返過(guò)程中存儲(chǔ)自定義控件數(shù)據(jù)的方法”,這是msdn上的原句,asp.net2.0只是為controlstate提供了一個(gè)基礎(chǔ),當(dāng)controlstate是一個(gè)自定義的狀態(tài)保持機(jī)制,也就是說(shuō)保持狀態(tài)的機(jī)制需要你開(kāi)發(fā)人員自己去完成,而不像viewstate,它有自己默認(rèn)的狀態(tài)保持機(jī)制。在自定義控件使用controlstate也許才是微軟本意了,為的就避免在頁(yè)面級(jí)別禁用掉viewstate后,自定義控件還能正常運(yùn)行。當(dāng)然這里的意思就是,某些控件的正確運(yùn)行是依賴(lài)于它的狀態(tài)信息的,在asp.net1.1中,如果禁用了viewstate,這樣的控件就無(wú)法正確運(yùn)行了。但引入了controlstate后就不同了,因?yàn)閏ontrolstate是禁用不掉的。
 
  所以微軟才提醒開(kāi)發(fā)人員“請(qǐng)僅對(duì)那些在回發(fā)過(guò)程中對(duì)控件至關(guān)重要的少量關(guān)鍵數(shù)據(jù)使用控件狀態(tài),而不要將控件狀態(tài)作為視圖狀態(tài)的備用選項(xiàng)使用”。明確說(shuō)出,controlstate和viewstate完全是兩個(gè)東西,雖然它們可以完成相同的任務(wù),新推出的controlstate既不是用來(lái)替代viewstate也不是用來(lái)做viewstate的替補(bǔ)。它的使命是彌補(bǔ)viewstate的所不能完成的任務(wù),讓開(kāi)發(fā)人員開(kāi)發(fā)出更加健壯的控件。例如說(shuō),開(kāi)發(fā)的自定義控件某個(gè)狀態(tài)是至關(guān)重要的,缺少它就自定義控件不能正常工作,那么controlstate就該上場(chǎng)了。而且controlstate是自定義的狀態(tài)保持機(jī)制,也限制了controlstate自由的使用,你不但要在oninit 方法并調(diào)用 registerrequirescontrolstate 方法向頁(yè)面注冊(cè),而且要重寫(xiě)saveadaptercontrolstate(),loadadaptercontrolstate(object state)兩個(gè)方法自己去實(shí)現(xiàn)要保存什么,怎樣保存。根據(jù)我現(xiàn)在的理解,如果你需要保存該控件的10種不同狀態(tài),那你就得一一保存,再一一加載上去。從這點(diǎn)也就看出了微軟的初衷了,那不是很明顯嗎,如果不需要controlstate那就不使用它吧,否則怎么它什么都讓我們開(kāi)發(fā)人員去做呢?

  這只是基礎(chǔ)了,剛才我說(shuō)了,似乎微軟也是這么說(shuō)的,controlstate針對(duì)的是自定義控件,其實(shí)我們真的要去開(kāi)啟基本控件例如label控件的controlstate,微軟也是允許的,這就是稍深的內(nèi)容了,這就涉及到控件適配器了(controladapter)。如果需要了解這方面的內(nèi)容,請(qǐng)看用控件適配器開(kāi)啟基本控件的controlstate。http://sifang2004.cnblogs.com/archive/2006/06/01/415288.html

  附錄

  為了更加充分理解上面的內(nèi)容,需要對(duì)以下內(nèi)容有個(gè)了解:

  pair 類(lèi)

  用作存儲(chǔ)兩個(gè)相關(guān)對(duì)象的基本結(jié)構(gòu)。它是在整個(gè) asp.net 中(在如頁(yè)面狀態(tài)管理任務(wù)期間或配置節(jié)處理程序的過(guò)程中)有多種用法的實(shí)用工具類(lèi)。可以在自己的代碼中需要包含兩個(gè)相關(guān)對(duì)象的結(jié)構(gòu)的任意位置和不一定需要數(shù)據(jù)綁定的位置使用 pair 類(lèi)。pair 類(lèi)不將其對(duì)象引用 first 和 second 封裝在屬性中;該類(lèi)直接將它們作為公共類(lèi)字段公開(kāi)到所有調(diào)用代碼。

  pair 類(lèi)在頁(yè)狀態(tài)保留實(shí)現(xiàn)中有多種用法。最常見(jiàn)的用法是同時(shí)作為 viewstate 和 controlstate 集合的容器。在這種情況下,first 屬性用于 viewstate,而 second 用于 controlstate。

  pagestatepersister 類(lèi)

  http 請(qǐng)求和響應(yīng)原本是無(wú)狀態(tài)的。要在 http 請(qǐng)求之間保持狀態(tài)信息,asp.net 服務(wù)器頁(yè)可以存儲(chǔ) page 狀態(tài)。此狀態(tài)稱(chēng)為視圖狀態(tài),它包含頁(yè)和控件設(shè)置及數(shù)據(jù),這些設(shè)置和數(shù)據(jù)使得頁(yè)和控件看起來(lái)就像在上一次將它們提交到服務(wù)器然后又返回到客戶(hù)端時(shí),用戶(hù)所看到并與之交互的頁(yè)和控件一樣。有幾種機(jī)制可在對(duì)相同頁(yè)的連續(xù)請(qǐng)求之間存儲(chǔ)視圖狀態(tài)。pagestatepersister 抽象類(lèi)表示這些狀態(tài)信息存儲(chǔ)機(jī)制的基類(lèi)。

  要在不能支持現(xiàn)有視圖狀態(tài)持久性機(jī)制的客戶(hù)端上保留視圖狀態(tài),可以擴(kuò)展 pagestatepersister 類(lèi),引入您自己的視圖狀態(tài)持久性方法,并且可以使用頁(yè)適配器將 asp.net 應(yīng)用程序配置為根據(jù)為其提供頁(yè)的客戶(hù)端的類(lèi)型使用不同的視圖狀態(tài)持久性機(jī)制。從 pagestatepersister 類(lèi)派生的類(lèi)必須重寫(xiě) save 抽象方法,以便在持久性介質(zhì)中存儲(chǔ)視圖狀態(tài)和控件狀態(tài),同時(shí)重寫(xiě) load 方法以提取狀態(tài)信息。如果想知道如何寫(xiě)pagestatepersister的派生類(lèi),請(qǐng)參考視圖狀態(tài)持久性機(jī)制。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 盐池县| 江口县| 兴隆县| 东乡县| 宁明县| 体育| 宽城| 龙泉市| 苍南县| 霍山县| 临沂市| 扎兰屯市| 宣城市| 紫云| 维西| 英德市| 嘉兴市| 兰溪市| 休宁县| 漾濞| 寻乌县| 天峻县| 修文县| 施甸县| 黎城县| 五河县| 高唐县| 荔波县| 西藏| 大厂| 玉门市| 汾阳市| 安国市| 盖州市| 东辽县| 黄骅市| 来宾市| 额济纳旗| 应城市| 且末县| 日照市|