頁面的處理指示 頁面指令的處理用於配置執行該頁面的運行時環境。在ASP.NET中,指令可以位於頁面的任何位置,但良好且常見的習慣是將其置於檔案的開始部分。除此,頁面指令的名稱是不區分大小寫,且指令的屬性(attribute)值也不必加引號。@Page是ASP.NET中最重要的也是最常用的指令。表3.4列出了所有ASP.NET指令。 【101~102】 表3.4 ASP.NET頁面支援的指令
指 令 |
說 明 |
@Assembly |
用於將程式集連結到當前頁面或使用者控制項上 |
@Control |
用於定義控制項特有的屬性(attribute),這些屬性會控制控制項編譯器的行為 |
@Implements |
用於指示當前頁面或目前使用者控制項實現指定的.NET Framework 介面 |
@Import |
用於顯式地將命名空間匯入到頁面或使用者控制項中 |
@Master |
用於指示將當前頁面標識為ASP.NET主版頁面(詳見第6章)。ASP.NET 1.x不支援該指令 |
@MasterType |
當通過Master屬性(property)訪問ASP.NET主版頁面時,它會為該主版頁面提供一種建立強型別引用的方式(詳見第6章)。ASP.NET 1.x不支援該指令 |
@OutputCache |
用於控制頁面或使用者控制項的輸出緩衝策略(詳見第16章) |
@Page |
用於定義頁面特有的屬性,以便控制處理該頁面的頁面編輯器和語言解析器的行為 |
@PreviousPageType |
提供了一種擷取之前的頁面強型別引用的方式,通過PreviousPage屬性便可以對之前的頁面進行訪問 |
@Reference |
用於將頁面或使用者控制項連結到當前頁面或使用者控制項上 |
@Register |
用於在頁面或控制項中建立自訂標籤。新的標籤(包括首碼和名稱)會將命名空間和使用者定義的控制項關聯起來 |
除@Page、 @PreviousPageType、@Master、@MasterType和@Control外,所有指令都可以在頁面和控制項中聲明。@Page和 @Control是互斥的:@Page僅能用在.aspx檔案中,而@Control指令僅能用在.ascx檔案中。@Master用於定義一種非常特殊的頁面——主版頁面(master page)。 處理指示的文法較特殊,但對於所有指令類型都是一致的。多個屬性(attribute)必須用空白分割,屬性與值間的等號(=)兩邊不能有空白,如下所示: <%@ Directive_Name attribute="value" [attribute="value" … ] %> 【103】 每種指令都有自己類型化的屬性集合。將錯誤類型的值賦給一個屬性,或在某個屬性中使用錯誤的屬性,都會導致編譯錯誤。 要點:指令的屬性內容總是以純文字的形式被解析。然而,對於某些屬性,應包含能夠被解析為特定.NET Framework類型的值。當ASP.NET頁面被解析時,所有指令屬性 會被提取,並儲存在一個字典中。屬性的名稱和數目必須與該指令所對應模式相匹配。只要用字串表示的屬性值能夠被轉換為目標類型,那麼它便是有效。例如,如果某個屬性只接受布爾(Boolean)類型的值,則只有true和false是有效。 @Page指令
@Page指令只能在.aspx頁面中使用,若在其他ASP.NET頁(如控制項和Web服務)中使用,會導致編譯錯誤。每個.aspx檔案最多隻能包含一個@Page指令。雖然從文法的角度看,沒有必要強制要求指定該指令,但實際幾乎所有複雜的頁都這樣做。 @Page指令大約有30個屬性,它們從邏輯上可以分為三類:編譯(詳見表3.5)、頁面整體行為(詳見表3.6)和頁面輸出(詳見表3.7)。每個ASP.NET頁在第一次請求時進行編譯,實際發送給瀏覽器的HTML是類的方法產生的,而這些類也是動態產生的。表3.5所列的屬性用於對編譯器參數進行調整,並能夠選擇要使用的語言。 表3.5 用於頁面編譯的@Page指令屬性
屬 性 |
說 明 |
ClassName |
用於指定頁面被請求時動態產生的類的名稱。它必須是不帶命名空間資訊的類名 |
CodeFile |
用於提示當前頁面程式碼後置類別的路徑。該類檔案必須被部署到Web伺服器上。ASP.NET 1.x不支援該屬性 |
CodeBehind |
Visual Studio .NET 2003使用的屬性,用於提示當前頁面程式碼後置類別的路徑。該類檔案會被編譯為可部署的程式集(對2.0或更高版本的ASP.NET來說,應使用 CodeFile屬性) |
CodeFileBaseClass |
用於指定頁的基類及其關聯的程式碼後置類別的基類名稱。該屬性是可選的,但如果使用了CodeFile屬性,則必須指定該屬性。ASP.NET 1.x不支援該屬性 |
CompilationMode |
用於指示當前頁面是否在運行時編譯。ASP.NET 1.x不支援該屬性 |
CompilerOptions |
用於編譯當前頁的一系列編譯器命令列參數 |
Debug |
一個布爾值,用於指示是否應使用偵錯符號編譯該頁 |
Explicit |
一個布爾值,用於確定在編譯該頁時是否將Visual Basic的Option Explicit模式設定為On。Option Explicit會強制編程人員顯式聲明所有變數。如果當前頁所選語言不是Visual Basic .NET,該屬性將被忽略 |
Inherits |
用於定義當前頁要繼承的基類,它可以為從Page類派生的任何類 |
Language |
用於在編譯時間提示內聯代碼塊(<% … %>)和<script>區段中代碼所使用的語言。支援的語言套件括Visual Basic .NET、C#、JScript .NET和J#。如果沒有另外指定,則採用預設設定Visual Basic .NET |
續表
屬 性 |
說 明 |
LinePragmas |
用於確定運行時是否應在原始碼中產生行雜注(line pragma) |
MasterPageFile |
用於指示當前頁面的主版頁面。ASP.NET 1.x不支援該屬性 |
Src |
用於指示包含實現Inherits指定的基類的源檔案路徑。Visual Studio和其他快速應用程式開發(RAD)設計器不使用該屬性 |
Strict |
一個布爾值,用於確定在編譯當前頁時,是否將Visual Basic的Option Strict設為On。若開啟Option Strict,則只允許型別安全的轉換,禁止可能導致資料丟失的隱式類型轉換(在這種情況下,其行為與C#一致)。如果當前頁所選語言不是Visual Basic .NET,該屬性將被忽略 |
Trace |
一個布爾值,用於指示是否開啟跟蹤功能。如果啟用跟蹤功能,額外的資訊會被追加到頁面的輸出中。預設值為false |
TraceMode |
當啟用跟蹤功能時,提示當前頁面跟蹤訊息的顯示方式。有效值為SortByTime和SortByCategory。若跟蹤功能開啟,該屬性的預設值為SortByTime |
WarningLevel |
提示編譯器的警告層級,當到達指定的層級時,編譯過程將中止。有效值為0~4 |
【104~105】 注意,Explicit和Strict屬性的預設值從應用程式的設定檔中讀取。通過合并所有電腦級、應用程式級和檔案夾級的設定,從而獲得ASP.NET應用程式的設定。這表明我們還可以控制 Explicit和Strict屬性的預設值。如果不更改預設的配置資訊(即.NET Framework安裝時建立的配置資訊),Explicit和Strict便為預設設定true。如果在各設定檔中,刪除與其相關的所有設定,二者的值都會變為false。 可通過表3.6列出的屬性在某種程度上控制頁的整體行為和支援的功能。例如,我們可以設定自訂的錯誤頁、禁用工作階段狀態,以及控制頁面的事物處理行為。 表3.6 用於控制頁面行為的@Page指令屬性
屬 性 |
說 明 |
AspCompat |
布爾類型的屬性。若設為true,則允許當前頁面在單一執行緒 Apartment(STA)線程上執行。該設定使頁能夠調用COM+ 1.0組件,以及用Visual Basic 6.0開發的需要訪問非託管ASP內建對象的組件(第14章將探討該話題) |
Async |
如果設定為true,則產生的頁面類將派生於IHttpAsyncHandler,而不是使IHttpHandler 將某些內建的非同步功能添加到頁中。ASP.NET 1.x不支援該屬性 |
續表
屬 性 |
說 明 |
AsyncTimeOut |
用於定義處理非同步任務時使用的逾時時間(單位為秒)。預設為45秒。ASP.NET 1.x不支援該屬性 |
AutoEventWireup |
布爾類型的屬性,用於指示是否啟用頁面的事件。預設為true。使用Visual Studio .NET開發的頁會將該屬性設定為false,頁面的事件會被分別綁定到處理常式上 |
Buffer |
布爾類型的屬性,用於確定是否啟用HTTP響應緩衝。預設值為true |
Description |
用於提供當前頁面的文本描述。ASP.NET頁解析器會忽略該屬性,而只用作文檔說明 |
EnableEventValidation |
布爾類型的屬性,用於決定是否使當前頁面產生一隱含欄位,為支援事件數目據驗證的輸入欄位做緩衝。預設值為true。 ASP.NET 1.x不支援該屬性 |
EnableSessionState |
用於定義當前頁面處理會話資料的方式。如果設為true,則可以讀/寫工作階段狀態。如果設為false,則應用程式無法使用會話資料。最後,如果設為ReadOnly,則只能讀取會話資料,而不能更改 |
EnableViewState |
布爾類型的屬性,用於指示是否在頁面請求間保持檢視狀態。檢視狀態是頁面調用的上下文,用於儲存往返過程之間當前頁面狀態值的集合(第15章將對此進行講解) |
EnableTheming |
布爾類型的屬性,用於指示當前頁是否對嵌入的控制項應用主題。預設值為true。ASP.NET 1.x不支援該屬性 |
EnableViewStateMac |
布爾類型的屬性,用於指示ASP.NET是否為特定的電腦產生身分識別驗證碼,並將其追加到頁的檢視狀態中(除 Base64編碼)。屬性名稱中的Mac代表“電腦身分識別驗證檢查”(machine authentication check,MAC)。若將該屬性設定為true,則在回傳時,ASP.NET會檢查檢視狀態的身分識別驗證碼,以便確保其在用戶端上沒有被 篡改 |
ErrorPage |
定義一個目標URL,後者指向一提示頁。在頁發生未處理異常時,使用者會被重新導向到該位置 |
MaintainScrollPositionOnPostback |
用於指示是否在回傳之後恢複用戶端瀏覽器的捲軸位置。預設值為fasle |
SmartNavigation |
布爾類型的屬性,用於指示當前頁是否支援Internet Explorer 5或更高版本的智能導航功能。智能導航使得頁面重新整理後不會失去滾動位置和元素焦點 |
Theme,StyleSheetTheme |
用於指示為當前頁選擇的主題(或樣式表主題)名稱。ASP.NET 1.x不支援該屬性 |
續表
屬 性 |
說 明 |
Transaction |
用於指示當前頁是否支援或需要事物。有效值為:Disabled、NotSupported、Supported、 Required和RequiresNew。預設情況下,事務支援是被禁用的 |
ValidateRequest |
布爾類型的屬性,用於指示是否執行請求驗證。如果設定為true,ASP.NET將根據一硬式編碼潛在危險值列表對所有的輸入資料進行檢查。該功能有助於降低頁面的跨網站指令碼攻擊風險。預設值為true。ASP.NET 1.0不支援該功能 |
ViewStateEncryptionMode |
用於指示檢視狀態的加密方式。有三個可能的枚舉值:Auto、Always和Never。預設為Auto,這表明只有在控制項要求時才加密檢視狀態。注意,每次請求的頁面處理都加密視圖資料,會對伺服器造成一定的額外開銷 |
【106~107】 表3.7中列舉的屬性用於控製為頁面產生的輸出資訊格式。例如,我們可以設定頁面的內容類型,或者儘可能地使輸出本地化。 表3.7 用於控制輸出的@Page指令屬性
屬 性 |
說 明 |
ClientTarget |
用於指示ASP.NET伺服器控制項呈現其內容時所要面向的瀏覽器 |
CodePage |
用於指示相應的字碼頁值。只有在使用一個字碼頁建立該頁(而不是使用運行該頁的Web伺服器的預設字碼頁)時,才設定該屬性。在這種情況下,將該屬性設定為開發電腦的字碼頁。字碼頁是一個符號集合,包括數字、標點和其他符號。不同語言的字碼頁會有區別 |
ContentType |
用於將響應的內容類型定義為標準的MIME類型。支援任何有效HTTP內容類型字串 |
Culture |
用於指示當前頁的地區性設定。地區性資訊包括書寫與排序系統、日曆和貨幣格式。該屬性值必須為地區性相關的名稱,即它必須包含語言和國家資訊。例如,en-US就是一個有效值,而en本身則會被認為是國家不相關的 |
LCID |
32位的值,用於定義頁的地區標識符。預設情況下,ASP.NET會使用Web伺服器的地區設定 |
ResponseEncoding |
用於指示當前頁面的編碼方案名稱。該值用於設定內容類型HTTP標題的CharSet屬性。在內部,ASP.NET會將所有字串按Unicode處理 |
Title |
用於指示當前頁的標題。對於一般的頁面作用不大,因為可以使用HTML的<title>標籤,該屬性的定義是為了協助開發人員在內容頁中不能訪問<title>的情況下(這取決於主版頁面的結構設計),為其設定標題 |
續表
屬 性 |
說 明 |
UICulture |
用於指定資源管理員(Resource Manager)使用的預設區域資訊名稱,以便在運行時尋找地區性特定的資源 |
不難看出,表3.7中的許多屬性與頁面的本地化有關。ASP.NET(更一般地講是.NET Framework)極大地簡化了構建多語言的國際化應用程式的任務。第5章會深入探討該問題。 @Assembly指令
@Assembly指令用於將某個程式集連結到當前頁面,使其類和介面可以在該頁面上使用。在ASP.NET編譯該頁時,會有幾個預設的程式集被連結進去。因此,只有在需要連結一個非預設程式集時,才應使用該指令。表3.8列出了自動提供給編譯器的.NET程式集。 【108】 表3.8 預設連結的程式集
組件檔名 |
說 明 |
Mscorlib.dll |
提供.NET Framework的核心功能,包括類型、AppDomain和運行時服務 |
System.dll |
提供另一組系統服務,包括Regex、編譯、本地方法、檔案輸入/輸出和網路 |
System.Configuration.dll |
定義了讀/寫設定檔資料的類。ASP.NET 1.x不包含該程式集 |
System.Data.dll |
定義了資料容器和資料訪問類,包括整個ADO.NET架構 |
System.Drawing.dll |
實現了GDI+功能 |
System.EnterpriseServices.dll |
提供允許被服務的組件和COM+之間進行互動的類 |
System.Web.dll |
該程式集實現了ASP.NET核心服務、控制項和類 |
System.Web.Mobile.dll |
該程式集實現了ASP.NET核心行動服務、控制項和類。.NET Framework的1.0版安裝時不包含該程式集 |
System.Web.Services.dll |
包含驅動Web服務啟動並執行核心代碼 |
System.Xml.dll |
實現了.NET Framework的XML功能 |
System.Runtime.Serialization.dll |
定義了.NET序列化功能的API。在ASP.NET 2.0應用程式中,該程式集是開發人員額外添加的最常用程式集之一。ASP.NET 3.5之前的版本沒有引入該程式集 |
System.ServiceModel.dll |
定義了Windows Communication Foundation(WCF)服務的類和結構。ASP.NET 3.5之前的版本沒有引入該程式集 |
System.ServiceModel.Web.dll |
定義了ASP.NET和AJAX需要使用的附加類。ASP.NET 3.5之前的版本沒有引入該程式集 |
System.WorkflowServices.dll |
定義了工作流程(Workflow)和WCF服務需要的類。ASP.NET 3.5之前的版本沒有引入該程式集 |
除這些程式集外,ASP.NET運行庫還會自動將 Web應用程式Bin子目錄中的程式集連結到所有頁面上。通過編輯電腦級web.config檔案中的設定,可以更改、擴充或限制預設的程式集列表。這種更改將作用於運行在該Web伺服器上的所有ASP.NET應用程式。此外,還可以編輯應用程式特定的web.config檔案,逐一對每個應用程式的程式集列表進行定製。為防止將Bin目錄中存在的所有程式集都連結到頁面,可以在根設定檔中刪除以下代碼: <add assembly="*" /> 【109】 警示:對於ASP.NET應用程式,整個配置屬性集都在電腦級進行了設定。最初,伺服器電腦上啟動並執行所有應用程式共用相同的設定。獨立的應用程式可以在其自身的web.config檔案中重寫其中的某些設定。每個應用程式可以在其根目錄放置一個web.config檔案,在應用程式特定的子目錄下放置其他特殊化的web.config副本。每一頁的設定取決於從電腦級到當前檔案夾路徑發現的所有設定檔中的全部設定。在ASP.NET 1.x中,machine.config檔案包含完整的預設設定樹。而在ASP.NET 2.0中,與Web應用程式有關的設定資料被移到了web.config檔案中,與machine.config處於同一系統檔案夾。該檔案夾叫 CONFIG,位於ASP.NET安裝路徑下:%WINDOWS%\Microsoft. Net\Framework\[version] 。 要將所需程式集連結到頁面,可使用如下文法: <%@ Assembly Name="AssemblyName" %> <%@ Assembly Src="assembly_code.cs" %> @Assembly指令支援兩個互斥屬性:Name 和Src。Name用於提示連結到頁面的程式集名稱。該名稱不能包含路徑和副檔名。Src用於指示要動態編譯並連結到頁面的源檔案路徑。 @Assembly指令可以在頁面的主體部分出現多次。事實上,對於每個要連結的程式集來說,都需要分別添加指令。Name和Src不能同時在一個 @Assembly指令中使用,但對於頁面中定義的不同指令,則可以分別選擇。 提示:雖然 Name指向的是一個已存在的且準備載入的程式集,但Name與Src在效能方面的差別很小。使用Src引用的源檔案只在首次被請求時編譯一次。 ASP.NET運行庫會將源檔案與動態編譯的程式集進行映射,並在源檔案被更改前,一直使用已編譯的代碼。也就是說,在應用程式級的首次調用過後,無論使用Name還是Src,對頁面效能的影響都是相同的。 @Import指令
@Import指令用於將指定的命名空間連結到頁面,以便所有已定義類型可以在頁面訪問,而不必使用完全限定名(fully qualified name)。例如,為建立一ADO.NET DataSet類的執行個體,可以匯入System.Data命名空間,也可以像下面這樣使用完全限定名: System.Data.DataSet ds = new System.Data.DataSet(); 【110】 一旦將System.Data命名空間引入當前頁,我們就可以像下面這樣更自然地編寫代碼: DataSet ds = new DataSet(); @Import指令的文法是自描述的: <%@ Import namespace="value" %> @Import可以在頁面主體中多次使用。 ASP.NET的@Import指令相當於C#的using語句,也相當於Visual Basic .NET的Import語句。回顧非託管的C/C++,可以說該指令所起的作用幾乎與#include指令相同。 注意:@Import只能協助編譯器解析類的名稱,並不會自動連結所需程式集。使用@Import指令可以縮短類的名稱,但倘若包含該類的程式集未被正確地連結,會引發編譯器的類型錯誤。如果程式集尚未被連結,使用“完全限定類名”也無濟於事,因為編譯器需要類型的定義。您可能已經注意到了,程式集和命名空間的名稱往往是一致的。但請記住,這純屬巧合,程式集與命名空間是完全不同的實體,分別需要相應的指令。 例如,為串連SQL Server資料庫並擷取某些無串連資料,我們需要匯入以下兩個命名空間: <%@ Import namespace="System.Data" %> <%@ Import namespace="System.Data.SqlClient" %> 我們需要System.Data命名空間以便使用 DataSet和DataTable類,而通過System.Data.SqlClient命名空間來準備並發送命令。在這種情況下,我們不需要另外連結程式集,因為System.Data.dll程式集是預設連結的。 @Implements指令
@Implements指令用於指示當前頁面實現的.NET Framework中的特定介面。介面是一組邏輯上相關的函數簽名,作為各組件暴露其函數集合的一種契約。與抽象類別(abstract class)不同,介面不提供代碼或執行功能。若在ASP.NET頁中實現某個介面,要在<script>區段中定義所需方法和屬性。 @Implements指令的文法如下所示: <%@ Implements interface="InterfaceName" %> 【111】 如果頁中需要實現多種介面,@Implements 指令可以在該頁中出現多次。注意,如果決定將所有頁的邏輯定義在單獨的檔案中,則不能使用該指令來實現介面,而要在程式碼後置類別中進行。 @Reference指令
@Reference指令用於建立當前頁與指定頁或使用者控制項間的動態連結。該功能在跨頁面通訊方面發揮著重大作用。我們可通過它來建立使用者控制項的強型別執行個體。讓我們來看一下它的文法。 @Reference指令可以多次出現在頁面中,並有兩個互斥屬性:Page和Control。這兩個屬性都用於指定源檔案的路徑: <%@ Reference page="source_page" %> <%@ Reference control="source_user_control" %> Page屬性用於指向某個.aspx源檔案,而 Control屬性包含的是.ascx使用者控制項的路徑。在這兩種情況下,被引用的源檔案都會被動態編譯進程式集中,如此一來,在編程時,可以在主動引用頁面中使用源檔案中定義的類。在運行時,ASP.NET頁面是.NET Framework類的執行個體,帶有由方法和屬性群組成的特定介面。當主動引用頁面執行時,被引用頁面變為表示.aspx源檔案的類,可以按需要對其進行執行個體化和編碼。注意,為使該指令發揮作用,被引用頁面必須與主調頁面處於一個域中。不允許跨網站調用,且Page和Control屬性只接受相對虛擬路徑。 |