开发和使用自定义服务器控件
此演練演示如何創(chuàng)建和編譯自定義 ASP.NET 服務(wù)器控件以及如何在頁中使用該控件。
通過此演練,您將學(xué)會如何執(zhí)行以下任務(wù):
-
創(chuàng)建一個(gè) ASP.NET 服務(wù)器控件。
-
向該控件及其成員添加元數(shù)據(jù)以控制安全性和設(shè)計(jì)時(shí)行為。
-
使用 ASP.NET 網(wǎng)站中的 App_Code 目錄對控件進(jìn)行測試(無需手動編譯步驟)。
-
在配置文件和該控件的程序集中指定一個(gè)標(biāo)記前綴。
-
將該控件編譯為一個(gè)程序集并將其添加到 Bin 目錄中。
-
將一個(gè)位圖嵌入到該控件的程序集中,以作為可視化設(shè)計(jì)器的工具箱圖標(biāo)使用。
-
在頁中使用已編譯的控件。
可視化設(shè)計(jì)工具(如 Microsoft Visual Studio 2005)可以簡化控件的開發(fā)過程,但并不是創(chuàng)建或生成自定義控件的必不可少的工具。可以通過使用任何文本編輯器創(chuàng)建控件,并使用屬于 .NET Framework SDK 一部分的編譯器從命令行生成這些控件。無論以何種方式創(chuàng)建控件,在可視化設(shè)計(jì)器中控件的設(shè)計(jì)時(shí)外觀和行為都將相同。頁開發(fā)人員可將控件添加到可視化設(shè)計(jì)器的工具箱,可將其拖動到設(shè)計(jì)圖面上,還可以在屬性瀏覽器中訪問其屬性和事件。在有些可視化設(shè)計(jì)器(如 Visual Studio 2005)中,自定義控件還可自行支持 IntelliSense。
創(chuàng)建服務(wù)器控件要創(chuàng)建的控件 WelcomeLabel 是一個(gè)簡單控件,與標(biāo)準(zhǔn)的 控件類似。WelcomeLabel 類從 派生,它定義了一個(gè) Text 屬性,該屬性允許頁開發(fā)人員提供一個(gè)文本字符串,以歡迎訪問站點(diǎn)的用戶。如果用戶名出現(xiàn)在用戶瀏覽器發(fā)送的標(biāo)題中,WelcomeLabel 就會將用戶名追加到該文本字符串。有關(guān)檢索用戶名的更多信息,請參見 。例如,如果頁開發(fā)人員將“Hello”設(shè)置為 Text 屬性的值,則根據(jù)標(biāo)題中是否出現(xiàn)用戶名,WelcomeLabel 將呈現(xiàn)“Hello, 用戶名!”或“Hello!”。
創(chuàng)建自定義服務(wù)器控件的代碼
創(chuàng)建一個(gè)名為 WelcomeLabel.cs 或 WelcomeLabel.vb 的文件。
將以下代碼添加到控件的源文件中:
Visual Basic' WelcomeLabel.vbOption Strict OnImports SystemImports System.ComponentModelImports System.Security.PermissionsImports System.WebImports System.Web.UIImports System.Web.UI.WebControlsNamespace Samples.AspNet.VB.Controls< _AspNetHostingPermission(SecurityAction.Demand, _Level:=AspNetHostingPermissionLevel.Minimal), _AspNetHostingPermission(SecurityAction.InheritanceDemand, _Level:=AspNetHostingPermissionLevel.Minimal), _DefaultProperty("Text"), _ToolboxData( _"<{0}:WelcomeLabel runat=""server""> </{0}:WelcomeLabel>") _> _Public Class WelcomeLabelInherits WebControl< _Bindable(True), _Category("Appearance"), _DefaultValue(""), _Description("The welcome message text."), _Localizable(True) _> _Public Overridable Property Text() As StringGetDim s As String = CStr(ViewState("Text"))If s Is Nothing Then s = String.EmptyReturn sEnd GetSet(ByVal value As String)ViewState("Text") = valueEnd SetEnd PropertyProtected Overrides Sub RenderContents( _ByVal writer As HtmlTextWriter)writer.WriteEncodedText(Text)If Context IsNot Nothing ThenDim s As String = Context.User.Identity.NameIf (s IsNot Nothing) AndAlso (s <> String.Empty) ThenDim split() As String = s.Split("\".ToCharArray)Dim n As Integer = split.Length - 1If (split(n) <> String.Empty) Thenwriter.Write(", ")writer.Write(split(n))End IfEnd IfEnd Ifwriter.Write("!")End SubEnd ClassEnd NamespaceC#// WelcomeLabel.csusing System;using System.ComponentModel;using System.Security.Permissions;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;namespace Samples.AspNet.CS.Controls{[AspNetHostingPermission(SecurityAction.Demand,Level = AspNetHostingPermissionLevel.Minimal),AspNetHostingPermission(SecurityAction.InheritanceDemand,Level=AspNetHostingPermissionLevel.Minimal),DefaultProperty("Text"),ToolboxData("<{0}:WelcomeLabel runat=\"server\"> </{0}:WelcomeLabel>")]public class WelcomeLabel : WebControl{[Bindable(true),Category("Appearance"),DefaultValue(""),Description("The welcome message text."),Localizable(true)]public virtual string Text{get{string s = (string)ViewState["Text"];return (s == null) ? String.Empty : s;}set{ViewState["Text"] = value;}}protected override void RenderContents(HtmlTextWriter writer){writer.WriteEncodedText(Text);if (Context != null){string s = Context.User.Identity.Name;if (s != null && s != String.Empty){string[] split = s.Split('\\');int n = split.Length - 1;if (split[n] != String.Empty){writer.Write(", ");writer.Write(split[n]);}}}writer.Write("!");}}}代碼討論
下面的代碼討論并不是執(zhí)行此演練中的步驟必不可少的內(nèi)容,可以在開始時(shí)跳過。但是,如果您初學(xué)控件創(chuàng)作,我們建議您至少要在完成演練后閱讀此內(nèi)容。
如果控件要呈現(xiàn)用戶界面 (UI) 元素或任何其他客戶端可見的元素,則應(yīng)從 System.Web.UI.WebControls.WebControl(或派生類)派生該控件。如果控件要呈現(xiàn)在客戶端瀏覽器中不可見的元素(如隱藏元素或 meta 元素),則應(yīng)從 派生該控件。WebControl 類從 Control 派生,并添加了與樣式相關(guān)的屬性,如 、 和 。此外,一個(gè)從 WebControl 派生的控件也自行參與到 ASP.NET 的主題功能。
如果您的控件要擴(kuò)展現(xiàn)有控件(如 、Label 或 控件)的功能,則可以從該控件派生。由于 WelcomeLabel 擴(kuò)展了 Label 控件的功能,因此它可從 Label 派生。但是,本演練從 WebControl 派生 WelcomeLabel 以演示如何定義屬性和定義屬性元數(shù)據(jù)。
WelcomeLabel 定義一個(gè) Text 屬性,并使用視圖狀態(tài)存儲該屬性值。使用視圖狀態(tài)保存回發(fā)間的 Text 值。每次回發(fā)時(shí),將重新創(chuàng)建頁并從視圖狀態(tài)還原值。如果 Text 值并未存儲在視圖狀態(tài)中,則在每次回發(fā)時(shí)會將值設(shè)置為其默認(rèn)的 。 屬性繼承自 WebControl,是保存數(shù)據(jù)值的字典。通過使用 鍵,可輸入和檢索值。本例中將“Text”用作鍵。字典中的項(xiàng)被類型化為 ,然后必須將其強(qiáng)制轉(zhuǎn)換為屬性類型。有關(guān)更多信息,請參見 。
WelcomeLabel 控件通過重寫繼承的 方法呈現(xiàn)其 Text 屬性。傳入 RenderContents 方法的參數(shù)是 類型的對象,是具有呈現(xiàn)標(biāo)記和其他 HTML(和 HTML 變量)標(biāo)記的方法的實(shí)用工具類。
注意,WelcomeLabel 會連續(xù)調(diào)用 HtmlTextWriter 對象的 方法,而不是先執(zhí)行字符串串聯(lián)然后調(diào)用 Write 方法。由于 HtmlTextWriter 對象直接寫入輸出流,因此這樣可以提高性能。字符串串聯(lián)需要時(shí)間和內(nèi)存來創(chuàng)建字符串,然后寫入流。在控件中實(shí)現(xiàn)呈現(xiàn)時(shí),應(yīng)按照本演練中說明的模式進(jìn)行操作。
注意通常,在從 WebControl 派生控件并呈現(xiàn)單個(gè)元素時(shí),應(yīng)重寫 RenderContents 方法(而不是 方法),以呈現(xiàn)控件標(biāo)記中的內(nèi)容。在呈現(xiàn)控件及其樣式屬性的開始標(biāo)記之后,WebControl 的 Render 方法將調(diào)用 RenderContents。如果重寫 Render 方法以寫入內(nèi)容,則控件將丟失生成到 WebControl 的 Render 方法中的樣式呈現(xiàn)邏輯。有關(guān)呈現(xiàn)從 WebControl 派生的控件的更多信息,請參見 。
應(yīng)用于 WelcomeLabel 的屬性包含由公共語言運(yùn)行庫和設(shè)計(jì)時(shí)工具使用的元數(shù)據(jù)。
在類級別上,通過以下屬性標(biāo)記 WelcomeLabel :
是代碼訪問安全屬性。該屬性使 JIT 編譯器檢查鏈接到 WelcomeLabel 的代碼是否具有 權(quán)限。所有的公共 ASP.NET 類均使用此屬性標(biāo)記。應(yīng)將 AspNetHostingPermissionAttribute 應(yīng)用于控件,以對部分受信任的被調(diào)用方進(jìn)行安全檢查。
是設(shè)計(jì)時(shí)屬性 (Attribute),它指定控件的默認(rèn)屬性 (Property)。在可視化設(shè)計(jì)器中,當(dāng)頁開發(fā)人員在設(shè)計(jì)圖面上單擊控件時(shí),屬性瀏覽器通常突出顯示此默認(rèn)屬性。
指定元素的格式字符串。如果在工具箱中雙擊控件或?qū)⑵鋸墓ぞ呦渫蟿拥皆O(shè)計(jì)圖面上時(shí),該字符串將成為控件的標(biāo)記。對于 WelcomeLabel,該字符串創(chuàng)建此元素:
<aspSample:WelcomeLabel runat="server"> </aspSample:WelcomeLabel>WelcomeLabel 控件還從 WebControl 基類繼承了兩個(gè)屬性: 和 。它們被應(yīng)用為 ParseChildren(true) 和 PersistChildren(false)。這兩個(gè)屬性 (Attribute) 一起與 ToolboxDataAttribute 屬性 (Attribute) 共同使用,這樣可將子元素解釋為屬性 (Property),并將屬性 (Property) 作為屬性 (Attribute) 保留。
以下應(yīng)用于 WelcomeLabel 的 Text 屬性 (Property) 的屬性 (Attribute) 是標(biāo)準(zhǔn)設(shè)計(jì)時(shí)屬性 (Attribute),通常會將標(biāo)準(zhǔn)設(shè)計(jì)時(shí)屬性 (Attribute) 應(yīng)用于控件的所有公共屬性 (Property):
(被指定為 true 或 false),指定將屬性綁定到數(shù)據(jù)對可視化設(shè)計(jì)器是否有意義。例如,在 Visual Studio 2005 中,如果屬性標(biāo)記為 Bindable(true),則該屬性可顯示在“數(shù)據(jù)綁定”對話框中。如果屬性 (Property) 沒有使用此屬性 (Attribute) 標(biāo)記,則屬性 (Property) 瀏覽器會推斷其值為 Bindable(false)。
指定如何在可視化設(shè)計(jì)器的屬性瀏覽器中對屬性進(jìn)行分類。例如,當(dāng)頁開發(fā)人員使用屬性瀏覽器的分類視圖時(shí),Category("Appearance") 將告知屬性瀏覽器在“外觀”類別中顯示屬性。可以根據(jù)屬性瀏覽器中的現(xiàn)有類別指定字符串參數(shù),也可以創(chuàng)建自己的類別。
指定屬性的簡短描述。在 Visual Studio 2005 中,屬性瀏覽器將在“屬性”窗口底部顯示選定的屬性的描述。
指定屬性的默認(rèn)值。此值應(yīng)與從屬性訪問器 (getter) 返回的默認(rèn)值相同。在 Visual Studio 2005 中,DefaultValueAttribute 允許頁開發(fā)人員通過在“屬性”窗口中喚出快捷菜單然后單擊“重置”按鈕將屬性值重置為其默認(rèn)值。
(指定為 true 或 false)指定本地化屬性對可視化設(shè)計(jì)器是否有意義。當(dāng)某屬性標(biāo)記為 Localizable(true) 時(shí),可視化設(shè)計(jì)器會在對本地化資源進(jìn)行序列化時(shí)包含該屬性。對控件輪詢可本地化的屬性時(shí),設(shè)計(jì)器會將此屬性值保存到非特定于區(qū)域性的資源文件或其他本地化源中。
注意由于 ASP.NET 1.0 版和 1.1 版中的 ASP.NET 本地化模型不同,因此在這些版本中不能將 LocalizableAttribute 應(yīng)用于自定義服務(wù)器控件。
應(yīng)用于控件及其成員的設(shè)計(jì)時(shí)屬性在運(yùn)行時(shí)不會影響控件的功能,但在可視化設(shè)計(jì)器中使用控件時(shí),這些屬性能提升開發(fā)人員的體驗(yàn)。有關(guān)服務(wù)器控件的設(shè)計(jì)時(shí)、分析時(shí)和運(yùn)行時(shí)屬性的完整列表,可參見。
使用 App_Code 目錄測試控件(無需編譯)可以使用 ASP.NET 動態(tài)編譯功能對頁中的控件進(jìn)行測試,而無需將控件編譯為程序集。ASP.NET 能動態(tài)編譯 ASP.NET 網(wǎng)站根目錄下 App_Code 目錄中放置的代碼。這樣就可以從頁訪問 App_Code 中源文件中的類,而無需將其手動編譯為程序集。如果將控件的源文件放入了 App_Code 目錄,則對控件的代碼所做的更改能立即在使用這些控件的頁中反映出來。
注意App_Code 目錄是 ASP.NET 1.0 和 1.1 中都沒有的新功能。使用 App_Code 目錄進(jìn)行初始控件測試是一個(gè)可選步驟。生成服務(wù)器控件的主要步驟與早期版本相同,下一節(jié)“將控件編譯為程序集”將對此進(jìn)行介紹。
創(chuàng)建 ASP.NET 網(wǎng)站和 App_Code 目錄
創(chuàng)建一個(gè)名為 ServerControlsTest 的網(wǎng)站。可以在 IIS 中將該站點(diǎn)創(chuàng)建為名為 ServerControlsTest 的虛擬目錄。有關(guān)創(chuàng)建和配置 IIS 虛擬目錄的詳細(xì)信息,請參見。
直接在網(wǎng)站根目錄(也稱 Web 應(yīng)用程序根目錄)下創(chuàng)建一個(gè) App_Code 目錄。
將控件的源文件(WelcomeLabel.cs 或 WelcomeLabel.vb)復(fù)制到 App_Code 目錄。
創(chuàng)建標(biāo)記前綴
標(biāo)記前綴是指在頁中以聲明方式創(chuàng)建控件時(shí)出現(xiàn)在控件類型名稱前面的前綴,如 <asp:Table /> 中的“asp”。若要在頁中以聲明方式使用您的控件,則 ASP.NET 需要一個(gè)映射到該控件的命名空間的標(biāo)記前綴。通過在每個(gè)使用自定義控件的頁上添加一個(gè) 指令,頁開發(fā)人員可提供標(biāo)記前綴/命名空間映射,如下面的示例所示:
C#<%@ Register TagPrefix="aspSample" Namespace="Samples.AspNet.CS.Controls"%>[Visual Basic]
<%@ Register TagPrefix="aspSample" Namespace="Samples.AspNet.VB.Controls"%>注意ASP.NET 2.0 中的 指令與 ASP.NET 1.0 和 ASP.NET 1.1 中的相同。如果您熟悉 ASP.NET 早期版本中的 Register 指令,您會注意到前面的 Register 指令中缺少指定控件程序集名稱的 assembly 屬性。如果缺少 assembly 屬性,則 ASP.NET 會推斷該程序集是從 App_Code 目錄中的源文件動態(tài)編譯而來。
除了在每個(gè) .aspx 頁中使用 指令,頁開發(fā)人員還可以在 Web.config 文件中指定標(biāo)記前綴/命名空間映射。如果將在 Web 應(yīng)用程序的多個(gè)頁中使用自定義控件,則該方法非常有用。下面的過程描述如何在 Web.config 文件中指定標(biāo)記前綴映射。
在 Web.config 文件中添加標(biāo)記前綴映射
如果不存在名為 Web.config 的文本文件,則請?jiān)诰W(wǎng)站的根目錄下創(chuàng)建該文件。
創(chuàng)建了新的(空的)Web.config 文件之后,將以下代碼復(fù)制到該文件中并保存該文件。
C#<?xml version="1.0"?><configuration><system.web><pages><controls><b> <add tagPrefix="aspSample" </b><b> namespace="Samples.AspNet.CS.Controls"></b><b> </add></b></controls></pages></system.web></configuration>?
Visual Basic<?xml version="1.0"?><configuration><system.web><pages><controls><b> <add tagPrefix="aspSample" </b><b> namespace="Samples.AspNet.VB.Controls"></b><b> </add></b></controls></pages></system.web></configuration>突出顯示部分是一個(gè)標(biāo)記前綴項(xiàng),該項(xiàng)將標(biāo)記前綴“aspSample”映射到命名空間 Samples.AspNet.CS.Controls 或 Samples.AspNet.VB.Controls。
如果已存在一個(gè) Web.config 文件,則請將前一步驟中突出顯示的文本作為該配置文件的 controls 元素的子項(xiàng)添加到該文件中。如果 Web.config 文件中沒有 controls 和 pages 元素,則請按照前一步驟中介紹的方法創(chuàng)建這些元素。
注意標(biāo)記前綴項(xiàng)必須是 controls 節(jié)的子項(xiàng),而該節(jié)必須位于 pages 節(jié)下,而后者又必須是 system.web 的子項(xiàng)。
在配置文件中指定了標(biāo)記前綴映射之后,可以在網(wǎng)站的任何頁中以聲明方式使用 WelcomeLabel 控件(如 <aspSample:WelcomeLabel />)。
注意標(biāo)記前綴的配置項(xiàng)是 ASP.NET 2.0 的新功能。在 ASP.NET 1.0 和 1.1 中,標(biāo)記前綴映射在每個(gè)使用自定義控件的頁的 指令中指定。
創(chuàng)建使用控件的頁
創(chuàng)建使用自定義控件的頁
在網(wǎng)站中創(chuàng)建一個(gè)名為 WelcomeLabelTest.aspx 的文本文件。
將以下標(biāo)記復(fù)制到 WelcomeLabelTest.aspx 文件中并保存該文件。
Visual Basic<%@ Page Language="VB"%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head id="Head1" runat="server"><title>WelcomeLabel Test</title></head><body><form id="form1" runat="server"><div><aspSample:WelcomeLabel Text="Hello" ID="WelcomeLabel1"runat="server" BackColor="Wheat" ForeColor="SaddleBrown" /></div></form></body></html>C#<%@ Page Language="C#"%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head id="Head1" runat="server"><title>WelcomeLabel Test</title></head><body><form id="form1" runat="server"><div><aspSample:WelcomeLabel Text="Hello" ID="WelcomeLabel1"runat="server" BackColor="Wheat" ForeColor="SaddleBrown" /></div></form></body></html>在地址欄中輸入以下 URL,以在瀏覽器中顯示 WelcomeLabelTest.aspx:
http://localhost/ServerControlsTest/WelcomeLabelTest.aspx對控件的源代碼做一些更改。例如,通過在 RenderContents 方法末尾處添加此行代碼來多寫一個(gè)字符串:
C#writer.Write("Testing how the App_Code directory works.");?
Visual Basicwriter.Write("Testing how the App_Code directory works.")在瀏覽器中刷新 WelcomeLabelTest.aspx 頁。
將看到,盡管沒有編譯控件,對控件所做的更改仍在頁中反映出來了。
除了顯式定義的 WelcomeLabel 控件的 Text 屬性之外,從頁中的控件實(shí)例可以看到,它還具有之前并沒有定義的 BackColor 和 ForeColor 屬性。WelcomeLabel 控件通過從 WebControl 基類繼承,從而獲取與樣式相關(guān)的這些屬性和其他屬性。此外,WelcomeLabel 可自行分配外觀并成為主題的一部分。
將控件編譯為程序集盡管利用 App_Code 目錄可以不編譯就對控件進(jìn)行測試,但是如果您希望將您的控件作為對象代碼分發(fā)給其他開發(fā)人員,則必須對其進(jìn)行編譯。此外,如果沒有將控件編譯為程序集,就不能將該控件添加到可視化設(shè)計(jì)器的工具箱中。
將控件編譯為程序集
按照以下這些步驟設(shè)置計(jì)算機(jī)的 Windows 環(huán)境 PATH 變量,使其包含 .NET Framework 的安裝路徑:
在 Windows 中,右擊“我的電腦”,選擇“屬性”,單擊“高級”選項(xiàng)卡,然后單擊“環(huán)境變量”按鈕。
在“系統(tǒng)變量”列表中,雙擊 Path 變量。
在“變量值”文本框中,將一個(gè)分號 (;) 添加到文本框中的現(xiàn)有值的末尾,然后鍵入 .NET Framework 的安裝路徑。.NET Framework 通常安裝在位于 \Microsoft.NET\Framework\版本號 的 Windows 安裝目錄中。
單擊“確定”關(guān)閉每個(gè)對話框。
從為本演練第一步中的源文件創(chuàng)建的目錄中運(yùn)行以下命令。
注意這與復(fù)制控件源文件以進(jìn)行測試的 App_Code 目錄不同。
C#csc /t:library /out:Samples.AspNet.CS.Controls.dll /r:System.dll /r:System.Web.dll *.cs?
Visual Basicvbc /t:library /out:Samples.AspNet.VB.Controls.dll /r:System.dll /r:System.Web.dll *.vb/t:library 編譯器選項(xiàng)告知編譯器創(chuàng)建一個(gè)庫,而不是創(chuàng)建一個(gè)可執(zhí)行程序集。/out 選項(xiàng)為程序集提供名稱,而 /r 選項(xiàng)則列出鏈接到您的程序集的那些程序集。
為保持示例獨(dú)立,本演練要求創(chuàng)建具有單個(gè)控件的程序集。通常,.NET Framework 設(shè)計(jì)指導(dǎo)原則建議不要創(chuàng)建只包含很少的類的程序集。為了便于部署,應(yīng)盡可能少地創(chuàng)建程序集。
在控件程序集中嵌入圖標(biāo)
可視化設(shè)計(jì)器(如 Visual Studio 2005)通常使用默認(rèn)圖標(biāo)(如齒輪圖像)顯示工具箱中的控件。作為控件的一個(gè)選項(xiàng),可以通過在控件的程序集中嵌入一個(gè) 16*16 像素的位圖來自定義控件在工具箱中的外觀。根據(jù)約定,可視化設(shè)計(jì)器將該位圖最下方左側(cè)的像素用作透明色。
在控件程序集中嵌入圖標(biāo)
創(chuàng)建或獲取一個(gè) 16*16 像素的位圖,將其作為控件的工具箱圖標(biāo)。
將該位圖命名為 WelcomeLabel.bmp。
將該位圖文件添加到包含 WelcomeLabel 控件源文件的目錄(CustomControlsCS 或 CustomControlsVB)中。
從包含源文件的目錄中運(yùn)行以下命令:
C#csc /res:WelcomeLabel.bmp,Samples.AspNet.CS.Controls.WelcomeLabel.bmp/t:library /out:Samples.AspNet.CS.Controls.dll /r:System.dll/r:System.Web.dll *.cs?
Visual Basicvbc /res:WelcomeLabel.bmp,Samples.AspNet.VB.Controls.WelcomeLabel.bmp/t:library /out:Samples.AspNet.VB.Controls.dll /r:System.dll/r:System.Web.dll *.vb此命令將編譯控件并將該位圖作為資源嵌入到程序集中。嵌入的位圖資源的名稱必須與關(guān)聯(lián)控件的命名空間限定名稱完全相同。例如,如果控件名稱為 Samples.AspNet.CS.Controls.WelcomeLabel,則嵌入的位圖的名稱必須為 Samples.AspNet.CS.Controls.WelcomeLabel.bmp。此命名約定使可視化設(shè)計(jì)器能自動將該位圖用作控件的工具箱圖標(biāo)。如果不使用此命名約定,則必須將 應(yīng)用于該控件,以指定嵌入的位圖資源的名稱。
使用 TagPrefixAttribute 提供標(biāo)記前綴/命名空間映射
在本演練前面的內(nèi)容中,在介紹使用 App_Code 目錄時(shí)講述了頁開發(fā)人員如何在頁或 Web.config 文件中指定標(biāo)記前綴。可以選擇通過包含程序集級別的 屬性,建議可視化設(shè)計(jì)器應(yīng)為控件使用的默認(rèn)標(biāo)記前綴。如果設(shè)計(jì)器未找到在 Web.config 文件或頁中的 Register 指令中映射的標(biāo)記前綴,TagPrefixAttribute 屬性就會為可視化設(shè)計(jì)器提供可以使用的標(biāo)記前綴,因此該屬性非常有用。在工具箱中首次雙擊控件或?qū)⑵鋸墓ぞ呦渫蟿拥巾撝袝r(shí),此標(biāo)記前綴將向頁進(jìn)行注冊。
如果決定使用 TagPrefixAttribute 屬性,則可以在與控件一起編譯的單獨(dú)文件中指定該屬性。根據(jù)約定,該文件名為 AssemblyInfo.語言擴(kuò)展,如 AssemblyInfo.cs 或 AssembyInfo.vb。下面的過程介紹如何指定 TagPrefixAttribute 元數(shù)據(jù)。
注意如果沒有在控件的程序集中指定 TagPrefixAttribute,并且頁開發(fā)人員沒有在頁或 Web.config 文件中指定標(biāo)記前綴/命名空間映射,則可視化設(shè)計(jì)器將創(chuàng)建一個(gè)默認(rèn)的標(biāo)記前綴。例如,從工具箱中拖動控件時(shí),Visual Studio 2005 將創(chuàng)建其自己的控件標(biāo)記,如 cc1。
使用 TagPrefixAttribute 添加命名空間/標(biāo)記前綴映射
在源代碼目錄中創(chuàng)建一個(gè)名為 AssemblyInfo.cs 或 AssemblyInfo.vb 的文件并向該文件添加以下代碼。
C#using System;using System.Web.UI;[assembly: TagPrefix("Samples.AspNet.CS.Controls", "aspSample")]?
Visual BasicImports SystemImports System.Web.UI<Assembly: TagPrefix("Samples.AspNet.VB.Controls", "aspSample")>標(biāo)記前綴屬性在命名空間 Samples.AspNet.CS.Controls 或 Samples.AspNet.VB.Controls 與前綴 aspSample 之間創(chuàng)建映射。
使用前面使用的編譯命令重新編譯所有的源文件(使用或不使用嵌入資源)。
在 ASP.NET 頁中使用已編譯的自定義控件若要測試自定義控件的已編譯版本,則必須使網(wǎng)站中的頁可以訪問此控件的程序集。
使網(wǎng)站可以訪問控件的程序集
在網(wǎng)站的根目錄下創(chuàng)建一個(gè) Bin 目錄。
將控件程序集(Samples.AspNet.CS.Controls.dll 或 Samples.AspNet.VB.Controls.dll)復(fù)制到 Bin 目錄。
從 App_Code 目錄中刪除該控件的源文件。
如果沒有刪除源文件,則您的控件的類型將同時(shí)存在于編譯的程序集中和由 ASP.NET 動態(tài)生成的程序集中。這在加載該控件時(shí)會造成不明確引用,加載任何使用該控件的頁時(shí)將生成編譯器錯(cuò)誤。
本演練中創(chuàng)建的程序集必須放在 ASP.NET 網(wǎng)站的 Bin 目錄中才能使網(wǎng)站中的頁使用您的控件,故而該程序集為私有程序集。如果其他應(yīng)用程序沒有安裝該程序集的副本,則這些應(yīng)用程序都不能訪問該程序集。如果要為共享的 Web 宿主應(yīng)用程序創(chuàng)建控件,通常會將控件打包到一個(gè)私有程序集中。但是,如果要創(chuàng)建在專用宿主環(huán)境中使用的控件,或要創(chuàng)建 ISP 向所有客戶提供的一系列控件,則需要將您的控件打包到安裝在全局程序集緩存中的一個(gè)共享(強(qiáng)名稱)程序集中。有關(guān)更多信息,請參見。
接下來,必須修改在 Web.config 中創(chuàng)建的標(biāo)記前綴映射,以指定控件的程序集名稱。
修改 Web.config 中的標(biāo)記前綴映射
編輯 Web.config 文件,向 add tagPrefix 元素添加 assembly 屬性:
C#<controls><add tagPrefix="aspSample"namespace="Samples.AspNet.CS.Controls"<b>assembly="Samples.AspNet.CS.Controls</b>"></add></controls>?
Visual Basic<controls><add tagPrefix="aspSample"namespace="Samples.AspNet.VB.Controls"<b>assembly="Samples.AspNet.VB.Controls</b>"></add></controls>assembly 屬性指定控件所在的程序集的名稱。add tagPrefix 元素將標(biāo)記前綴映射到命名空間和程序集的組合。ASP.NET 從 App_Code 目錄中的源文件動態(tài)生成程序集時(shí),無需提供程序集屬性。未使用程序集屬性時(shí),ASP.NET 會從通過 App_Code 目錄動態(tài)生成的程序集加載控件的類型。
查看使用自定義控件的頁
通過在地址欄中輸入以下 URL,可在瀏覽器中顯示 WelcomeLabelTest.aspx 頁:
http://localhost/ServerControlsTest/WelcomeLabelTest.aspx如果在可視化設(shè)計(jì)器(如 Visual Studio 2005)中使用您的控件,可以向工具箱添加您的控件,可以將其從工具箱拖動到設(shè)計(jì)圖面,還可以在屬性瀏覽器中訪問其屬性和事件。此外,在 Visual Studio 2005 中,您的控件在頁設(shè)計(jì)器的“源”視圖和代碼編輯器中具有完整的 IntelliSense 支持。這包括 script 塊中的語句結(jié)束支持以及頁開發(fā)人員單擊控件標(biāo)記時(shí)的屬性瀏覽器支持。
注意在許多可視化設(shè)計(jì)器中,可以將自定義控件添加到設(shè)計(jì)器的工具箱中。有關(guān)詳細(xì)信息,請參閱設(shè)計(jì)器文檔。
后續(xù)步驟本演練演示了如何開發(fā)簡單的自定義 ASP.NET 服務(wù)器控件以及如何在頁中使用該控件。您了解了如何定義屬性以及如何將控件編譯為程序集。有關(guān)更多信息,包括有關(guān)呈現(xiàn)、定義屬性、維護(hù)狀態(tài)和實(shí)現(xiàn)復(fù)合控件的信息,請參見。
在本演練中,您了解了可以為您的控件提供自定義工具箱圖標(biāo)。您還學(xué)習(xí)了如何添加設(shè)計(jì)時(shí)元數(shù)據(jù),從而為您的控件自定義屬性瀏覽器支持。通過使用在設(shè)計(jì)時(shí)和運(yùn)行時(shí)提供不同用戶界面的可視化設(shè)計(jì)器類,復(fù)雜控件(如 控件)進(jìn)一步增強(qiáng)了其設(shè)計(jì)時(shí)體驗(yàn)。ASP.NET 2.0 為服務(wù)器控件提供的設(shè)計(jì)器對象模型與 ASP.NET 1.0 和 1.1 中提供的模型大為不同。若要了解有關(guān)在 ASP.NET 2.0 中為您的控件實(shí)現(xiàn)自定義設(shè)計(jì)器類的信息,請參見 。
在 ASP.NET 2.0 中,服務(wù)器控件通過使用適配器類可以為客戶端瀏覽器或設(shè)備定義不同行為。有關(guān)更多信息,請參見
不同的瀏覽器和相同瀏覽器的不同版本支持不同的功能。ASP.NET 服務(wù)器控件將自動確定已請求 .aspx 頁的瀏覽器,并為該瀏覽器正確設(shè)置所生成的 HTML 標(biāo)記的格式。但是,部分控件功能無法在較低版本的瀏覽器上呈現(xiàn),因此需要在盡可能多的瀏覽器類型上查看頁的輸出,以確保頁以預(yù)期方式呈現(xiàn)在所有瀏覽器中。有關(guān)更多信息,請參見 。
請參見其他資源
開發(fā)自定義 ASP.NET 服務(wù)器控件總結(jié)
以上是生活随笔為你收集整理的开发和使用自定义服务器控件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [翻译]使用C#创建SQL Server
- 下一篇: 解读服务器虚拟化的十大误区