ASP.NET Global.asax詳解

來源:互聯網
上載者:User

標籤:des   blog   http   使用   檔案   資料   

http://blog.csdn.net/xiarenwang/article/details/7633160

文檔來源:http://club.topsage.com/thread-485397-1-1.html

global.asax是一個文字檔,它提供全域可用代碼。這些程式碼封裝括應用程式的事件處理常式以及會話事件、方法和靜態變數。有時該檔案也被稱為應用程式檔案。

global.asax 檔案中的任何代碼都是它所在的應用程式的一部分。每個應用程式在其根目錄下只能有一個global.asax檔案。然而,這個檔案是可選的。如果沒有global.asax檔案,應用程式將對所有事件應用由 HttpApplication類提供的預設行為。

提示:經典ASP有一個與global.asax類似格式和構造的,名為global.asa的檔案。實際上,如果將一個正在啟動並執行global.asa檔案代碼複製到global.asax中,應用程式同樣可以運行。

當應用程式啟動並執行時候,global.asax的內容被編譯到一個繼承自HttpApplication類的類中。因此,HttpApplication類中所有的方法、類和對象對於應用程式都是可用的。

CLR 監控著global.asax的變化。如果它察覺到這個檔案發生了改變,那麼將自動啟動一個新的應用程式複本,同時建立一個新的應用程式定義域。原應用程式定義域當前正在處理的請求被允許結束,而任何新的請求都交由新應用程式定義域來處理。當原應用程式定義域的最後一個請求處理完成時,這個應用程式定義域即被清除。這有效保證了應用程式可以重新啟動,而不被任何使用者察覺。

為防止應用程式使用者下載應用程式而看到原始碼,ASP.NET預設配置為阻止使用者查看global.asax的內容。如果有人在瀏覽器輸入以下URL:

http://localhost/progaspnet/Global.asax

這將會收到一個403(禁止訪問)錯誤資訊或者類似的資訊如:

This type of page is not served。

提示:簡單而言,web.config檔案與global.asax有些類似的地方。如果這個檔案被更改,應用程式將自動“重啟”。同樣,也不可能在瀏覽器中查看web.config檔案。

Global.asax檔案從外觀和結構上與分頁檔(.aspx)相似。它可以有一個或多個部分,簡要描述如下:

l 指令

l 指令碼塊

l Object聲明

正如Web頁和Web服務能夠使用程式碼後置功能,global.asax同樣也可以。然而,與Web頁和Web服務的條件有所不同,VS2005預設狀態下不對global.asax使用程式碼後置功能。

提示:Visual Studio 2005預覽版預設對global.asax使用程式碼後置模型。目前仍然支援程式碼後置,但不是預設使用。

為了對global.asax使用程式碼後置技術,可使用位於該檔案頭部的Application指令(類似於分頁檔的Page指令,下一節將詳細介紹)的Inherits屬性,該屬性指向global.asax.cs中的程式碼後置類別。

同時,也有一個CodeBehind屬性用來指向程式碼後置檔案。然而,如果它指向的是一個位於App_Code檔案夾以外的位置,那麼必須對這個類檔案進行手動編輯。

通過按右鍵方案總管中的網站或者單擊網站菜單,然後選擇“Add New Item...”,接著選擇全域應用程式類,可以為Web應用程式添加一個global.asax檔案。保留預設名稱global.asax。

VS2005將建立一個如樣本18-1所列的檔案。模板中包括對以下5個事件的空白聲明:Application_Start、Application_End、Session_Start、Session_End和Applica- tion_Error。

樣本18-1:global.asax模板

< %@ Application Language="C#" %>

在樣本18-2所列舉的global.asax檔案中,為應用程式狀態設定了一些值,同時,在每次應用程式啟動的時候向記錄檔寫一個條目。為了使用這個樣本,需要保證ASP.NET帳戶對根目錄c:\具有寫入許可權(在產品系統中不推薦)。

