將 ASP 轉換爲 ASP.NEThtml
升級至 Microsoft .NETmysql
本文將先從解釋典型數據驅動的 ASP 應用程序開始,再接下來討論將 ASP 應用程序移植到 ASP.NETsql
目標數據庫
· 將 ASP 及 Microsoft ASP.NET 執行在相同的網頁服務器上瀏覽器
· 分析通常的 ASP 應用程序服務器
· 將 ASP 應用程序移植至 ASP.NET網絡
前提oop
您應該具有下列特質以徹底瞭解這篇文章:測試
· 熟悉 Microsoft® Visual Basic® 程序設計概念和術語。網站
· 熟悉 ASP
內容
將 ASP 及 ASP.NET 執行在相同的網頁服務器上
分析 ASP 範例應用程序
將 ASP 應用程序移植至 ASP.NET
總結
將 ASP 及 ASP.NET 執行在相同的網頁服務器上
當使用 ASP.NET 時可能會注意到的第一件事就是新的擴展名:ASP.NET 網頁使用 .aspx,相對於 ASP 使用 .asp 做爲其擴展名。另外,當要求 ASP.NET 網頁時,IIS 將該要求遞交給 aspnet_wp.exe 處理序;而 ASP 則使用 asp.dll。
ASP 及 ASP.NET 可同時用於相同的網頁服務器上。也就是說,站臺中的網站或 Web 應用程序可同時包含 ASP.NET 網頁和 ASP 網頁。因爲 ASP 和 ASP.NET 網頁可同時從相同的網頁服務器存取,因此並不須要將現有的 ASP 網頁移植到 ASP.NET 相容的頁面。然而,將應用程序從 ASP 移植至 ASP.NET 有許多好處。其中一些最大的優勢包括:
· 提升效能:Microsoft 的測試顯示 ASP.NET 應用程序每秒可處理的要求量約爲傳統 ASP 應用程序兩到三倍。
· 增強穩定性:ASP.NET 執行階段將嚴格監視並管理各處理序,以便在其中一個處理序發生不當行爲 (遺漏、死鎖) 時,可創建新的處理序並立刻取代,這可幫助您的應用程序常常保持其可用狀態以處理要求。
· 提升開發人員產能:ASP.NET 中的新功能,如服務器控件和事件處理,可幫助開發人員更快並以更少的程序代碼建置應用程序。將程序代碼從 HTML 內容抽離也比以往更容易許多。
不幸的是,將現有的 ASP 網頁移植至 ASP.NET 網頁幾乎不可能像將擴展名從 .asp 改爲 .aspx 那麼簡單,再加上其它一些因素,Microsoft Visual Basic Scripting Edition (VBScript) 與 Visual Basic .NET 之間有着極大的差別。好消息是多數必要的變動都是有句法且自動化的。使用 COM 組件 (如 ADO 或您撰寫完成的自訂 COM 組件) 的 Visual Basic .NET 程序代碼實際上可保留現狀;而 C# 程序代碼就須要一些額外的程序代碼來處理 COM 組件,不過這已超出本文的範圍。
本文分紅兩個部份,先從解釋典型數據驅動的 ASP 應用程序開始。在稍後的部份,會大體瀏覽將 ASP 應用程序移植到 ASP.NET 的過程。
附註 本文把重點放在以儘量少的原始 ASP 程序代碼變動,而將 ASP 應用程序移植至 ASP.NET;它並不會探討從頭開始從新建置ASP 應用程序,使用 ASP.NET 中的新功能等。
分析 ASP 範例應用程序
在這裏將使用某一虛構公司的 Project Report Application 做爲移植至 ASP.NET 的 ASP 範例應用程序。這個應用程序會以VBScript撰寫。這種典型的應用程序會顯示進行中和過去項目的相關信息,讓使用者在 Project Report 畫面指定某些需求。
此 ASP 應用程序屬數據驅動 (data-driven),即項目信息是儲存在數據庫中;具體來講,會用到兩個數據庫數據表:Project 和Department。Department 數據表中包含公司中每一個部門的相關信息,而 Project 數據表則包含每一個項目的相關信息,如項目名稱、開始日期、預估完成日期、實際完成日期、優先級、負責項目的部門 (透過 Department 數據表的外部索引鍵),以及完整的項目說明。
瀏覽至 [Project Information] 網頁的使用者,將顯示在從去年開始的項目清單中。兩個清單方塊讓使用者能夠自訂目前項目的檢視方式。第一個清單方塊可以讓使用者指定要檢視進行中、已完成或所有項目 (進行中的項目其完成日期爲 NULL,而已完成的項目則有實際及過去完成的日期)。第二個清單方塊容許使用者依特定部門檢視項目以進一步自訂報告。
[圖 1] 顯示了項目報告的使用者接口。在這個例子當中,使用者選擇檢視內部計算機服務部門內全部的進行中項目。
[圖 1] 內部計算機服務部門內進行中的項目報告
分析 Project Report 程序代碼
整個 Project Report 應用程序的原始程序代碼都內含在單一 ASP 網頁中,這使用一種回傳窗體來處理使用者的報告自訂選項。因爲本文着重於移植 ASP 應用程序至 ASP.NET,故並未涵蓋 ASP 程序代碼運做的方式。咱們假設您具有如何將 ASP 及 ADO 數據存取用於建置現今的應用程序的相關知識。
下列程序代碼顯示在 Microsoft Access 數據庫創建並開啓的 ADO Connection 對象。
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.ConnectionString = _
"PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=" & _
Server.MapPath("Projects.mdb") & ";"
objConn.Open
Department 數據表中的每一數據列都是含有 Name 及 DepartmentID 的數據錄集 (Recordset)。此數據錄集的內容以後會顯示在清單方塊中。
Set objDeptListRS = Server.CreateObject("ADODB.Recordset")
objDepartmentListingRS.Open "Department", objConn, _
adOpenForwardOnly, adLockReadOnly, adCmdTable
'重複整個數據錄集
Response.Write "<b>Department:</b> " & _
"<select size=""1"" name=""lstDepartmentID"">"
Response.Write "<option value=""-1"">" & _
"-- Show All Departments --</option>" & vbCrLf
Do While Not objDeptListRS.EOF
Response.Write "<option value=""" & _
objDepartmentListingRS("DepartmentID") & """"
'咱們須要將項目變成「已選取」狀態嗎?
If CInt(objDepartmentListingRS("DepartmentID")) = _
CInt(iDepartmentID) then
Response.Write " selected"
End If
Response.Write ">" & objDeptListRS("DepartmentName") &_
"</option>"
objDeptListRS.MoveNext
Loop
Response.Write "</select>" & vbCrLf & vbCrLf
接下來,將依使用者所選取的選項建構動態 SQL 查詢。請注意在下列程序代碼中創建了 SQL 查詢的 WHERE 子句,讓它永遠只擷取那些從前一年開始的項目。WHERE 子句可根據使用者的選項更進一步擴充。iDepartmentID 和 strProjectView 變量是先前定義且指派給使用者所選取的清單方塊值。
strSQL = "SELECT D.DepartmentName, ProjectName, " & _
"StartDate, EstimatedEndDate, ActualEndDate, " & _
"Priority, ProjectDescription " & _
"FROM Project P " & _
"INNER JOIN Department D ON " & _
"D.DepartmentID = P.DepartmentID " & _
"WHERE StartDate >= #" & _
DateAdd("yyyy", -1, Date()) & "# "
'若有須要如今能夠建構額外的 WHERE 子句
If CInt(iDepartmentID) <> -1 then
'Add a clause for the department ID
strSQL = strSQL & " AND P.DepartmentID = " & _
iDepartmentID
End If
'咱們想要檢視哪一種項目?
Select Case strProjectView
Case "ongoing":
strSQL = strSQL & " AND ActualEndDate IS NULL"
Case "completed":
strSQL = strSQL & " AND ActualEndDate IS NOT NULL"
End Select
創建的另外一個 Recordset 對象,objProjectsRS,會填入上列動態 SQL 查詢結果。最後,此數據錄集會一直重複並顯示爲 HTML表格。
'輸出 HTML table 標記和 th 標記
Response.Write "<p><table align=""center"" " & _
"border=""1"" cellspacing=""1"">" & vbCrLf
Response.Write "<tr><th>Project</th><th>StartDate</th>" &_
"<th>Estimated Completion</th><th>Actual " & _
"Completion</th><th>Priority</th>" & _
"<th>Description</th></tr>" & vbCrLf
'重複整個數據錄集
Do While Not objProjectsRS.EOF
'顯示數據錄集信息
objProjectsRS.MoveNext '移到下一筆記錄
Loop
Response.Write "</table>" & vbCrLf & vbCrLf
將 ASP 移植至 ASP.NET
當移植 ASP 應用程序至 ASP.NET 時,會須要決定要花多少時間在現有的 ASP 應用程序併入 ASP.NET 新功能。將 ASP 網頁的擴展名從 .asp 改成 .aspx,並修正一些句法上的變動一般就夠讓 ASP 網頁如 ASP.NET 網頁般運做。這一類的移植,雖然可快速完成,但並無利用到多少 .NET 的新功能,包括 ASP.NET 的網頁控件、Microsoft ADO.NET、Microsoft .NET Framework 類別等。雖然更完整的移植可能須要花更多時間,但最後完成的 ASP.NET 網頁也更容易讀取、更容易維護且功能更豐富。
身爲一名開發人員,在決定要採起什麼方法將 ASP 應用程序移至 ASP.NET 時,您須要稍加斟酌。若是有時間的壓力,則從 ASP 至ASP.NET 的簡單移植可能比較合宜;若是沒有什麼期限,其實值得花點時間完全建置一個豐富的 ASP.NET 應用程序。固然,您也能夠採起漸進式的方法。若是您管理的大型站臺利用了許多 COM 組件來實做商務規則,則能夠選擇先移植網頁應用程序的使用者接口(UI) 部份,並繼續使用傳統的 COM 組件。
在接下來的部份,將探討以儘量少的修改將現有的 ASP 程序代碼移植至 ASP.NET。
將 ASP 應用程序移植至 ASP.NET
將現有 ASP 應用程序移植至 ASP.NET 的第一步就是將 ASP 網頁的擴展名從 .asp 從新命名爲 .aspx。因爲 Project Report Application 只有一個 ASP 網頁,因此剩下的工做其實很是簡單。一旦進行這項變動以後,花點時間透過您的 Web 瀏覽器參觀一下新的 .aspx 頁面。加載時有發生錯誤嗎?應該不太可能,不過 VBScript 程序代碼有可能包含了一些句法問題。
當移植咱們先前探討過的 ASP 應用程序時,會收到的第一個錯誤訊息是關於 Option Explicit 的錯誤,如 [圖 2] 所示。
[圖 2] Option Explicit 陳述式錯誤訊息
對 ASP.NET 網頁而言,此陳述式應該移至 @Page 指示詞。如今能夠開始編輯 .aspx 檔案,移除行 1 和行 2,並如下列 @Page 指示詞取代:
<% @Page Language="VB" Explicit="True" %>
完成這項變動以後,在瀏覽器中從新加載該頁面。將會收到另外一個關於 Response.Write 陳述式缺少括號的錯誤。
[圖 3] Response.Write 陳述式錯誤訊息
此錯誤的產生是由於 Visual Basic 要求副函式及函式中全部的自變量清單都必須使用括號括住。檢查整個文件併爲全部Response.Write 陳述式的自變量清單週圍放上括號,而後在瀏覽器中從新加載 ASP.NET 一次。
另外一個從 Visual Basic 6.0/VBScript 到 Visual Basic .NET 的變動是 Visual Basic .NET 並不支持預設屬性。預設屬性容許開發人員走一點快捷方式 — 若是在 Visual Basic 6.0/VBScript 中使用傳統 COM 組件而沒法指定屬性時,就可使用預設屬性。例如,ADO 數據錄集的預設屬性是 Fields 集合,而 Fields 集合的預設屬性是 Value 屬性。所以,當您使用:
Response.Write objRecordset("columnName")
在傳統的 ASP 中您本質上的意思是:
Response.Write objRecordset.Fields("columnName").Value
當將傳統的 ASP 網頁移植置 ASP.NET 時,您可能會收到下列密碼編譯的錯誤訊息:
Cast from __ComObject to String is not valid.
[圖 4] ASP.NET 移植程序錯誤訊息
發生這類錯誤是由於 Visual Basic .NET 並不支持預設屬性,當咱們使用:
Response.Write(objRecordset("columnName"))
Visual Basic .NET 嘗試將 Fields 對象轉換成 String,而它其實辦不到。相反地,咱們必須明確陳述但願輸出的屬性來指明想要輸出的 Value 屬性:
Response.Write(objRecordset.Fields("columnName").Value)
在繼續移植 ASP.NET 應用程序的同時,一定會碰到其它句法上的錯誤。[表 1] 總結了將 Project Report Appliction 從 ASP 移植至ASP.NET 時所遇到的句法錯誤。
附註 Visual Basic 在 Visual Basic .NET 的發行之時已蛻變爲成熟的程序設計語言。它如今支持 try...catch 錯誤處理、真實對象導向開發,以及許多其它期待已久的加強功能。爲了使 Visual Basic 更現代化,在語言上作些句法上的變動是必要的。也所以,Visual Basic .NET 並非 100% 與 VBScript 或 Visual Basic 6. 0 相容。有關 Visual Basic .NET 中的變動的詳細討論, 請務必參閱《Preparing your Visual Basic 6.0 Applications for the Upgrade to Visual Basic .NET》(英文)。
[表 1] 移植 Project Report Application 時所遇到的句法錯誤
錯誤 |
緣由 |
解析 |
Option Explicit 陳述式在程序中無效。 |
Option Explicit 須要使用 Explicit 屬性在 Page Directive 中定義。 |
將 <% @Page Explicit="True" %> 加入ASP.NET 網頁最上方。 |
只能有一個 Page Directive。 |
當新增 Page Directive時,@LANGUAGE = "VBSCRIPT" 指示詞在 ASP 網頁中是多餘的。 |
移除包含 <%@ LANGUAGE = "VBSCRIPT" %>的行,並在 Page Directive 加入Language="VB" 屬性。 |
呼叫陳述式的自變量清單如今必須使用括號括住。 |
Visual Basic .NET 要求全部副函式將其參數以括號括住。許多Response.Write 陳述式並無包含此類括號。 |
加入須要的括號:例如將 Response.Write str 變動爲 Response.Write(str)。 |
設定陳述式再也不支持 Let 和 Set陳述式。 |
因爲 Visual Basic .NET 再也不支持預設屬性,因此 Let 和 Set 關鍵詞已從Visual Basic 語言中移除。 |
移除任何 Let 或 Set 關鍵詞 (在 Porject Report Application 中,Set 關鍵詞會將 Connection 和Recordset 對象指定給變量)。 |
數據是一種型別,因此不是有效的表達式。只接受變量、常數或程序。 |
在 Project Report Application 中是使用 Date() 函式來取得目前日期。此已再也不支援。 |
以 DateTime.Now 取代 Date()。 |
並未宣告 IsNull 名稱。 |
Visual Basic .NET 再也不支持 IsNull函式 (記得在 Project Report Application 中,若是實際完成日期爲NULL,則表明項目未完成;在 ASP 版本中,IsNull 是用來檢查該字段是否爲 NULL)。 |
以 IsDBNull 取代 IsNull 可解決此問題。 |
從 __ComObject 轉換成 String無效。 |
Visual Basic .NET 再也不支持預設屬性,因此當使用傳統 COM 組件時,請肯定要徹底明確陳述但願使用的屬性。 |
將 objRS("colName") 的執行個體變動爲objRS.Fields("colName").Value。 |
COM 組件執行緒議題
在 ASP.NET 網頁中使用 COM 組件可能會引起一些問題,尤爲是該些被標爲 Apartment 執行緒的 COM 組件或透過ObjectContext 對象存取 ASP 內建對象 (Request、Response、Server、Application 及 Session) 的 COM 物件。
例如,依預設,ADO 對象在登陸中會被標爲 Apartment 執行緒;當嘗試透過 ASP.NET 網頁使用 apartment 執行緒組件時,會收到一個錯誤指出您嘗試創建的 apartment 執行緒組件沒法創建。[圖 5] 顯示 Project Report Application 的 ASP.NET 移植程序。請注意此錯誤的出現是由於 ADO 對象依預設標爲 apartment 執行緒。
[圖 5] 當嘗試透過 ASP.NET 網頁存取 apartment 執行緒 COM 組件時發生錯誤
還好 ASP.NET 提供一種「ASP 兼容性」模式,如錯誤訊息所說的。若要啓動 ASP 兼容性模式,將 aspcompat=true 屬性新增到Page Directive。新增此屬性完成了兩件事:
· ASP.NET 使用單一執行緒 Apartment (STA) 存取 COM 組件。預設是使用多執行緒 Apartment 或 MTA 執行緒。
· ASP.NET 以與舊版兼容的方式提供 ASP 內建對象的存取權。
有了這兩項變動,ASP 兼容性模式容許 ASP.NET 使用 apartment 執行緒的 COM 組件或存取 ASP 內建對象的 COM 組件。
附註 關於 COM 執行緒模型的完整討論已超過本文範圍。如需關於不一樣 COM 執行緒模型及其含意的詳細信息,請務必參閱《Understanding and Using COM Threading Models》(英文)。
總結
如今已探討過如何將 ASP 應用程序移植至 ASP.NET。如您所見,移植 ASP 網頁所牽涉的工做不過就比單單從新命名檔案擴展名再多一點。將 Project Report Application 從 ASP 移植至 ASP.NET,一個只有一頁的 ASP 應用程序再加上 20 行程序代碼,只需不超過五分鐘的時間。當移植您的 ASP 應用程序至 ASP.NET 時,請記得下列要點:
· 瞭解 VBScript 到 Visual Basic .NET 的句法變化。注意這些小小的句法錯誤將讓整個過程更平順。
· 若是移植的 ASP 網頁使用的是 apartment 執行緒 COM 組件或存取 ASP 內建對象的 COM 組件,則將aspcompat="true" 屬性加入 Page Directive。不然不須要此指示詞。
關於做者
Scott Mitchell 是 www.4GuysFromRolla.com 的創立者兼編輯,這是網絡上最大的 ASP 資源網站之一。他自 1998 年一月就開始熱衷於使用 Active Server Page,並撰寫相關文章。Scott 在 4Guys 上已着有上百篇 ASP 及 ASP.NET 相關的文章,還有無數關於Active Server Pages 及 ASP.NET 的初級和進階書籍。
關於 Informant Communications Group
Informant Communications Group, Inc. (www.informant.com) 是一家多樣化的媒體公司,着重在信息技術領域。ICG 成立於1990 年,並專長於軟件開發出版品、研討會、目錄發行及網站方面。ICG 在美國及英國都設有辦公室,並且以敬重的媒體及營銷內容整合者自居,知足了 IT 專業人員求取質量技術信息的成長需求。