asp.net ASP實現
原來的ASP對話只能將對話資料儲存在記憶體中。為了將對話資料儲存到SQL Server,需要寫一個自訂的Visual Basic 6.0 COM對象代替現在的對話對象來管理對話狀態。該COM對象在每個Web請求開始時被初始化,並從SQL Server重新載入對話資料。ASP指令碼完成時,該對象將終止並把對話狀態將返回到SQL Server。
Visual Basic 6 COM Session對象的主要目的是提供對微軟Internet資訊服務器(IIS)內部對象的訪問。Visual Basic 6 COM對話對象使用SessionUtility組件的mySession類來儲存對話狀態,SessionUtility的SessionPersistence類用於載入和儲存對話資料到SQL Server。使用regasm.exe工具將mySession和 SessionPersistence類作為COM對象暴露。regasm.exe工具可以註冊並為COM用戶端建立一個類型庫來使用架構組件類。
在對象的建構函式中狀態資訊被重新載入。建構函式(class_initialize)首先從Application對象中檢索對話cookie、對話逾時設定(SessionTimeOut)、資料庫連接字串(SessionDSN),並建立mySession類的一個執行個體來保持對話資料。接著建構函式將試圖重新使用給定的cookie從SQL Server中載入對話資料。如果SQL Server中沒有對話資訊,或者對話已經終止,將產生一個新的cookie。如果SQL Server返回了對話狀態資料,對話狀態資訊將儲存在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
如果對象執行個體超出了指令碼的範圍,將執行解構函數(class_terminate)。解構函數將使用SessionPersistence.SaveSession()方法保持對話資料。如果是一個新對話,解構函數將新cookie發送回瀏覽器。
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
常式
常式設計為增加並顯示一個數字。不管載入了哪個頁面,由於數字值儲存在SQL Server中並在ASP和ASP.NET間共用,數字將不斷增加。
建立常式的步驟
1. 建立一個新資料庫SessionDemoDb。
2. 建立新表SessState(osql.exe -E -d SessionDemoDb -i Session.sql)。
3. 建立新虛擬目錄Demo。
4. 在ASP配置頁中關閉ASP對話。
5. 將web.config、testPage.aspx、Global.asa、testPage.asp和GlobalInclude.asp複製到虛擬目錄。
6. 更新Global.asa和web.config中的DSN字串設定。對話逾時設定是可選的,預設為20分鐘。
7. 將SessionUtility.dll安裝到全域群組件緩衝(gacutil /i SessionUtility.dll)。
8. 使用regasm.exe把SessionUtility.dll作為COM對象暴露(regasm.exe SessionUtility.dll /tlb:SessionUtility.tlb)。
9. 將SessionManager.dll複製到本地目錄並使用regsvr32.exe註冊(regsvr32 SessionManager.dll)。
10. 賦予IUSR_<電腦名稱>帳戶讀取和運行訪問SessionMgr.dll的許可權。
運行常式的步驟
1. 開啟微軟Internet Explorer。
2. 為傳統的ASP中載入testPage.asp。數字"1"將出現在Web頁中。
3. 點擊Internet Explorer的重新整理來重新載入該頁面。數字將增加。
4. 為ASP.NET改變URL為testPage.aspx。數字仍然增加。
5. 如果使用testPage.aspx開始,過程相同。
在存在的ASP應用程式中插入COM對象
開發ASP應用程式的一個通常的習慣是在每個指令碼開始時包含一個檔案來共用代碼和常量。插入自訂對話對象的最後途徑是在公有包含檔案中加入範例程式碼。最後一步簡單地使用自訂對話變數名代替了所有到對話對象的引用。
限制/改進
本方案不支援在Session對象中儲存了COM對象的ASP應用程式。在這種情況下,為了使用自訂對話對象,需要一個自訂的調度器來序列化/並行化狀態。此外,本方案也不支援儲存字串類型數組。做一些附加工作可以實現該特性:使用Visual Basic 6.0的Join函數在儲存到對話對象前將數組元素串連成一個字串,反向操作可以使用Visual Basic 6.0的Split函數將字串分解為獨立的數組元素。在.NET架構組件中,Join和Split方法使String類的成員。
結論
ASP.NET提出了新的編程範例和體繫結構,並提供了許多比傳統ASP的好處。儘管將ASP移植到ASP.NET的過程不簡單,ASP.NET更好的編程模型和更高的效能將使轉換過程值得。除了在Session對象中儲存COM對象的特例,本文討論的途徑提供了一個簡單實現遷移的解決方案。