樣本18-2:global.asax樣本

< %@ Application  Language="C#"%>

指令

與Web頁和Web服務檔案相比,global.asax可以以多個指令作為開始。這些指令在處理ASP.NET檔案時指定應用程式編譯的設定。與Page指令相比,Application指令可

接受一個或者多個具有字典結構的屬性/值對。此處支援三個指令:Application、Import和Assembly。

Application  Application指令設定編譯器的應用程式專用屬性。以下是一個Application指令樣本:

< %@ Application  Language="C#" Inherits="WebServiceConsumer.Global"

Description="A sample application" %>

Language 屬性可以設定為任何一種標準語言名稱:VB、C#、JS、或VJ#,它們分別對應VB2005、C#、JScript.NET或J#。(可以使用任何一種支援.NET平台的第三方語言)預設值為C#。此處的Language設定的是語言專門用於global.asax檔案,而非其他應用程式代碼檔案。例如,可以完全合法地在global.asax檔案中使用C#,在.aspx檔案中使用VB2005,相反亦然。

Inherits屬性指定所繼承類名,具有代表性的如程式碼後置檔案中的類。

Description屬性接受對應用程式的文本描述,而分析器和編譯器將會忽略它。

CodeBehind屬性在Visual Studio .NET(非VS2005)中用來指定包含的程式碼後置檔案。

Import  Import指令僅包括一個Namespace屬性。所指定名字空間被明確地匯入應用程式中,使其所有的類和介面都可用。匯入的名字空間可以是.NET Framework的一部分或者使用者自訂的名字空間。

以下是一個典型的Import指令:

< %@ Import Namespace="System.Data" %>

只能有一個Namespace屬性。如果需要匯入多個名字空間,那麼需要使用多個Import指令。

下列名字空間自動匯入到所有的Web應用程式中,所以沒必要使用Import指令。

l System

l System.Collections

l System.Collections.Specialized

l System.Configuration

l System.IO

l System.Text

l System.Text.RegularExpressions

l System.Web

l System.Web.Caching

l System.Web.Security

l System.Web.SessionState

l System.Web.UI

l System.Web.UI.HtmlControls

l System.Web.UI.WebControls

Assembly  Assembly指令用於在編譯過程中將一個程式集連結到當前應用程式。這樣可以使所有程式集的類與介面對應用程式都是可用的。

提示:典型的程式集是.dll或.exe檔案,這將在下一章中詳細講解。

由於在編譯時間引用程式集,所以可以使用Assembly指令綁定程式集,然後在運行時將其載入到應用程式集區中。

位於應用程式集緩衝(也就是位於bin目錄和App_Code目錄中的代碼檔案)中的程式集可自動連接到應用程式。因此,任何位於bin目錄的程式集,或者由App_Code目錄中的代碼編譯而來的任何程式集,都不需要使用Assembly指令實現串連。

Assembly指令包括兩個屬性:Name和Src。Name屬性是一個字串,表示串連到應用程式的程式集名字,它不能包含路徑。Src屬性則是指向源檔案的路徑(只能為相對路徑),這些檔案將被動態編譯和串連。

每個程式集指令只能有一個屬性。如果需要串連多個程式集,則應使用多個Assembly指令。

Assembly指令類似於:

< %@ Assembly %>

< %@ Assembly Src="sources/SomeSourceFile.cs" %>

指令碼塊

典型的global.asax檔案中包含大量代碼,這些程式碼封裝含在以script標籤起止的指令碼塊中:

如果使用程式碼後置,雖然程式碼後置檔案中的代碼本身沒有附加script標籤,但包含在程式碼後置檔案中的代碼與指令碼塊中的代碼是等效的。

指令碼塊中的代碼可以包含事件處理常式或者方法,下文將對此進行講解。

事件

