【摘要】ASP.NET的出現大大提高了編寫的站點的性能,但傳統的ASP技術也需要同時應用,兩種技術間會話狀態的共享是必須解決的問題。文章即對實際編程時如何在ASP和ASP.NET中共享會話狀態,介紹了實現原理,給出了具體的操作步驟。
【關鍵詞】ASP,ASP.NET,會話狀態,共享
【中圖分類號】G434【文獻標識碼】B 【論文編號】1009—8097(2007)06—0061—04
一、前言
在構建教育網站、教育資源庫等網上平臺時經常會用到ASP.NET技術,Microsoft ASP.NET是新的 Microsoft 技術,用于開發基于 Web 的應用程序。相比傳統的 ASP 腳本技術而言,它具有很多優點,包括:(1)將UI表示形式從業務邏輯中分離出來,從而提供更好的開發結構;(2)其代碼是完全編譯的,而在傳統ASP中代碼是解釋的;(3)其編譯特性結合其高速緩存支持,這就意味著相對用傳統ASP編寫的等效站點而言,使用ASP.NET編寫的站點的性能有顯著提高[1]。
在“國家知識服務體系支撐技術研究”項目中,用到了ASP和ASP.NET兩種技術。由于在ASP.NET中,Session的存儲機制與ASP的存儲機制不一樣,雖然可以在同一個IIS下同時運行.asp與.aspx,但是ASP 腳本將會話狀態信息存儲在內存中,不能與其他應用程序(如 ASP.NET)共享。因此,就涉及到如何解決對話狀態共享的問題。
微軟的msdn文檔里提出了一個Session共享的解決方案,但此文檔說明原理時偏重于代碼編寫,略顯晦澀,而且也沒有說明具體的操作步驟,應用起來有許多不清楚的地方,不易操作。所以,本文首先對共享原理加以說明,然后主要討論了如何利用這種原理,在實際操作中實現ASP與ASP.NET之間session的共享。
二、共享實現原理
(一)原理綜述
ASP和ASP.NET之間標識會話狀態用到了Cookie,它是Web應用程序用來標識用戶會話的最常用方法。ASP將會話狀態信息存儲在內存中,不能與其他應用程序(如ASP.NET)共享。如果會話狀態以一種通用格式存儲在Microsoft SQL Server中,則傳統的ASP和ASP.NET都能訪問會話狀態。
在ASP和ASP.NET共享會話狀態時,使用了一個名為mySession的cookie來標識用戶會話。當用戶向Web應用程序發出請求時,該用戶將被發放一個唯一的cookie以便標識該會話;此后在其后續請求中,瀏覽器將此唯一的cookie發送回服務器以標識該會話;在加載所請求的Web頁面之前,一個自定義的對象利用此唯一的cookie從SQL Server中重新加載用戶會話數據,在Web頁面中通過該自定義的對象即可訪問會話狀態;當Web請求結束后,隨著該請求的終止,會話數據將被保存回SQL Server中(見圖1)[1]。
(二)ASP.NET實現原理
在ASP.NET中,每個Web頁面都是從System.Web.UI.Page類派生出來的,Page類中包含HttpSession對象的一個實例以用于會話數據。在此,從System.Web.UI.Page派生了一個名為SessionPage的自定義Page類,以實現與Page類完全相同的各種特性。派生頁的唯一不同之處就是利用一個自定義的會話對象重寫了默認的HttpSession。這個自定義的會話類負責將會話狀態存儲到內存中,并且將會話數據類型限定為僅允許字符串型,以實現與ASP之間的互操作(默認的HttpSession允許將任何類型的數據存儲在會話中,這將不能與ASP互操作)。
Page類公開了不同的事件和方法以供進行自定義,其中OnInit方法用于設置Page對象的初始化狀態。在頁面初始化時,如果用戶的請求不具有唯一的mySession cookie,則將給請求者發放一個新的唯一的mySession cookie;如果有,就利用一個自定義的數據訪問對象(SessionPersistence)從SQL Server中檢索會話數據(數據庫連接從web.config中檢索到)[1]。為了獲得最佳性能,SessionPersistence類以二進制格式對會話狀態進行序列化和反序列化,再將所得到的二進制會話狀態數據以image字段類型存儲在SQL Server中。
當該請求結束時,將激發Page類的Unload事件,相應的事件處理程序將會話數據序列化成二進制格式,并將所得的二進制數據保存到SQL Server中。
SessionPage類及其相關類都封裝在SessionUtility程序集中。在ASP.NET項目中,要建立一個對SessionUtility程序集的引用,并且為了與ASP共享會話,要從SessionPage而不是Page類派生出每個頁面[1]。
(三)ASP實現原理
本機的ASP會話只能將會話數據存儲在內存中,為了將會話數據存儲到SQL Server中,要編寫一個自定義的COM對象以管理會話狀態,而不使用本機的會話對象進行管理。這個COM對象將在每個Web請求開始時得以實例化,并從SQL Server處重新加載會話數據。當ASP腳本完成時,此對象將終止,并且會話狀態將被保存回SQL Server中。
COM Session對象的主要目的就是提供對Microsoft Internet Information Server內部對象的訪問。它使用SessionUtility程序集的mySession類來保留會話狀態,并使用SessionUtility的SessionPersistence類從SQL Server中加載會話數據或將會話數據保存回SQL Server。利用regasm.exe,mySession和SessionPersistence類可被公開為COM對象。regasm.exe能夠注冊并創建一個類庫,以便COM客戶端使用各個框架類[1]。
三、具體實現步驟
(一)首先,確保整個項目應用程序(ASP和ASP.NET)的數據庫只有一個。在數據庫中創建數據表SessionState來存放會話狀態。
打開SQL Server查詢分析器,運行以下腳本來創建數據表,數據表名為SessionState。
(四)關閉IIS中ASP的Session選項
打開IIS,選擇站點,右擊依次選擇屬性->主目錄->配置->應用程序選項,將啟用會話狀況前的復選勾去除(見圖2)。
(五)安裝SessionUtility.dll
SessionUtility.dll即上文的自定義COM對象。
首先找到 gacutil.exe 文件,一般情況下在 Microsoft Visual Studio .NET 2003\\SDK\\v1.1\\Bin 目錄下。
運行cmd命令,在命令提示符窗口中,執行 gacutil /i SessionUtility.dll,如果執行失敗,則將命令的當前目錄改為gacutil.exe 文件的所在目錄,如D:\\Program Files\\Microsoft Visual Studio .NET 2003\\SDK\\v1.1\\Bin,再執行gacutil /i F:\\session\\SessionUtility.dll(將SessionUtility.dll的路徑也寫全)。
(六)注冊SessionUtility.dll為Com對象
同樣,要找到 regasm.exe 文件,一般情況下在 WINDOWS \\Microsoft.NET\\Framework\\v1.1.4322目錄下。
運行cmd命令,在命令提示符窗口中,執行regasm.exe SessionUtility.dll /tlb:SessionUtility.tlb,最好寫全兩個文件的路徑, 具體方法同上。這樣就會在SessionUtility.dll所在的文件夾下產生出一個tlb文件, 可以當作普通的Com組件來調用。
(七)注冊SessionManager.dll
這步很簡單,運行cmd命令,在命令提示符窗口中,執行regsvr32 SessionManager.dll,同樣最好寫全兩個文件的路徑,具體方法同上。regsvr32.exe通常在WINDOWS\\system32下。
(八)如果是NTFS格式的系統,找到 SessionMgr.dll,右鍵點擊“屬性”,將IUSR權限設置為可讀和可執行。
至此,已經可以實現ASP與ASP.NET之間Session的共享了。
在ASP中,要在頁面的開始端和結束端分別加上以下代碼:
而在ASP.NET中,要如下使用:
首先,在項目中添加對SessionUtility的引用,并且編譯通過;
其次,編碼時,將原來的繼承 public class WebForm1:System.Web.UI.Page,修改為public class WebForm1:MSDN.SessionPage(SessionPage類封裝在SessionUtility中)。
這樣就可以使用Session(\"UserID\")這樣的形式在ASP和ASP.NET中共享會話狀態了。
四、注意事項
完成以上步驟后,Session就可以在ASP和ASP.NET中實現共享了,但是還有一些細節上的問題會影響到共享效果,如下:
(一)雖然Session實現了共享,但是Session的使用語法,相對于.NET中新增的部分,就沒有實現,畢竟要照顧ASP,比如Session.Remove就不能用了。
(二)如果原來ASP和ASP.NET各自有自己的數據庫,要將其合為一個,也就是最終在Web.config文件中appSettings里和global.asa文件中Application(\"SessionDSN\")里所連接的數據庫。
(三)ASP的文件要放在ASP.NET文件夾下,并且在IIS中建立虛擬目錄時指向此ASP.NET文件夾。
(四)global.asa文件中Session.Timeout = 20和Session. Abandon兩句代碼要刪掉或注釋掉,否則第一次登錄.asp網頁時會提示global.asa文件中有錯誤,刷新頁面才能進入(因為IIS中本機的會話被禁用,缺少默認的session)。
(五)移植程序時一定要將代碼中所有的虛擬目錄改為新建的虛擬目錄(指向包括ASP文件的ASP.NET文件夾)的名字。
五、結束語
微軟的msdn中對于session的共享原理及代碼已經講解的比較清晰,所以文章并未在共享原理上多花文
字,主要是講述具體操作步驟,更有實際應用意義。文章中也許還有遺漏及不夠細致之處,請大家共同討論,以對此過程更加明了。
——————————
參考文獻
[1]微軟MSDN文檔[DB/OL].http://www.microsoft.com/china / MSDN/library/WebServices/ASP.NET/HowtoShareSessionStateBetweenClassicASPandASP.NET.mspx?mfr=true.
How to Share Session State Between ASP and ASP.NET
Ma Wenjie1, 2LiNa1, 2Liu Qingtang2
1. Engineering Research Center for Education Information Technology, HuaZhong Normal University, Wuhan Hubei., 430079
2.Information Technology Department, HuaZhong Normal University,.Wuhan, Hubei 430079
Abstract: The appearance of ASP.NET has improved the performance of compiling web site greatly, but simultaneously the traditional technology ASP is still in use, thus sharing Session state between the two technologies is a problem needing resolved. This article introduces the principle realized, presents material operations step by step on how to share Session state between ASP and ASP.NET in practical programs.
Keywords: ASP, ASP.NET, Session State, Share
注:本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文。