頁面的處理指令
頁面指令的處理用於配置執行該頁面的運行時環境。在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,則允許當前頁面在單線程單元(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
|
提供另一組系統服務,包括正則表達式、編譯、本地方法、文件輸入/輸出和網路
|
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屬性只接受相對虛擬路徑。
|