標籤: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對象。這樣就可以在應用程式或者每個會話過程中使用。