如同Web頁和控制項可以公開事件一樣,應用程式中的Application對象和 Session對象也能夠公開事件。這些事件能被global.asax檔案或指定的檔案中的事件處理常式處理。例如,當應用程式開始執行時,觸發 Application_Start事件;當應用程式結束時,觸發Application_End事件。Application的某些事件是每當頁面請求時觸發,而其他一些事件,例如Application_Error,則僅在特定情況下觸發。

樣本18-2中的global.asax檔案代碼說明了Application_Start 和Application_End事件。樣本18-2中的Application_Start事件設定了兩個Application屬性:一個是名為 strConnectionString的字串,一個是名為arBooks的字串數組。事件處理常式方法調用一個名為WriteFile的輔助方法,它包含在global.asax檔案中。該輔助方法將一個字串寫入記錄檔中。以下是樣本18-2中的WriteFile方法代碼:

void WriteFile(string strText)

{

System.IO.StreamWriter writer =

new System.IO.StreamWriter(@"C:\test.txt",true);

string str;

str = DateTime.Now.ToString(  ) + "  " + strText;

writer.WriteLine(str);

writer.Close(  );

}

WriteFile 是一個簡單的記錄日誌的方法。該方法初始化一個基於文字檔的 StreamWriter對象,並對c:\test.txt進行寫入程式碼。它在檔案中添加了一個時間戳記,並寫入通過方法傳遞的字串。 StreamWriter方法的布爾值參數為true,其表示如果檔案已經存在,那麼將文本行追加到檔案中。如果檔案不存在,則建立一個檔案。

Application_End事件處理方法調用了另一個WriteFile方法,它添加了一個日誌條目以記錄應用程式結束。

為了查看這兩個事件處理常式的結果,可對global.asax進行一些無意義的編輯,並儲存檔案。此時將強制結束應用程式。然後請求虛擬目錄中的任意URL地址。例如,使用上一章中的一個網頁——實際上無論哪一個——或者一個自己建立的網頁。樣本18-3顯示了記錄檔內容。

樣本18-3:Test.txt摘錄

8/26/2006 5:46:23 PM  Application Starting

8/26/2006 6:13:35 PM  Application Ending

8/27/2006 10:17:39 PM  Application Starting

8/27/2006 10:18:23 PM  Application Ending

8/27/2006 10:18:36 PM  Application Starting

如同Application對象的Start和End事件一樣,Session對象也擁有Session_ Start和Session_End事件。這將允許應用程式每次啟動和結束過程中為每個會話都運行代碼。

如樣本18-4中高亮顯示的方法名所示,其包括了global.asax檔案中所有可能的應用程式事件處理常式。在頁面請求被接受、處理和呈現過程中,可以容易地查看應用程式生命週期。

樣本18-4:Global.asax事件說明

< %@ Application  Language="C#" %>

以下是頁面請求觸發的所有事件,以觸發順序排序:

Application_BeginRequest

當ASP.NET開始處理每個請求時觸發。在這個事件處理中的代碼將在頁面或者服務處理請求之前執行。

Application_AuthenticateRequest

在驗證請求之前觸發。(正如第12章介紹的,驗證是確認使用者就是他所說的那個人的過程)在這個事件處理常式的代碼中允許實現自訂安全管道。

Application_AuthorizeRequest

在為請求授權之前觸發。(授權是確定是否請求使用者具有訪問資源的許可權的過程,在

第12章已經介紹過)在這個事件處理常式的代碼中允許實現自訂安全管道。

Application_ResolveRequestCache

在ASP.NET確定是否應該產生新的輸出,或者由緩衝填充前觸發。無論何種情況,都將執行該事件處理常式中的代碼。

Application_AcquireRequestState

在擷取工作階段狀態之前執行。

Application_PreRequestHandlerExecute

在將請求發送到服務於請求的處理常式對象之前觸發。當事件觸發後,頁面將由HTTP處理常式處理請求。

Application_PostRequestHandlerExecute

