VS2010中呈現(xiàn)控件時出錯的解決方法
在制作控件的時候容易遇到“呈現(xiàn)控件時出錯”“發(fā)生了未處理的異常。未將對象引用設置到對象的實例?!边@樣的錯誤,如下圖:(也有可能僅僅只是因為未設置runat="server"標簽而導致該錯誤,請先檢查該項。)
但是在編譯時/運行時也都是沒有錯誤的。
分析
如圖所示的情況我們稱之為“設計時”以區(qū)別于“編譯時”/“運行時”。
設計時:在ASP.NET環(huán)境中也就是當我們在Visual Studio中使用網(wǎng)頁設計器進行編輯的時候。直接的理解就是在ASPX頁面切換到“設計”的時候。
編譯時:直接的理解就是當你進行編譯的時候,通常這個時候的錯誤是由類型檢查,參數(shù)匹配等顯式可直接通過語法約束所限制的錯誤。
運行時:直接的理解就是當你進行預覽/運行的時候。通常這個時候的錯誤則是由具體的異常,邏輯錯誤所組成的。
讓我們分析控件在設計時的表現(xiàn),我們的控件在設計時的時候,VS智能地模擬輸出控件在運行時的樣貌,控件的呈現(xiàn)通過了一定順序的方法,并最終形成了當前輸出。按照標準,我們應該是在Render或RenderContents中對控件進行了輸出的操作(事實上其他也是可以,但我們通常也不那么做,或者說更多的“呈現(xiàn)控件時出錯”的異常主要來自于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);
}
因為該控件在設計的時候需要有一個向上的按鈕和一個向下的按鈕,分別需要用兩個特殊的標點符號向上和向下,而這兩個符號需要通過設置如下所示的代碼編號才可以正確地被瀏覽器呈現(xiàn):
private string upButtonText = "∧"; private string downButtonText = "∨";
而這兩個符號在呈現(xiàn)前卻會被頁面進行一個HtmlEncode方法編譯后再輸出,而這兩個特殊的標志卻只能通過直接輸出的方式進行呈現(xiàn),也就是說在HtmlEncode之后只能將該特殊標志以文本的形式輸出∧ ∨而不會輸出向上和向下的箭頭。這時候我們需要引入它的反向方法Page.Server.HtmlDecode進行解碼,注意到這里我們使用了Page實例,該實例只有在頁面真實存在的情況下才為非空,否則后續(xù)的操作將是對null的操作,而這樣的操作將會顯示“未將對象引用設置到對象的實例。”這樣的錯誤。
設計時:我們剛才提到了,設計時僅僅只是模擬頁面呈現(xiàn)的過程,而頁面事實上是不存在的。因此在這個時候Page對象的實例將為空,后續(xù)的調(diào)用將引發(fā)異常。
假設說我們只有這個方法用于處理當前所需要的行為,那么我們在調(diào)用Page的時候必將導致null的對象并致使后續(xù)操作發(fā)生異常。這個時候我們引入“設計模式”這個概念(非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對象的實例,因此設計時的異常將迎刃而解。
總結(jié)
因此在設計控件的時候,特別是在考慮控件呈現(xiàn)的時候,為了避免類似異常的發(fā)生,我們應該考慮該控件在設計時能夠獲取足夠的資源,對于未能獲取資源的項,我們應該顯式將其區(qū)分(如上代碼中使用DesignMode來判斷是否為設計時要執(zhí)行的代碼)。
擴展
剛才我們所見到的情形可以歸結(jié)為在設計時無法引用具體實例所導致的異常,類似該異常的還會有數(shù)據(jù)庫/文件系統(tǒng)讀取、變量未附初值、調(diào)用了類似Page的屬性如Session,Page.Request.QueryString等。在頁面設計的時候由于以上部分方案特別是調(diào)用到Page的相關(guān)方法的由于頁面總是會存在,因此我們不會經(jīng)常看到它們出異常,在設計控件的時候我們更應該注意。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- VS2010/MFC編程(常用控件:樹形控件Tree Control控件創(chuàng)建h和實例)
- 使用VS2010 C#開發(fā)ActiveX控件(下),完整代碼打包下載
- 使用VS2010 C#開發(fā)ActiveX控件(上)
- asp.net GridView控件中模板列CheckBox全選、反選、取消
- asp.net 打印控件使用方法
- asp.net+jquery滾動滾動條加載數(shù)據(jù)的下拉控件
- Asp.net 菜單控件簡潔版
- asp.net AjaxControlToolKit--TabContainer控件的介紹
- ASP.NET單選按鈕控件RadioButton常用屬性和方法介紹
- asp.net fileupload控件上傳文件與多文件上傳
相關(guān)文章
asp.net core中Cookie和Session的實現(xiàn)示例
ASP.NET Core用戶會話管理主要通過Cookie和Session實現(xiàn),本文主要介紹了asp.net core中Cookie和Session的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2025-01-01
ABP(現(xiàn)代ASP.NET樣板開發(fā)框架)系列之二、ABP入門教程詳解
ABP是為新的現(xiàn)代Web應用程序使用最佳實踐和使用最流行工具的一個起點??勺鳛橐话阌猛镜膽贸绦虻幕A(chǔ)框架或項目模板。接下來通過本文給大家詳細介紹ABP入門教程,感興趣的朋友一起看看吧2017-10-10
用WebClient.UploadData方法上載文件數(shù)據(jù)的方法
用WebClient.UploadData方法上載文件數(shù)據(jù)的方法...2007-04-04
asp.net(c#)實現(xiàn)從sqlserver存取二進制圖片的代碼
有一個員工表Employee,需要保存員工照片(Photo)到數(shù)據(jù)庫(sql server)上。員工照片對應的字段是varbinary(max),也就是要存成二進制文件類型(這和以前討巧地存圖片文件路徑就不相同了),默認可以為空。2011-09-09
Asp.net TreeView來構(gòu)建用戶選擇輸入的方法 推薦
選擇優(yōu)于輸入,這是一般人的共識,面對繁多的數(shù)據(jù),提供良好的選擇界面,一方面增強用戶的界面體驗,一方面也提高了數(shù)據(jù)的準確性,更節(jié)省了用戶的寶貴時間。2009-12-12
.Net?Core使用Logger實現(xiàn)log寫入本地文件系統(tǒng)
這篇文章介紹了.Net?Core使用Logger實現(xiàn)log寫入本地文件系統(tǒng)的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06

