如果我們的伺服器控制項需要較完備的GUI,譬如需要控制HTML元素的附加屬性字型、顏色、高度等,那麼應當從Control的子類WebControl繼承,以得到所需的基礎效能。從WebControl類派生,需要遵守通常如下的約定:
1、 包含從System.Web.UI.WebControl的命名空間的引用
2、 不能夠重載Render方法直接向輸出資料流提供資料,而應當重載RenderContents方法來實現
3、 通常情況下,WebControl的衍生類別最終在輸出資料流中表現為<span>標籤,但是如果自己希望使用其它的標籤,就應當重載WebControl的tagKey屬性或者TagName屬性。
經驗(或者說MS建議):
1、 如果控制項產生非可視化元素或顯示給非HTML用戶端,那麼應當選用Control作為符類繼承。如<meta><xml>等標籤
2、 提供HTML介面的從WebControl繼承
3、 擴充修改功能時應當從一個已存控制項派生,但是不要從System.Web.UI.HtmlControls命名空間派生,因為vs.net設計器不承認從該類派生的控制項
為了能夠支援設計器,實現設計期,那麼需要考慮attribute(中繼資料)的編程。
檢視狀態
web編程很重要的一個方面是狀態管理,也就是解決在無狀態的http協議基礎上的狀態管理問題。在asp類web編程技術時代,這通常通過以下技術手段來解決:
1、 Session
2、 Cookies
3、 隱藏變數
4、 URL攜參
然而,以上方案都有自身的缺陷,譬如Session不宜擴充,Cookies在特定情況下可能不可用,隱藏變數不易管理,URL攜參有長度限制且容量有限。。。
綜合考慮,MS提出了基於隱藏變數方案的ViewState(視圖)的概念,通過視圖儲存2個asp.net頁間的伺服器端控制項狀態。視圖是如何工作的呢?
在處理一個Web請求後,頁面架構會收集頁面控制項樹中所有控制項的狀態並且建立一個視圖對象。每一個Control都有一個ViewState字典儲存自己的狀態,當輸出html到客戶時將全部ViewState進行序列化為一個字串運算式,作為隱含變數發送到用戶端,通常情況下我們將視圖的序列化子符串在伺服器同用戶端間進行傳遞,上一個請求的隱含變數會回傳到伺服器端進行並行化,然後“還原”給伺服器控制項。本質上,是一個隱含變數,但是在隱含變數基礎上加入了asp.net的管理功能,這就是視圖的本質。
Control的EnableViewState決定了控制項是否同意將自己的狀態交給自動化的視圖管理。
當一個控制項需要儲存狀態時候,沒人可以支援儲存的屬性為int32 boolean 等“簡單原生”資料類型。如果是較為複雜的屬性值類型,需要編程者提供類型轉換器,將值資料轉換為字串,若未提供,那麼採用代價高昂的二進位序列化功能(逐個byte的進行)。視圖資料在傳遞過程中通過傳遞一個附加的摘要來確保資料不被篡改(但無法保證不被窺探,畢竟base64編碼近乎明文)。