當HTTP處理常式與頁面請求一起完成時觸發。此時,Response對象將獲得由用戶端返回的資料。

Application_ReleaseRequestState

當釋放和更新試圖狀態時觸發。

Application_UpdateRequestCache

如果輸出被緩衝,那麼緩衝更新時將觸發。

Application_EndRequest

當請求結束時執行。

Application_PreSendRequestHeaders

在向用戶端發送HTTP頭之前觸發。如果啟用響應緩衝,這意味著直到所有資料都準備好(預設條件),都不會發送任何資料。該事件總是在Application_EndRequest事件之後。如果禁用響應緩衝,那麼無論何時將資料發送給用戶端,都將觸發該事件。響應控制由Page指令的一個屬性,或者Web服務的WebMethod屬性控制。

Application_PreSendRequestContent

向用戶端發送HTTP內容之前觸發。和Application_PreSendRequestHeaders事件一樣,Application_PreSendRequestContent事件能否被觸發取決於響應緩衝是否可用。

以下列舉應用程式事件,它們在特定條件下觸發:

Application_Start

當應用程式啟動時觸發。當首次請求應用程式虛擬目錄中的任何頁面時,將啟動應用程式,同時如果應用程式已經運行,則不觸發該事件。

Application_End

應用程式結束時觸發。無論何時修改了設定檔(global.asax、global.asax.cs、

global.asax.vb或者web.config),或者伺服器崩潰或者重啟,應用程式都將結束。通常在該事件處理常式中執行清除功能的代碼,例如關閉資料庫連接。

Session_Start

每個會話開始時觸發,這是放置具體會話代碼的地方。

Session_End

會話結束時觸發。它為儲存儲存在會話中的任何資料提供了機會。

Application_Disposed

當CLR從記憶體中移除應用程式時觸發。

Application_Error

無論在應用程式中何時何處發生未處理的錯誤都將觸發。它提供了一個實現跨平台 app程式錯誤處理的好機會。

使用try...catch語句塊能夠在代碼中處理特定錯誤,也可以使用Page指令的ErrorPage屬性來捕獲頁面級錯誤。使用這些方式處理任何錯誤都不會觸發Application_Error事件。

為了測試新版的global.asax,在樣本18-5中建立一個網頁。查看GlobalEvents網站。當該網頁運行時,將看到18-4所示的頁面。

樣本18-5:GlobalEvents網站的default.aspx

< %@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs"

Inherits="_Default" %>

"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

Global Events

Text="End Session"

OnClick="btnEndSession_Click" />

Text="Generate Error"

OnClick="btnError_Click" />


圖18-4:GlobalEvents

18-4所示,可看到觸發了一系列應用程式事件。在這些事件執行的中途,呈現了.aspx頁面自身,接著是另一些應用程式事件。

警告:樣本GlobalEvents必須在一個真實的IIS虛擬路徑下才能良好運行。

頁面第一次顯示時觸發Session_Start事件,而在隨後的顯示中則不再觸發該事件。 這是因為請求是相同的會話。單擊“End Session”按鈕,調用Session.Abandon方法,這將結束當前會話。下一次頁面被提交到伺服器時,將再次觸發Session_Start 事件。

Post按鈕提供了一個簡單的再次提交頁面的方法。

樣本18-4中大部分的應用程式事件處理常式都使用了Response.Write方法,以便顯示觸發的事件。然而,Application_Start和Application_End方法調用了WriteFile方法。如果在這些事件處理常式中試圖使用Response.Write方法,那麼在頁面中將不會

顯示。因為那時用於呈現的頁面會話還沒有運行。但是,當檢查記錄檔c:\test.txt時,將看到應用程式啟動和結束所顯示的條目。

樣本18-4所示的global.asax檔案說明了一種使用Application_Error事件的方法。以下列舉了這些代碼:

protected void Application_Error(Object sender, EventArgs e)

