[ASP.NET] 如何於泛型處理常式(ashx)中存取工作階段變數(Session)
通常我們在繪製圖形驗證碼、下載檔案或是產出特定內容(content)的時候,
都會透過泛型處理常式 (ashx) 或是 Http Handler 來進行。
(基本上都是一樣的, 因為他們都繼承自 System.Web.IHttpHandler )
以圖形驗證碼來講,大多數人的習慣都是以 Session 變數記錄「驗證碼」的值,
但是預設在 ashx 中卻無法存取 Session 變數的值,會發生類似以下的錯誤訊息。
1: 應用程式中發生伺服器錯誤。
2:
3: 並未將物件參考設定為物件的執行個體。
4:
5: 描述:
6: 在執行目前 Web 要求的過程中發生未處理的例外情形。
7: 請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
8:
9: 例外詳細資訊:
10: System.NullReferenceException: 並未將物件參考設定為物件的執行個體。
11:
12: 原始程式錯誤:
13: 在執行目前 Web 要求期間,產生未處理的例外狀況。
14: 如需有關例外狀況來源與位置的資訊,可以使用下列的例外狀況堆疊追蹤取得。
15:
16: 堆疊追蹤:
17: [NullReferenceException: 並未將物件參考設定為物件的執行個體。]
18: IGS.Online.Resources.Management.Handler1.ProcessRequest(HttpContext context) +99
19: System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +100
20: System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
這個大概很多人都會背了吧 => 並未將物件參考設定為物件的執行個體
其實關於這點的解決方式 Google 真是超好找的啦…
要能夠在泛型處理常式中存取 Session 變數,ashx 其類別必須實作 System.Web.SessionState 命名空間中的 IRequiresSessionState 介面。
何謂實作 System.Web.SessionState.IRequiresSessionState 介面,其實很簡單我們來看看,實作前後吧!
- 原始 ashx 檔案建立後的內容
1: public class Handler1 : IHttpHandler
2: {
3: public void ProcessRequest(HttpContext context)
4: {
5: context.Response.ContentType = "text/plain";
6: context.Response.Write("Hello World");
7: }
8:
9: public bool IsReusable
10: {
11: get
12: {
13: return false;
14: }
15: }
16: }
- 實作後
1: public class Handler1 : IHttpHandler, System.Web.SessionState.IRequiresSessionState
2: {
3: public void ProcessRequest(HttpContext context)
4: {
5: context.Response.ContentType = "text/plain";
6: context.Response.Write("Hello World");
7: }
8:
9: public bool IsReusable
10: {
11: get
12: {
13: return false;
14: }
15: }
16: }
其實差別不大吧!
重點就在於,必須在本來僅繼承自「IHttpHandler 介面」的類別後(or 前)加上 「System.Web.SessionState.IRequiresSessionState」的程式碼
接下來,我們就可以存取 ProcessRequest HttpContext 參數下的 Session (工作階段變數) 的值嚕!
1: public class Handler1 : IHttpHandler, System.Web.SessionState.IRequiresSessionState
2: {
3: public void ProcessRequest(HttpContext context)
4: {
5: context.Response.ContentType = "text/plain";
6: context.Response.Write(context.Session["LoginUser"]);
7: }
8: // ~略
9: }