遷移到 ASP .NET:需考慮的重要問題(2)
發(fā)表時間:2024-02-25 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]與 COM 有關(guān)的變化隨著 .NET 框架和 ASP .NET 的誕生,COM 實際上沒有發(fā)生任何變化。但這并不表示在 ASP .NET 中使用 COM 對象時不必?fù)?dān)心和考慮他們的行為。有一些基本情況,您必須了解。線程模式的變化ASP .NET 線程模式是多線程單元 (MTA)。這就意味著,對于目...
與 COM 有關(guān)的變化
隨著 .NET 框架和 ASP .NET 的誕生,COM 實際上沒有發(fā)生任何變化。但這并不表示在 ASP .NET 中使用 COM 對象時不必?fù)?dān)心和考慮他們的行為。有一些基本情況,您必須了解。
線程模式的變化
ASP .NET 線程模式是多線程單元 (MTA)。這就意味著,對于目前使用的為單線程單元 (STA) 創(chuàng)建的組件,如果不采取額外的措施,將不能在 ASP .NET 中可靠地執(zhí)行或運(yùn)行。其中包括但不限于使用 Visual Basic 6.0 及其更低版本創(chuàng)建的所有 COM 組件。
ASPCOMPAT 屬性
您將很高興聽到這樣一個消息:仍然可以使用這些 STA 組件,而不需要更改任何代碼。您需要做的工作只是在 ASP .NET 網(wǎng)頁的 <%@Page> 標(biāo)記中包含兼容性屬性 aspcompat=true,如 <%@Page aspcompat=true Language=VB%>。使用此屬性將強(qiáng)制網(wǎng)頁以 STA 模式執(zhí)行,從而確保您的組件可以繼續(xù)正確運(yùn)行。如果試圖使用 STA 組件但沒有指定此標(biāo)記,運(yùn)行時將會發(fā)生異常情況。
將此屬性的值設(shè)置為 true 時,將允許網(wǎng)頁調(diào)用 COM+ 1.0 組件,該組件需要訪問非管理的 ASP 內(nèi)置對象。可以通過 ObjectContext 對象進(jìn)行訪問。
如果將此標(biāo)記的值設(shè)為 true,性能會稍微有些下降。建議只在確實需要時才這樣做。
早期綁定與后期綁定
在 ASP 中,對 COM 對象的所有調(diào)用都是通過 IDispatch 接口進(jìn)行的。這種行為被稱為“后期綁定”,因為對實際對象的調(diào)用是在運(yùn)行時通過 IDispatch 間接處理的。在 ASP .NET 中,只要您愿意,可以繼續(xù)以這種方式調(diào)用您的組件。
Dim Obj As Object
Obj = Server.CreateObject("ProgID")
Obj.MyMethodCall
仍然可以使用這種方式訪問您的組件,但這不是首選方式,F(xiàn)在,在 ASP .NET 中,您可以利用早期綁定直接創(chuàng)建對象,如下所示:
Dim Obj As New MyObject
MyObject.MyMethodCall()
使用早期綁定,可以通過類型安全的方式與組件交互。為了在 COM 組件中使用早期綁定,您需要像在 Visual Basic 6.0 項目中添加 COM 引用一樣,在項目中添加一個引用。假設(shè)您正在使用 Visual Studio .NET,將在 COM 組件之上后臺創(chuàng)建一個管理的代理對象,給您的感覺就好像是直接在處理一個 .NET 組件,而不是 COM 組件。
現(xiàn)在,您可能會擔(dān)心性能問題。由于代理對象而引入了一個額外的層,所以使用 COM 協(xié)同操作時確實會存在一些問題。但是,大多數(shù)情況下,應(yīng)該不會遇到什么問題,因為進(jìn)行協(xié)同操作的實際 CPU 指令數(shù)仍然遠(yuǎn)遠(yuǎn)小于間接 IDispatch 調(diào)用的要求。您所得到的將遠(yuǎn)遠(yuǎn)超出您所失去的。當(dāng)然,理想情況是使用最新創(chuàng)建的管理對象,但我們知道,由于我們在 COM 組件上的投入所限,并不總是能夠立即做到這一點。
OnStartPage 和 OnEndPage 方法
需要特別注意的是對舊版 OnStartPage 和 OnEndPage 方法的使用。如果您依賴于這些方法訪問 ASP 固有對象,將需要使用 ASPCOMPAT 指令和 Server.CreateObject 以早期綁定方式創(chuàng)建組件,如下所示:
Dim Obj As MyObj
Obj = Server.CreateObject(MyObj)
Obj.MyMethodCall()
注意,我們并沒有使用“ProgID”,而是以早期綁定方式使用實際類型。為了讓這種方式有效,您需要在 Visual Studio 項目中添加 COM 組件引用,這樣才能創(chuàng)建早期綁定的包裝類。這是唯一必須繼續(xù)使用 Server.CreateObject 的情況。
COM 總結(jié)
表 2 總結(jié)了為繼續(xù)有效使用 COM 組件而必須完成的一些工作。
表 2:舊版 COM 對象的 ASP .NET 設(shè)置
COM 組件類型/方法 ASP .NET 設(shè)置/過程
自定義 STA(標(biāo)記為“Apartment”的 Visual Basic 組件或其它組件) 使用 ASPCOMPAT 和早期綁定
自定義 MTA(標(biāo)記為“Both”或“Free”的 ATL 或自定義 COM 組件) 不使用 ASPCOMPAT,使用早期綁定
固有對象(通過 ObjectContext 訪問) 使用 ASPCOMPAT 和早期綁定
OnStartPage 和 OnEndPage 使用 ASPCOMPAT 和 Server.CreateObject(Type)
無論您的組件是否部署在 COM+ 中,都將同樣應(yīng)用這些設(shè)置。
應(yīng)用程序配置的變化
在 ASP 中,所有 Web 應(yīng)用程序配置信息都存儲在系統(tǒng)注冊表和 IIS 配置數(shù)據(jù)庫中。由于服務(wù)器上經(jīng)常未安裝適當(dāng)?shù)墓芾砉ぞ,使得查看或修改設(shè)置變得非常困難。ASP .NET 引入了一整套全新的配置模型,這套模型以簡單的、易讀的 XML 文件為基礎(chǔ)。每個 ASP .NET 應(yīng)用程序都有自己的 Web.Config 文件,該文件位于主應(yīng)用程序目錄中?梢酝ㄟ^此文件控制 Web 應(yīng)用程序的自定義配置、行為和安全性。
如果您與我一樣,您可能會通過“Internet 服務(wù)管理器”管理單元檢查和更改 ASP .NET 應(yīng)用程序的設(shè)置。但是,您必須了解,現(xiàn)在我們擁有兩種完全不同的配置模型。除一些安全性設(shè)置外,ASP .NET 應(yīng)用程序?qū)⒑雎允褂?IIS 管理工具配置的其它大部分設(shè)置。您需要將這些配置設(shè)置保存在 Web.Config 文件中。
有關(guān) .NET 的應(yīng)用程序配置將在另一篇文章中詳細(xì)討論,此處就不詳細(xì)介紹了。表 3 說明了可以在自己的文件中配置的一些更有意義的設(shè)置。記住,還有更多設(shè)置。
表 3:Web.Config 設(shè)置示例
設(shè)置 說明
<appSettings>
配置自定義應(yīng)用程序設(shè)置。
<authentication>
配置 ASP .NET 身份驗證支持。
<pages>
標(biāo)識網(wǎng)頁特定的配置設(shè)置。
<processModel>
配置 IIS 系統(tǒng)中的 ASP .NET 進(jìn)程模型設(shè)置。
<sessionState>
指定會話狀態(tài)選項。
在 .NET 基本類庫中還有其它一些類可用,它們簡化了對這些設(shè)置的編程訪問。
狀態(tài)管理
如果應(yīng)用程序使用 Session 或 Application 固有對象存儲狀態(tài)信息,則在 ASP .NET 中可以繼續(xù)使用這些對象,而不會出現(xiàn)任何問題。隨之帶來的好處是,現(xiàn)在提供了更多的狀態(tài)存儲位置選項。
狀態(tài)管理選項
ASP .NET 中還包含其它一些狀態(tài)管理模型選項,最終可使您管理不止一個 Web 服務(wù)器,并支持通過 Web 場進(jìn)行狀態(tài)管理。
可以在 web.config 文件的 <sessionState> 一節(jié)中配置狀態(tài)管理選項,如下所示:
<sessionState
mode="Inproc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;user id=sa;password=" cookieless="false"
timeout="20"
/>
模式屬性指定將在何處存儲狀態(tài)信息?捎眠x項有 Inproc、StateServer、SqlServer 或 Off。
表 4:會話狀態(tài)存儲信息
選項 說明
Inproc 會話狀態(tài)本地存儲在此服務(wù)器中(ASP 樣式)。
StateServer 會話狀態(tài)遠(yuǎn)程(或本地)存儲在狀態(tài)服務(wù)進(jìn)程中。
SqlServer 會話狀態(tài)存儲在 SQL Server 數(shù)據(jù)庫中。
Off 會話狀態(tài)被禁用。
如果使用這些選項之一,StateConnectionString 和 sqlConnectionString 無疑將成為至關(guān)重要的參數(shù)。每個應(yīng)用程序只能使用一個存儲選項。
存儲 COM 組件
需記住的的一點是,如果您依賴于對 Session 或 Application 對象中舊版 COM 組件的存儲引用,將無法在應(yīng)用程序中使用新的狀態(tài)存儲機(jī)制(StateServer 或 SqlServer)。您將需要使用 Inproc。部分原因是對象需要在 .NET 中實現(xiàn)自我串行,很顯然,COM 組件無法做到這一點。另一方面,新創(chuàng)建的管理組件可以相對輕松地實現(xiàn)這一點,因此可以使用新的狀態(tài)存儲模式。
性能
當(dāng)然,就性能而言,每前進(jìn)一步都將付出相應(yīng)的代價。但您完全可以相信,大多數(shù)情況下,使用 Inproc 依然是最佳選擇,其后依次是 StateServer 和 SqlServer。您自己應(yīng)該對應(yīng)用程序進(jìn)行測試,確保選定的選項可以達(dá)到您的性能目標(biāo)。
ASP 和 ASP .NET 之間的共享狀態(tài)
需要考慮的另外一個重要問題是,雖然應(yīng)用程序可以同時包含 ASP 和 ASP .NET 網(wǎng)頁,但您無法共享固有 Session 或 Application 對象中存儲的狀態(tài)變量。可能需要將這些信息復(fù)制到這兩個系統(tǒng)中或提出其它自定義解決方案,才能完全遷移您的應(yīng)用程序。最好的情況是您未使用 Session 和 Application 對象。另一方面,如果您大量使用了這些對象,您需要一直小心謹(jǐn)慎,或許可以提出某種自定義的短期解決方案來共享狀態(tài)。
與安全性有關(guān)的變化
安全性是需要特別注意的另一個重要問題。下面簡要介紹了 ASP .NET 安全性系統(tǒng)。有關(guān)安全性問題更完整的研究,請參見 ASP .NET 安全性文檔。
ASP .NET 安全性主要受 web.config 文件中安全性部分的設(shè)置控制。ASP .NET 與 IIS 協(xié)同工作,為您的應(yīng)用程序提供完善的完全性模型。IIS 安全性設(shè)置是實際攜帶并應(yīng)用于 ASP .NET 應(yīng)用程序的少數(shù)幾個應(yīng)用程序設(shè)置,其攜帶和應(yīng)用方式與在 ASP .NET 中相似。當(dāng)然,在很多方面都得到了改進(jìn)。
身份驗證
對于身份驗證,ASP .NET 支持表 5 中所示的選項。
表 5:ASP .NET 身份驗證選項
類型 說明
Windows ASP .NET 使用 Windows 身份驗證。
Forms 基于 Cookie 的自定義登錄表單。
Passport 非 Microsoft 提供的 Passport Service。
None 不執(zhí)行身份驗證。
除新增加的 Passport 身份驗證選項之外,其它選項都與 ASP 中的選項相同。例如,下列配置對應(yīng)用程序啟用基于 Windows 的身份驗證。
<configuration>
<system.web>
<authentication mode="Windows"/>
</system.web>
</configuration>
授權(quán)
用戶通過身份驗證后,將集中考慮允許他們訪問哪些資源。在下例中,授予了“jkieley”和“jstegman”訪問權(quán)限,而其他所有人都被拒絕訪問。
<authorization>
<allow users="NORTHAMERICA\jkieley, REDMOND\jstegman"/>
<deny users="*"/>
</authorization>
模擬
做為刷新程序,模擬是指這樣一個過程:對象以它所代表的實體的標(biāo)識執(zhí)行代碼。在 ASP 中,模擬允許您的代碼代表通過身份驗證的用戶運(yùn)行;蛘撸脩粢部梢酝ㄟ^特定標(biāo)識匿名運(yùn)行。默認(rèn)情況下,ASP .NET 不會針對每個請求進(jìn)行模擬。這一點與 ASP 不同。如果您依賴于這種功能,則需要在 web.config 文件中啟用它,如下所示:
<identity>
<impersonation enable = "true"/>
</identity>
數(shù)據(jù)訪問
遷移過程中,需要重點考慮的另一個關(guān)鍵問題是數(shù)據(jù)訪問。隨著 ADO .NET 的誕生,現(xiàn)在您具有了一種訪問數(shù)據(jù)的強(qiáng)有力的全新方法。由于數(shù)據(jù)訪問本身就是一個很大的主題,本文就不詳細(xì)討論了。大多數(shù)情況下,您可以像過去一樣繼續(xù)使用 ADO,但是我極力推薦您了解一下 ADO .NET,并通過它改善 ASP .NET 應(yīng)用程序中的數(shù)據(jù)訪問方法。
準(zhǔn)備向 ASP .NET 遷移
現(xiàn)在您已了解了可能會遇到的大多數(shù)問題,您可能會想:目前我需要做好哪些準(zhǔn)備工作以備將來最終遷移到 ASP .NET 呢?目前確實需要完成幾項工作,以確保將來的遷移過程順利進(jìn)行。其中的許多建議對您的 ASP 代碼大有益處,即使目前不打算向 ASP .NET 遷移。
使用 Option Explicit
這始終是一個不錯的建議,但至今仍然有許多人沒有使用它。通過使用 Option Explicit,強(qiáng)制在 ASP 中聲明變量,您至少可以控制在何處定義每個對象以及如何使用變量。遷移到 ASP .NET 之后,我建議使用 Option Strict。在 Visual Basic .NET 中,默認(rèn)使用 Option Explicit,但是使用更具強(qiáng)制性的 Option Strict,可以確保所有變量都聲明為正確的數(shù)據(jù)類型。這樣做確實需要增加一些額外的工作,但從長期考慮,您將發(fā)現(xiàn)還是很值得這樣做的。
避免使用默認(rèn)屬性
我們前面已討論過,不再允許使用默認(rèn)屬性。顯式訪問屬性并不是什么難事。它將增強(qiáng)代碼的可讀性,而且可以在將來節(jié)省您的時間。
使用括號和 Call 關(guān)鍵字
正如本文前面詳細(xì)討論過的,應(yīng)盡可能使用括號和 Call 語句。在 ASP .NET 中,將強(qiáng)制使用括號。現(xiàn)在使用 Call 語句有助于您熟悉一些規(guī)則,為將來的工作打好基礎(chǔ)。
避免嵌套的包含文件
這一點可能說起來容易做起來難,但還是應(yīng)盡可能避免嵌套包含文件。我的意思是說,應(yīng)該努力避免在包含文件中包括其它包含文件。隨著時間的推移,可能會碰到的一種情況是,您的代碼不再依賴于在其它某處的包含文件中定義的全局變量,您需要訪問的原因僅僅是因為其中嵌套了包含您真正需要的全局變量的另一個文件。
向 ASP .NET 遷移時,您很有可能會將全局變量和程序遷移到類庫中,這種情況下,如果您清楚地了解每個對象的訪問位置,遷移起來就很容易。您不需要將一些對象移來移去,也不需要更改多個文件中相同的那些程序名稱。
將實用函數(shù)合并到單個文件中
遷移過程中的一個策略是將服務(wù)器端包含文件中包含的所有實用函數(shù)和代碼遷移到 Visual Basic 或 C# 類庫中。這樣,您最終可以將所有代碼放到所屬對象中,這一點與多解釋的 ASP 文件不同。提前組織好代碼,可以節(jié)省將來的遷移時間。理論上講,您應(yīng)該可以將子程序組合到邏輯文件中,從而使您可以輕松地創(chuàng)建一組 VB 或 C# 類。這些函數(shù)可能應(yīng)位于 COM 對象中。
如果服務(wù)器端包含文件中存在一大堆全局變量或常量,也最好考慮將他們組合到單個文件中。一旦遷移到 ASP .NET 后,您就可以輕松創(chuàng)建一個類來存放全局或常量數(shù)據(jù)。這將使系統(tǒng)更干凈、更易維護(hù)。
盡可能將代碼與內(nèi)容分開
這又是一件說起來比做起來容易的工作,但是您應(yīng)該盡量將代碼與 HTML 內(nèi)容分開。清理一下主體中即有代碼、又有腳本的那些函數(shù)。這樣做使您處于非常有利的位置,可以充分利用代碼--無論怎么說,這是 ASP .NET 中的最佳模式。
不要在 <% %> 塊聲明函數(shù)
ASP .NET 不支持在 <% %> 塊聲明函數(shù)。應(yīng)該在 <script> 塊進(jìn)行聲明。有關(guān)此技術(shù)的示例,請參閱本文前面的結(jié)構(gòu)變化一節(jié)。
避免使用生成函數(shù)
如前所述,應(yīng)該盡量避免使用“生成函數(shù)”。如果現(xiàn)在可以更改或準(zhǔn)備代碼,應(yīng)在構(gòu)造這類函數(shù)時使用 Response.Write 塊。
顯式釋放資源(調(diào)用 Close 方法)
確保對使用的對象和資源中存在的 close() 或清理方法進(jìn)行顯式調(diào)用。我們都知道,Visual Basic 和 VBScript 在清理方面的容錯能力很強(qiáng)。通常情況下,他們能夠立即清理對象。但遷移到 .NET 后,您將無法準(zhǔn)確掌握對象何時會被清理,就像您無法確定垃圾堆中的垃圾何時會被清理一樣。如果您能夠顯式清理和釋放資源,最好顯式地進(jìn)行清理和釋放。
避免混用語言
應(yīng)該盡量避免在同一網(wǎng)頁中混用服務(wù)器端 VBScript 和 JScript。一般而言,這是一種不太明智的編程方式。而且向 ASP .NET 遷移時還會存在問題,因為由于采用了新的編譯模式,每個網(wǎng)頁只要求一種內(nèi)嵌 <% %> 語言。但仍然可以使用過去的方式生成客戶端腳本。
總結(jié)
正如我們已經(jīng)了解的,在向 ASP .NET 遷移應(yīng)用程序之前,有許多問題需要考慮。我在此文中歸納了遷移前后會發(fā)生的大多數(shù)變化,這應(yīng)該能使您的遷移過程變得相對簡單一些。
如果您擁有一個大型站點,完成此進(jìn)程之后,您可能會對遇到并修正了如此多的死代碼、無效代碼以及所有 Bug 而驚奇不已。另外,通常您還可以充分利用 ASP .NET 和 .NET 平臺中大量強(qiáng)大的新增功能。
Jim Kieley 是 Microsoft Consulting Services 的高級顧問。從 .NET 發(fā)展初期,Jim 就一直與 Visual Studio 組密切合作,而且他還是早期創(chuàng)建 ASP .NET 和 .NET 框架應(yīng)用程序的用戶之一。您可以通過下列電子郵件地址與 Jim 聯(lián)系:jkieley@microsoft.com