{

string strError;

strError = Server.GetLastError(  ).ToString(  );

if (Context!= null)

  Context.ClearError(  );

Response.Write("Application_Error" + "

");

Response.Write("Error Msg: " + strError + "

" +

  "End Error Msg

");

}

該事件處理常式使用HttpServerUtility對象的GetLastError方法,以報告最後出現的錯誤。這個錯誤被轉換為一個字串,並被指定給一個字串變數:

strError = Server.GetLastError(  ).ToString(  )

接下來調用HttpContext對象的ClearError方法來清除目前HTTP請求中的所有錯誤:

Context.ClearError(  )

如果沒有將錯誤清除,那麼錯誤將顯示在用戶端瀏覽器,並且還是無法看見Respons- e.Write方法的顯示結果。

最後,Response.Write方法顯示一個資訊,當前的錯誤將顯示在用戶端。

另一種向使用者報告錯誤的方式是顯示自訂錯誤處理頁面。為此,需要使用以下程式碼替代Application_Error事件處理常式中的Response.Write方法:

Response.Redirect("CustomErrorPage.aspx?Msg=" +

  Server.UrlEncode(strError));

以上程式碼調用HttpServerUtility對象的UrlEncode方法,其將錯誤資訊作為一個QueryString參數傳遞給CustomErrorPage.aspx頁面中的自訂錯誤處理代碼。 CustomErrorPage.aspx頁面有一個名為lblMessage的Label控制項。以下是頁面中的Page_Load方法代碼:

void Page_Load(Object Source, EventArgs E)

{
lblMessage.Text = Request.QueryString["Msg"];
}

Default.aspx中的Generate Error按鈕故意觸發一個錯誤,以便查看錯誤處理。該按鈕的單擊事件處理常式的代碼如下所示,它將除零異常:

protected void btnError_Click(object sender, EventArgs e)

{

int a = 5;

int b = 0;

int c;

c = a / b;

}

伺服器端包括

使用伺服器端包括能夠實現在應用程式中包含外部原始碼檔案。在編譯之前,包括檔案中的代碼將被添加到global.asax檔案中。儘管應用程式的語言可能與包括檔案的語言不同,但是用於包括檔案的語言必須與global.asax檔案所使用的語言匹配。

下面是用於伺服器端的文法:

在這個句法中,PathType類型可以是表18-1所示之一。

表18-1  PathType屬性

路徑類型 說  明
File 檔案名稱是包含global.asax檔案的目錄的相對路徑
Virtual 檔案名稱是包含網站虛擬目錄的虛擬路徑



查看樣本18-4所示的global.asax檔案,將下面的代碼添加到第二行中:

建立一個新的名為IncludeFile.cs的文字檔,將該檔案和global.asax儲存在同一目錄下。這個檔案需要與global.asax檔案一樣的一對指令碼標籤。

將global.asax頁面中的WriteFile方法複製到包括檔案中,然後注釋(或者刪除)global.asax頁面中的WriteFile方法。這樣包括檔案應類似於樣本18-6。

樣本18-6:具有包括檔案的global.asax

如果運行任意一個網頁,那麼將不會與先前有什麼區別,因為您所做的只是把一個檔案中的代碼轉移到另外一個檔案中。

如果CLR監視global.asax檔案的變化,並和重新啟動應用程式一樣,CLR也監視組件括檔案的變化。如果包括檔案發生變化,那麼應用程式也會重新啟動。

對於在多個應用程式中所包括的相同標準代碼而言,包括檔案非常有用。這些通用代碼可能包括資料庫存取方法、寫入日誌記錄、錯誤處理管道、登入或者每個應用程式的基礎類型程式碼片段。

對象聲明

在global.asax檔案中包括代碼的另一個方法是是聲明object標籤。這些聲明的靜態對象要麼是Application,或者是Session對象。這樣就可以在應用程式或者每個會話過程中使用。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.