在ASP與ASP.NET之間共享對話狀態(tài)(2)
ASP實(shí)現(xiàn) 原來的ASP對話只能將對話數(shù)據(jù)保存在內(nèi)存中。為了將對話數(shù)據(jù)保存到SQL Server,需要寫一個(gè)自定義的Visual Basic 6.0 COM對象代替現(xiàn)在的對話對象來管理對話狀態(tài)。該COM對象在每個(gè)Web請求開始時(shí)被初始化,并從SQL Server重新載入對話數(shù)據(jù)。ASP腳本完成時(shí),該對象將終止并把對話狀態(tài)將返回到SQL Server。 Visual Basic 6 COM Session對象的主要目的是提供對微軟Internet信息服務(wù)器(IIS)內(nèi)部對象的訪問。Visual Basic 6 COM對話對象使用SessionUtility組件的mySession類來保存對話狀態(tài),SessionUtility的SessionPersistence類用于載入和保存對話數(shù)據(jù)到SQL Server。使用regasm.exe工具將mySession和 SessionPersistence類作為COM對象暴露。regasm.exe工具可以注冊并為COM客戶端建立一個(gè)類型庫來使用框架組件類。 在對象的構(gòu)造函數(shù)中狀態(tài)信息被重新載入。構(gòu)造函數(shù)(class_initialize)首先從Application對象中檢索對話cookie、對話超時(shí)設(shè)置(SessionTimeOut)、數(shù)據(jù)庫連接字符串(SessionDSN),并建立mySession類的一個(gè)實(shí)例來保持對話數(shù)據(jù)。接著構(gòu)造函數(shù)將試圖重新使用給定的cookie從SQL Server中載入對話數(shù)據(jù)。如果SQL Server中沒有對話信息,或者對話已經(jīng)終止,將產(chǎn)生一個(gè)新的cookie。如果SQL Server返回了對話狀態(tài)數(shù)據(jù),對話狀態(tài)信息將保存在mySession對象中。 Private Sub Class_Initialize() On Error GoTo ErrHandler: Const METHOD_NAME As String = "Class_Initialize" Set mySessionPersistence = New SessionPersistence Set myObjectContext = GetObjectContext() mySessionID = ReadSessionID() myDSNString = GetConnectionDSN() myTimeOut = GetSessionTimeOut() myIsNewSession = False Call InitContents Exit Sub ErrHandler: Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description End Sub Private Sub InitContents() On Error GoTo ErrHandler: Const METHOD_NAME As String = "InitContents" If mySessionID = "" Then Set myContentsEntity = New mySession mySessionID = mySessionPersistence.GenerateKey myIsNewSession = True Else Set myContentsEntity =mySessionPersistence.LoadSession(mySessionID, myDSNString, myTimeOut) End If Exit Sub ErrHandler: Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description End Sub 如果對象實(shí)例超出了腳本的范圍,將執(zhí)行解構(gòu)函數(shù)(class_terminate)。解構(gòu)函數(shù)將使用SessionPersistence.SaveSession()方法保持對話數(shù)據(jù)。如果是一個(gè)新對話,解構(gòu)函數(shù)將新cookie發(fā)送回瀏覽器。 Private Sub Class_Terminate() On Error GoTo ErrHandler: Const METHOD_NAME As String = "Class_Terminate" Call SetDataForSessionID Exit Sub ErrHandler: Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description End Sub Private Sub SetDataForSessionID() On Error GoTo ErrHandler: Const METHOD_NAME As String = "SetDataForSessionID" Call mySessionPersistence.SaveSession(mySessionID, myDSNString, myContentsEntity, myIsNewSession) If myIsNewSession Then Call WriteSessionID(mySessionID) Set myContentsEntity = Nothing Set myObjectContext = Nothing Set mySessionPersistence = Nothing Exit Sub ErrHandler: Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description End Sub 例程 例程設(shè)計(jì)為增加并顯示一個(gè)數(shù)字。不管載入了哪個(gè)頁面,由于數(shù)字值保存在SQL Server中并在ASP和ASP.NET間共享,數(shù)字將不斷增加。 建立例程的步驟 1. 建立一個(gè)新數(shù)據(jù)庫SessionDemoDb。 2. 建立新表SessState(osql.exe -E -d SessionDemoDb -i Session.sql)。 3. 建立新虛擬目錄Demo。 4. 在ASP配置頁中關(guān)閉ASP對話。 5. 將web.config、testPage.aspx、Global.asa、testPage.asp和GlobalInclude.asp復(fù)制到虛擬目錄。 6. 更新Global.asa和web.config中的DSN字符串設(shè)置。對話超時(shí)設(shè)置是可選的,默認(rèn)為分鐘。 7. 將SessionUtility.dll安裝到全局組件緩存(gacutil /i SessionUtility.dll)。 8. 使用regasm.exe把SessionUtility.dll作為COM對象暴露(regasm.exe SessionUtility.dll /tlb:SessionUtility.tlb)。 9. 將SessionManager.dll復(fù)制到本地目錄并使用regsvr32.exe注冊(regsvr32 SessionManager.dll)。 10. 賦予IUSR_帳戶讀取和運(yùn)行訪問SessionMgr.dll的權(quán)限。 運(yùn)行例程的步驟 1. 打開微軟Internet Explorer。 2. 為傳統(tǒng)的ASP中載入testPage.asp。數(shù)字"1"將出現(xiàn)在Web頁中。 3. 點(diǎn)擊Internet Explorer的刷新來重新載入該頁面。數(shù)字將增加。 4. 為ASP.NET改變URL為testPage.aspx。數(shù)字仍然增加。 5. 如果使用testPage.aspx開始,過程相同。 在存在的ASP應(yīng)用程序中插入COM對象 開發(fā)ASP應(yīng)用程序的一個(gè)通常的習(xí)慣是在每個(gè)腳本開始時(shí)包含一個(gè)文件來共享代碼和常量。插入自定義對話對象的途徑是在公有包含文件中加入示例代碼。一步簡單地使用自定義對話變量名代替了所有到對話對象的引用。 限制/改進(jìn) 本方案不支持在Session對象中保存了COM對象的ASP應(yīng)用程序。在這種情況下,為了使用自定義對話對象,需要一個(gè)自定義的調(diào)度器來串行化/并行化狀態(tài)。此外,本方案也不支持保存字符串類型數(shù)組。做一些附加工作可以實(shí)現(xiàn)該特性:使用Visual Basic 6.0的Join函數(shù)在保存到對話對象前將數(shù)組元素連接成一個(gè)字符串,反向操作可以使用Visual Basic 6.0的Split函數(shù)將字符串分解為獨(dú)立的數(shù)組元素。在.NET框架組件中,Join和Split方法使String類的成員。 結(jié)論 ASP.NET提出了新的編程范例和體系結(jié)構(gòu),并提供了許多比傳統(tǒng)ASP的好處。盡管將ASP移植到ASP.NET的過程不簡單,ASP.NET更好的編程模型和更高的性能將使轉(zhuǎn)換過程值得。除了在Session對象中保存COM對象的特例,本文討論的途徑提供了一個(gè)簡單實(shí)現(xiàn)遷移的解決方案。
來源:http://edu.chinaz.com