Download presentation
Presentation is loading. Please wait.
1
Chapter 7 網頁應用程式與狀態管理
2
本章提要 7 - 1 代表整個網頁的 Page 物件 7 - 2 ASP.NET 網頁的存留週期與 Page 事件
7 - 3 連線要求與回應的 Request、Response 物件 7 - 4 網頁的狀態與 ViewState 7 - 5 使用 Cookie 將狀態儲存在用戶端 7 - 6 使用 Session 於連線時保存狀態
3
本章提要 7 - 7 Application 物件-在所有使用者間保存狀態 7 - 8 各狀態管理方式的比較
7 - 9 Global.asax-ASP.NET 應用程式檔
4
7 - 1 代表整個網頁的 Page 物件 ASP.NET 執行網頁時, 會使用 .NET Framework 的 Page 類別衍生代表網頁的類別, 並產生此網頁物件 (以下簡稱 Page 物件) 以回應用戶端要求。 前面章節中已經用過 Page 物件了, 例如第 2 章以 Page.Title 修改網頁標題、第 3 章使用 Page_Load 事件處理程序、第 6 章使用 Page.IsValid 檢查驗證是否通過。
5
代表整個網頁的 Page 物件 本節會說明 Page 物件其他重要屬性與方法, 以及網頁載入時, Page 物件會產生的事件與相對應的處理程序。
6
Page 物件重要屬性與方法 下表列出 Page 物件的重要屬性與方法:
7
檢查是否為 PostBack 前面 4-6 節曾經提到 PostBack 的觀念, 而 Page.IsPostBack 屬性便是用來檢查連線是否為 PostBack, 若 Page.IsPostBack 屬性為 False, 則表示用戶端是第一次連線, 如果為 True, 便代表網頁是因為 PostBack 而重新被執行:
8
檢查是否為 PostBack
9
檢查是否為 PostBack 所以只有第一次連線時, Page.IsPostBack 屬性值才會是 False, 而從上面步驟 3 之後, Page.IsPostBack 的屬性值便會是 True。 有時候我們會在網頁第一次連線時進行變數或控制項的初始化;或開啟檔案、連線資料庫取得程式所需資料, 此時便可以藉由檢查 Page.IsPostBack 屬性來避免重複執行這些動作。
10
檢查是否為 PostBack 假設要製作一個網頁程式如下:
11
檢查是否為 PostBack 功能 1、2 需要在網頁載入時執行, 不過功能 1 會在網頁『每次』載入時隨機選一本書, 而功能 2 只需要在網頁『第一次』載入時取得所有書籍資料, 之後直接使用即可, 不必每次載入時重複執行, 所以程式只要在 Page.IsPostBack = False 時才產生列表即可。
12
檢查是否為 PostBack 瞭解程式設計的方式後, 請如下在 Web Form 建立控制項並設定屬性:
13
檢查是否為 PostBack 然後請建立 Page_Load 事件處理程序, 在其中輸入以下程式碼:
14
檢查是否為 PostBack
15
檢查是否為 PostBack 因為尚未介紹檔案與資料庫的存取方式, 所以在第 12 行先以陣列儲存書籍名稱, 並於第 16 行將之加到 CheckBoxList1 控制項中。 Page.IsPostBack 屬性除了以上用途外, 也可以用於檢查網頁是否因為 PostBack 而被載入 (亦即非第一次連線), 使用方式就依照程式的需要而定。
16
7 - 2 ASP.NET 網頁的存留週期與 Page 事件
17
Page 的存留週期與事件 當我們連線 ASP.NET 網頁時, 伺服器端會有一連串處理過程, 處理完畢後才會將網頁送出, 這一連串的處理過程便稱為 ASP.NET 網頁的存留週期。 存留週期的不同階段會產生不同的 Page 事件:
18
Page 的存留週期與事件
19
Page 的事件處理程序 因為網頁處理過程會產生許多相關的 Page 事件, 所以我們可以如下建立 Page 各事件的處理程序, 便能依照不同需求在各個階段進行處理:
20
Page 的事件處理程序 由於順序先後緣故, 較早觸發的 Page 事件處理程序所做的動作, 有可能會被順序較後的程序修改與覆蓋。
例如在 Page_Load 事件處理程序設定 Label1.Text 為 "abc", 但是某個 Button 的 Click 事件處理程序卻設定 Label1.Text 為 "123", 從上表可以看到『處理事件』的順序晚於『載入』, 所以 Label1.Text 屬性會被覆蓋為 "123"。
21
Page 的事件處理程序 下面例子將示範各 Page 事件產生的順序, 請先在設計模式下放置一個 Label 控制項 (ID = "Label1"), 然後如下設計各事件的處理程序:
22
Page 的事件處理程序
23
Page 的事件處理程序 在瀏覽器檢視執行結果:
24
7 - 3 連線要求與回應的 Request、Response 物件
取得用戶端瀏覽器的資訊 使用 Response 物件處理回傳內容
25
Request、Response 物件的意義
下圖是用戶端以瀏覽器讀取網頁時的連線過程:
26
Request、Response 物件的意義
從上面可以看到讀取網頁時包含了用戶端的要求 (Request) 與伺服器的回應 (Response), 所以 ASP.NET 中分別以 Request 與 Response 兩個物件來代表這兩個連線。
27
Request、Response 物件的意義
當用戶端要求連線時, 會將本身的資訊, 例如 IP 位址、瀏覽器名稱及版本...等, 一起傳送給伺服器, 所以 Request 物件即包含了這些用戶端資訊可供程式運用。 至於 Response 物件則處理伺服器要回傳給用戶端的內容, 所以程式中可以利用 Response 物件輸出要傳送給瀏覽器的內容、或是將連線導向到其他網頁...等。
28
使用 Request 物件讀取用戶端資訊 下表是 Request 物件的重要屬性:
29
使用 Request 物件讀取用戶端資訊 以下範例示範如何讀取用戶端的資訊, 請先在設計模式下放置一個 Label 控制項 (ID = “Label1”), 然後建立 Page_Load 事件處理程序, 輸入如下程式碼:
30
使用 Request 物件讀取用戶端資訊
31
使用 Request 物件讀取用戶端資訊 執行結果:
32
使用 Request 物件讀取用戶端資訊 Request.Url 與 Request.UrlReferrer 屬性內都是 System.Uri 類別的物件, 所以程式第 10 行使用 ToString 方法將其轉換為字串, 才能將網址放入 Label1.Text。
33
取得用戶端瀏覽器的資訊 Request.Browser 屬性包含了用戶端瀏覽器的相關資訊, 因為瀏覽器的資訊相當多, 所以 Request.Browser 內分成數個屬性以代表各資訊。 下面將以實例說明這些屬性的使用方法, 請先在設計模式下放置一個 Label 控制項 (ID = "Label1"), 然後建立 Page_Load 事件處理程序, 如下輸入程式碼:
34
取得用戶端瀏覽器的資訊
35
取得用戶端瀏覽器的資訊 執行結果:
36
取得用戶端瀏覽器的資訊 程式第 17 行使用 Request.Browser.EcmaScriptVersion 屬性取得瀏覽器所支援的 ECMAScript 版本, ECMAScript 是 Ecma International 組織所制訂的 JavaScript 標準版, 所以若此屬性的值大於等於 1, 便表示瀏覽器支援 JavaScript。 另外此屬性為 System.Version 類別的物件, 所以必須使用 ToString 方法將其轉換為字串, 才能放入 Label1.Text。
37
使用 Response 物件處理回傳內容 Response 物件是用來處理伺服器要回傳給用戶端的內容, 所以可使用此物件設定字元編碼、取得 HTTP 狀態碼...等。 第 3 章我們曾經使用 Response.Write() 方法將字串輸出給用戶端, 此處將說明如何使用 Response.Redirect() 將用戶端導向其他網頁, 稍後章節則會說明使用 Response.SetCookie() 設定 Cookie 的方法。
38
使用 Response 物件處理回傳內容 至於其他 Response 物件的屬性與方法因使用的機率較少, 所以請自行參考線上說明的『HttpResponse 成員』段落。 Response.Redirect() 的用法相當簡單, 只要使用 Response.Redirect ("網址") 即可將用戶端導向其他網頁, 前面 5-3 節便曾經使用 Response.Redirect(), 此處再以一個例子說明其使用方法。
39
使用 Response 物件處理回傳內容 請如下建立控制項並設定屬性:
40
使用 Response 物件處理回傳內容 請在設計模式下雙按各按鈕建立 Button1_Click、Button2_Click、Button3_Click 程序, 在其中輸入以下程式碼即可:
41
使用 Response 物件處理回傳內容
42
使用 Response 物件處理回傳內容 在瀏覽器檢視執行結果:
43
7 - 4 網頁的狀態與 ViewState HTTP 協定的 Stateless 特性 ViewState 的運作原理
44
HTTP 協定的 Stateless 特性 由網頁的存留週期可知, 一個網頁從開始到卸載, 其生命其實在伺服器送出後便已經結束。
在 HTTP 通訊協定中, 並沒有設計保存連線狀態的能力 (Stateless Connection), 雖然我們在瀏覽器連線網站時, 有『上一頁』、『下一頁』、『回傳』等動作, 但是對伺服器而言, 每次要送出的網頁都是重新建立 (不論是否同一頁)。
45
HTTP 協定的 Stateless 特性 所以每個 HTTP 連線之間都是獨立互不相干, 使用者輸入的資料, 或是網頁程式所產生的變數值, 都無法被保留下來 可以想見, Stateless 特性對於網頁程式的設計來說非常地不便, 所以便發展出許多技術將狀態保留下來, 以供後續連線繼續使用。 本節將先介紹 ASP.NET 的 ViewState (檢視狀態), 後面章節會說明 Cookie、Session 與 Application 等各種方法。
46
ViewState 的運作原理 ViewState 是 ASP.NET 用來在同一網頁的前後連線間保留狀態的方法, 7-5 頁的表格中提到在網頁『載入』(Page_Load) 前, 會『還原連線狀態』, 就是指 ASP.NET 會讀取 ViewState, 然後一一還原控制項或變數的屬性與內容。
47
ViewState 的運作原理 ViewState 使用網頁上的隱藏欄位來儲存狀態, 請任意執行一個 ASP.NET 網頁, 然後在瀏覽器中執行『檢視 / 原始碼』命令, 觀察瀏覽器收到的網頁內容:
48
ViewState 的運作原理 以下是 ViewState 的運作示意圖:
49
ViewState 的運作原理 從上面可以看到, ViewState 其實隱含在網頁原始碼中, 在連線中被交相傳遞。
但是缺點則是較不安全, 資料可能會被使用者檢視或惡意者攔截;而且資料量一多的話, 會造成網頁的大小遽增, 可能會影響傳輸的效率。
50
存取 ViewState ViewSt ate 可以用來儲存控制項的狀態或是程式內部所需的資料, 一般而言控制項的狀態都是由 ASP.NET 自動管理, 不需要特意去修改或設定。 如果想將程式內部的資料儲存於 ViewState, 可透過網頁的 ViewState 屬性, 語法如下:
51
存取 ViewState 設定的範例如下: 若要讀取 ViewState 屬性中某一變數的值, 只要引用『ViewState (“變數名稱”)』即可直接存取。 下面例子示範 ViewState 屬性的存取方式:
52
存取 ViewState
53
存取 ViewState
54
存取 ViewState 執行結果:
55
存取 ViewState 第 11 行檢查 ViewState ("x") 是否存在, 若否便進行初始化。雖然本程式的狀況下, 沒有初始化時亦可使用, 不過基於嚴謹的程式設計態度, 建議您仍然應該進行初始化。
56
使用 ViewState 儲存資料 有時候網頁程式可能會需要某些資料持續保留, 以便讓後續的連線可以使用, 此時便可以使用 ViewState 來記錄資料。 例如下面是一個讓使用者猜數字的程式:
57
使用 ViewState 儲存資料 這個程式必須在網頁第一次載入時產生一個亂數, 然後使用者每次輸入數字後, 比較大小並顯示相關訊息, 所以第一次連線產生的亂數, 必須讓後續連線都可以繼續使用, 否則每次連線都產生一個新數字, 將讓使用者無從猜測。 下面將以上述程式為例, 示範如何使用 ViewState 儲存資料, 請如下建立控制項並設定屬性:
58
使用 ViewState 儲存資料
59
使用 ViewState 儲存資料 然後在設計模式下雙按網頁空白處以及 Button1、Button2 按鈕, 建立 Page_Load、Button1_Click、Button2_Click 程序, 在其中輸入以下程式碼:
60
使用 ViewState 儲存資料
61
使用 ViewState 儲存資料
62
使用 ViewState 儲存資料
63
使用 ViewState 儲存資料 在瀏覽器檢視執行結果:
64
7 - 5 使用 Cookie 將狀態儲存在用戶端 本節將說明 Cookie 的原理, 以及如何使用 Cookie 將狀態記錄在用戶端。
65
Cookie 的運作原理 Cookie 是一種將狀態記錄於用戶端的技術, 下面是其運作的示意圖:
66
Cookie 的運作原理 當程式請用戶端儲存 Cookie 時, 只要瀏覽器支援 Cookie 而且使用者未關閉此功能, 瀏覽器就會依照程式的要求, 將變數與變數值儲存於用戶端電腦內 (格式為純文字檔), 使用者對伺服器的後續連線便會持續地帶有 Cookie, 讓程式可以取回先前保存的值:
67
Cookie 的運作原理
68
Cookie 的運作原理 因為 Cookie 儲存在用戶端電腦上, 只要使用者不將之刪除, 資料即可保留一段時間, 不會因為關閉瀏覽器而消失, 而且多個網頁之間也可以共享資料。 使用 Cookie 最常見的例子便是購物網站, 許多購物網站會使用 Cookie 製作購物車, 當使用者將產品放入購物車之後, 程式就會將資料寫入 Cookie 。
69
Cookie 的運作原理 如此就算關閉瀏覽器或是電腦, 未來使用者只要仍以同一電腦環境連上購物網站, 程式便可由 Cookie 取回前次選取的商品, 將購物車恢復為上次的狀態。 使用 Cookie 時有以下的限制: 如同 Cookie 的英文原意:小餅乾, 大多數瀏覽器會限制 Cookie 最大不得超過 4096 Bytes, 所以 Cookie 只適合用來存放小型資料, 如使用者名稱、帳號、上次到訪時間...等。
70
Cookie 的運作原理 多數瀏覽器只允許每個網站儲存 20 個 Cookie, 若超過就會蓋掉舊的 Cookie。
71
存取 Cookie 的方式 從前面 Cookie 運作示意圖可以看到, 伺服器透過 Response 連線送出 Cookie 請用戶端儲存;而用戶端則透過 Request 連線傳回 Cookie 。 所以程式要由 Response 物件寫入 Cookie, 然後由 Request 物件讀取 Cookie 資料。 下面是基本的 Cookie 存取語法:
72
存取 Cookie 的方式 Cookie 可以設定到期日, 到期之後該 Cookie 會被刪除而消失。
73
存取 Cookie 的方式 上面語法中, Now 屬性會取得目前伺服器上的日期與時間, 其 AddDays() 方法則可計算距今數天的日期, 例如 Now.AddDays(30) 就是 30 天之後的日期, Now.AddDays(-1) 便是昨天的日期。 所以如果想要刪除 Cookie, 只要使用『昨天』設定到期日即可。如果希望 Cookie 永遠有效不過期, 可設定到期日為距今 50 年後。
74
存取 Cookie 的方式 寫入 Cookie 之後, 可使用下面格式讀取 Cookie 資料:
75
存取 Cookie 的方式 讀取 Cookie 時, 如果該 Cookie 尚未設定, ASP.NET 會傳回例外錯誤而導致程式中止執行, 所以建議使用下面語法判斷該 Cookie 是否存在, 確定存在再進行讀取的動作:
76
在同一網頁中讀寫 Cookie 下面例子示範在同一網頁中讀寫 Cookie 的方式:
77
在同一網頁中讀寫 Cookie
78
在同一網頁中讀寫 Cookie 執行的結果如下:
79
在同一網頁中讀寫 Cookie 重新整理網頁
80
在同一網頁中讀寫 Cookie 如果您繼續重新整理網頁, 會發現時間一直變動, 如果您希望等使用者關閉視窗下次連線才算重新到訪, 可參考後面 Ch07-10.aspx 改用 Session 物件判斷連線狀態。
81
在不同網頁間讀寫 Cookie 預設同一網域下的網頁可以存取同一 Cookie, 所以同網站的不同網頁可存取同一組 Cookie 設定, 意即 A 網頁使用 "Response.Cookies ("abc").Value" 所建立的 Cookie, 同網站內的 B 網頁只要使用 Request.Cookies ("abc").Value 即可讀取其值, 而且也可以進行修改。
82
在不同網頁間讀寫 Cookie 請複製前面 Ch07-08.aspx 的程式碼, 在同網站下建立一個 Ch07-09.aspx 檔案, 然後在瀏覽器中檢視執行結果, 即可看到同網站下不同網頁存取同一組 Cookie 的情形:
83
7 - 6 使用 Session 於連線時保存狀態 Session 的意義 Session 的運作原理 使用 Session 存取資料的方法
判斷是否為新連線
84
Session 的意義 ASP.NET 的線上說明中將 Session 翻譯為 『工作階段』, 一個 Session 代表使用者開啟瀏覽器連線網站, 一直到關閉瀏覽器為止的工作期間。 所以重新開啟瀏覽器便是一個新的 Session, 而開啟兩個瀏覽器視窗則為兩個獨立的 Session:
85
Session 的意義
86
Session 的意義 當網頁程式使用 Session 技術儲存狀態或資料時, 不論是否為相同頁面, 只要在同一個 Session 內即可存取同一份資料。 但若是不同 Session, 就算在同一部電腦使用相同瀏覽器連線相同網頁讀寫同一名稱的資料, 其所存取的仍是兩份獨立不同狀態的資料。
87
Session 的運作原理 Session 是一種將資料記錄於伺服器的技術, 下面是其運作的示意圖:
88
Session 的運作原理 SessionID 就像一把鑰匙, 上面可以看到程式必須以 SessionID 來存取狀態與資料, 一般情況下, SessionID 會存放在沒有到期日的 Cookie 內 (但是其他 Session 資料皆儲存於伺服器上), 所以同一個網站的相同與不同網頁之間可以藉由 Cookie 掌握同一個 SessionID, 進而存取同一份資料。
89
Session 的運作原理 不過因為 Cookie 沒有到期日, 代表其在連線結束時會自動刪除, 因此關閉瀏覽器後重新連線同一網站, 得到的便是新的 SessionID。 Session 內的資料預設會存放於伺服器的記憶體, 與 Cookie 不同, 所以較為安全, 不易被檢視或竄改, 因此可以用來儲存重要的狀態或資料。
90
Session 的運作原理 此外, 因為 Session 是隨著瀏覽器的開啟與關閉而生滅的機制, 而且將資料記錄在伺服器而非用戶端, 所以相當適合使用在會員登入、購物結帳...等各網頁需要共享機密或重要資料, 而且每次連線都會因狀況不同而必須儲存不同資料的場合。
91
使用 Session 存取資料的方法 雖然 Session 必須藉由 SessionID 來存取資料, 不過 ASP.NET 會自動處理 SessionID 的取得、建立、傳送等工作, 所以程式中可以直接透過網頁的 Session 屬性存取資料, 不需要特別處理 SessionID 的相關事宜。
92
使用 Session 存取資料的方法 下面是使用 Session 儲存資料的語法:
93
使用 Session 存取資料的方法 下表為 Session 物件的常用屬性:
94
使用 Session 存取資料的方法 ASP.NET 預設會啟用網站的 Session 功能, 當用戶端第一次連上網站時, 伺服器便會建立一個新的 Session 物件, 所以第一次連線的 Session.IsNewSession 為 True, 而後的連線則沿用同一個 Session 物件, 故 Session.IsNewSession 的值便都是 False。
95
使用 Session 存取資料的方法 如果使用者沒有任何動作, 預設 20 分鐘之後 Session 會自動失效並被刪除。如果想要延長或縮短 Session 的有效時間, 可以使用 "Session.Timeout = n" 的語法, 設定 n 分鐘後才失效。
96
使用 Session 存取資料的方法 下面則是 Session 物件常用的方法:
97
判斷是否為新連線 前面提及 Session.IsNewSession 屬性可檢查 Session 物件是否為新建立的狀態, 因此可以利用這個屬性判斷使用者是否剛進入網站, 或者是進入後正在瀏覽。 前面程式 Ch07-08.aspx 會使用 Cookie 記錄使用者上次到訪時間, 不過該程式有一個缺點, 只要使用者一直重新整理網頁, 就會顯示新的上次到訪時間。
98
判斷是否為新連線 這樣並不合乎一般人使用的邏輯, 通常上次到訪指的是前一次開啟瀏覽器進入該網站的時間, 因此我們可以使用 Session.IsNewSession 的特點, 修正該程式, 顯示比較正確的上次到訪時間。 下面是改良後的程式碼:
99
判斷是否為新連線
100
判斷是否為新連線
101
判斷是否為新連線 執行結果:
102
7 - 7 Application 物件-在所有使用者間保存狀態
比較 Application 與 Session 物件 使用 Application 物件建立網站計數器
103
Application 的意義 在 ASP.NET 中, 一個 Application 代表一個網頁應用程式, 也就是一個網站。所以若您在 VWD 中建立了多個網站, 便等於是建立了多個 Application。 在網頁伺服器啟動之後, 當第一個使用者的第一個連線進入某一個網站時, ASP.NET 會為該網站建立一個 Application 物件。 此物件會一直保留在伺服器中, 不論是哪一個使用者的哪一次連線, 只是連線同一個網站, 都可以存取到同一個 Application 物件。
104
Application 的意義 當某個程式將資料放入 Application 物件, 同一網站的其它程式, 也可以存取到同一份資料, 所以 Application 物件可以在所有使用者之間保存狀態與共享資料。
105
Application 的意義 當網頁伺服器關閉或重新啟動, Application 物件便會刪除, 所以其存留週期開始於第一個使用者的第一個連線, 結束於網頁伺服器關閉或是重新啟動。 在存留週期結束之前, 若 Application 物件內有需要保留的資料, 便應該儲存在檔案或資料庫, 否則便會遺失。
106
Application 的意義 因為 Application 物件內的資料是儲存在伺服器上, 所以不像 Cookie 可能被使用者檢視或是竄改, 但是因為在所有連線中, 程式存取的都是同一個 Application 物件, 所以 Application 物件只適合存放所有使用者共用的全域變數與資料, 不應該放置隱密性或具差異性的使用者資料。
107
使用 Application 存取資料的方法
在 Application 儲存資料的方式與 Session 相當類似, 下面是使用 Application 儲存資料的語法: 設定之後, 只要使用『Application ("變數名稱") 』的語法便可以讀取資料。
108
使用 Application 存取資料的方法
因為同網站的所有網頁都可以將資料寫入 Application 物件, 假如有多個使用者同時寫入 Application 內的同一個變數, 可能會導致資料產生錯誤。
109
使用 Application 存取資料的方法
所以如果想要確保資料的正確性, 寫入前應該先使用 Application.Lock() 鎖定 Application 物件, 不過寫入完成後則要記得解除鎖定:
110
比較 Application 與 Session 物件
下面例子會同時寫入 Application 與 Session 物件, 然後再將其值分別顯示於網頁上, 除了示範 Application 物件的存取方式外, 也可以讓您比較兩者的差異。請如下建立控制項並設定屬性:
111
比較 Application 與 Session 物件
下面是程式的原始碼:
112
比較 Application 與 Session 物件
113
比較 Application 與 Session 物件
第 10、17 行檢查 Application 與 Session 中 x 變數是否存在, 若否便進行初始化。雖然本程式的狀況下, 沒有初始化時亦可使用, 不過基於嚴謹的程式設計態度, 建議您仍然應該進行初始化。 在瀏覽器檢視執行結果:
114
比較 Application 與 Session 物件
115
比較 Application 與 Session 物件
116
比較 Application 與 Session 物件
117
比較 Application 與 Session 物件
從上面可以看到, 新舊瀏覽器上將 Application 的 x 變數增加 1 時, 兩邊是存取同一份資料, 原本兩邊 Application ("x") 都等於 5, 新瀏覽器將其增加 1 之後變成 6, 舊瀏覽器再增加 1 則繼續變成 7。 至於新舊瀏覽器所存取的則是兩個獨立的 Session 物件, 所以兩邊寫入與讀取 Session 的 x 變數時不會互相影響。
118
使用 Application 物件建立網站計數器
我們會將到訪人數存放在 Application 的 Counter12 變數, 所以網頁只要讀取 Application (“Counter12”), 便能顯示目前總到訪人數。
119
使用 Application 物件建立網站計數器
另外, 為了避免使用者重新整理網頁, 或者再次進入網頁時會有重複計數的問題, 所以也會使用 Session 來判斷是否為新連線。下面是程式的原始碼:
120
使用 Application 物件建立網站計數器
121
使用 Application 物件建立網站計數器
執行結果: 因為放在 Application 內的資料會隨著伺服器關閉或重新啟動而消失, 所以網頁上顯示的是伺服器啟動之後的到訪人數。
122
使用 Application 物件建立網站計數器
如果想要保留計數資料, 便必須在 Application 物件消失前, 將資料存放於檔案或資料庫, 後面 7-9 節會再說明如何長久保留 Application 的資料。
123
7 - 8 各狀態管理方式的比較 前面已經介紹了相當多種狀態管理與儲存資料的方式, 包括 ViewState、Cookie、Session、Application, 加上之前就知道的變數 (常數), 以及後面章節會介紹的檔案與資料庫, 真是琳瑯滿目, 讓人弄不清什麼時候要用哪個方法比較好。 下表將比較這些方法, 讓您瞭解各方法適合的使用時機:
124
各狀態管理方式的比較
125
各狀態管理方式的比較
126
7 - 9 Global.asax-ASP.NET 應用程式檔
長久儲存人數的網站計數器
127
Global.asax 的用途 從前面章節說明中, 可以知道 Session 與 Application 物件在伺服器上面都具有一定的存留週期, 在物件起始或終止時, 我們可能會希望進行一些處理, 例如 Application 物件終止前, 會希望能將資料存放進檔案或資料庫, 以便之後繼續使用。
128
Global.asax 的用途 可是這些處理並無法在網頁程式中進行, 所以 ASP.NET 便提供了 Global.asax 這個應用程式檔, 裡面包含了 Session 與 Application 物件各事件的處理程序, 讓我們在這些程序中進行必要的處理。 Global.asax 並非必要檔案, 所以只有需處理 Session 與 Application 物件的各事件時, 才需要建立這個檔案。
129
建立 Global.asax 請在 VWD 中如下操作, 即可建立 Global.asax 檔:
130
建立 Global.asax
131
Global.asax 所包含的事件處理程序
Global.asax 建立完成後, 請在方案總管中雙按該檔案, 即可開啟 Global.asax 檔:
132
Global.asax 所包含的事件處理程序
133
Global.asax 所包含的事件處理程序
ASP.NET 已經自動在 Global.asax 中建立了 Session 與 Application 各事件的處理程序, 從預設的註解中就可以瞭解各處理程序的用途。 例如想要在 Application 終止前將資料儲存到檔案或資料庫, 就必須將處理的程式碼放置於 Application_End 程序內。
134
長久儲存人數的網站計數器 程式 Ch07-12.aspx 使用 Application 物件建立了網站計數器, 因為將人數資料存放於 Application 物件中, 所以一旦伺服器關閉或重新啟動, 人數便會歸零。
135
長久儲存人數的網站計數器 為了解決這個問題, 我們可以在 Global.asax 的 Application_End 程序內加入存檔動作, 在 Application 終止前先將資料儲存於檔案, 然後在 Application_Start 程序內放置讀取檔案的程式碼, 這樣下次 Application 重新啟動時, 就會先從檔案內讀取先前儲存的人數, 如此計數器就可以接著上次的數字計算下去。
136
長久儲存人數的網站計數器 筆者先在網站目錄下建立一個名為 Ch07-13.txt 的空白純文字檔, 供程式儲存計數器值。接著建立 Ch07-13.aspx 網頁檔, 先放入一個 Label 控制項, 並加入如下程式碼:
137
長久儲存人數的網站計數器
138
長久儲存人數的網站計數器 跟程式 Ch07-12.aspx 一樣, 此計數器依然使用 Application 物件來存放訪客人數。為了避免資料遺失, 請開啟 Global.asax 檔, 如下在 Application_Start 與 Application_End 程序中加入程式碼:
139
長久儲存人數的網站計數器
140
長久儲存人數的網站計數器
141
長久儲存人數的網站計數器 執行結果: 如此人數資料便可以持續累積, 不會因為伺服器重新啟動而歸零。
第 11、18 行分別用到在伺服器端讀取及寫入檔案的方法, 詳細說明請參閱第 14 章。
142
長久儲存人數的網站計數器 請小心, 不要過於依賴 Global.asax 中的各事件處理程序來儲存或處理重要的資料, 因為如果發生當機、斷電…等非伺服器能處理的意外, 便可能會因為無法順利觸發相關程式, 而導致資料遺失或錯誤。
143
針對 Application_End 程序進行偵錯
Application_End 是應用程式結束時所觸發的程序, 此程序內的程式碼如果有非語法上的錯誤, 可能很難透過第 8 章的方式偵錯, 此時您可以利用 Windows 的事件檢視器來觀察錯誤訊息。 所以如果 Application_End 程序執行的結果不符合您所預期, 請執行『開始 / 控制台 / 系統管理工具 / 事件檢視器』命令, 在應用程式類別下尋找來源為 ASP.NET 的事件, 開啟後即可看到錯誤訊息:
144
針對 Application_End 程序進行偵錯
Similar presentations