在製作控制項的時候容易遇到“呈現控制項時出錯”“發生了未處理的異常。未將對象引用設定到對象的執行個體。”這樣的錯誤,如:(也有可能僅僅只是因為未設定runat="server"標籤而導致該錯誤,請先檢查該項。)
但是在編譯時間/運行時也都是沒有錯誤的。
分析
的情況我們稱之為“設計時”以區別於“編譯時間”/“運行時”。
設計時:在ASP.NET環境中也就是當我們在Visual Studio中使用網頁設計器進行編輯的時候。直接的理解就是在ASPX頁面切換到“設計”的時候。
編譯時間:直接的理解就是當你進行編譯的時候,通常這個時候的錯誤是由類型檢查,參數匹配等顯式可直接通過文法約束所限制的錯誤。
運行時:直接的理解就是當你進行預覽/啟動並執行時候。通常這個時候的錯誤則是由具體的異常,邏輯錯誤所組成的。
讓我們分析控制項在設計時的表現,我們的控制項在設計時的時候,VS智能地類比輸出控制項在運行時的樣貌,控制項的呈現通過了一定順序的方法,並最終形成了當前輸出。按照標準,我們應該是在Render或RenderContents中對控制項進行了輸出的操作(事實上其他也是可以,但我們通常也不那麼做,或者說更多的“呈現控制項時出錯”的異常主要來自於Render或RenderContents)。
從錯誤的提示“未將對象引用設定到對象的執行個體。”從這一句話來看,也就是說,有一個或者以上的對象的執行個體在沒有賦初值的情況下就被使用了。
讓我們窺視一下我們的代碼:
protected override void RenderContents(HtmlTextWriter writer){ UpButton.Text = Page.Server.HtmlDecode(UpButton.Text); DownButton.Text = Page.Server.HtmlDecode(DownButton.Text); base.RenderContents(writer);}
因為該控制項在設計的時候需要有一個向上的按鈕和一個向下的按鈕,分別需要用兩個特殊的標點符號向上和向下,而這兩個符號需要通過設定如下所示的代碼編號才可以正確地被瀏覽器呈現:
private string upButtonText = "∧";private string downButtonText = "∨";
而這兩個符號在呈現前卻會被頁面進行一個HtmlEncode方法編譯後再輸出,而這兩個特殊的標誌卻只能通過直接輸出的方式進行呈現,也就是說在HtmlEncode之後只能將該特殊標誌以文本的形式輸出∧ ∨而不會輸出向上和向下的箭頭。這時候我們需要引入它的反向方法Page.Server.HtmlDecode進行解碼,注意到這裡我們使用了Page執行個體,該執行個體只有在頁面真實存在的情況下才為非空,否則後續的操作將是對null的操作,而這樣的操作將會顯示“未將對象引用設定到對象的執行個體。”這樣的錯誤。
設計時:我們剛才提到了,設計時僅僅只是類比頁面呈現的過程,而頁面事實上是不存在的。因此在這個時候Page對象的執行個體將為空白,後續的調用將引發異常。
假設說我們只有這個方法用於處理當前所需要的行為,那麼我們在調用Page的時候必將導致null的對象並致使後續操作發生異常。這個時候我們引入“設計模式”這個概念(非DesignPattern而是DesignMode),DesignMode是由Control類的一個受保護的(protected)屬性,它擷取一個值,用以指示該組件當前是否處於設計模式。這裡的設計模式也就相當於設計時的概念。
因此我們可以將代碼改造為如下形式:
protected override void RenderContents(HtmlTextWriter writer){ if (!DesignMode) { UpButton.Text = Page.Server.HtmlDecode(UpButton.Text); DownButton.Text = Page.Server.HtmlDecode(DownButton.Text); } base.RenderContents(writer);}
這樣只有在非設計時的時候,我們才引入Page對象的執行個體,因此設計時的異常將迎刃而解。
總結
因此在設計控制項的時候,特別是在考慮控制項呈現的時候,為了避免類似異常的發生,我們應該考慮該控制項在設計時能夠擷取足夠的資源,對於未能擷取資源的項,我們應該顯式將其區分(如上代碼中使用DesignMode來判斷是否為設計時要執行的代碼)。
擴充
剛才我們所見到的情形可以歸結為在設計時無法引用具體執行個體所導致的異常,類似該異常的還會有資料庫/檔案系統讀取、變數未附初值、調用了類似Page的屬性如Session,Page.Request.QueryString等。在頁面設計的時候由於以上部分方案特別是調用到Page的相關方法的由於頁面總是會存在,因此我們不會經常看到它們出異常,在設計控制項的時候我們更應該注意。
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援topic.alibabacloud.com。