ASP 迁移到 ASP .NET:需考虑的重要问题
简介
虽然 Microsoft® ASP .NET 的设计者在保持 ASP 应用程序的向后兼容性方面做了大量不懈的努力,但在将 Web 应用程序由 ASP 向 ASP .NET 迁移之前,还是应该了解一下几个关键的问题。在 .NET 平台和 ASP .NET 中对现有技术进行了改进并采用了一些新技术,透彻理解这些技术有利于简化此迁移过程,但这需要经过一段漫长的时间。
本文探讨各方面的变化,以便让用户清楚地了解建立 ASP 应用程序并使其在 ASP .NET 环境中运行所必须进行的一些工作。同时,它还指出了 ASP .NET 的一些新特性,用户可以充分利用这些新特性改进现有的应用程序。但这决不是 ASP .NET 所有新特性的全面介绍,而只是着重探讨一下成功迁移时需考虑的一些问题。
我设想,由于大多数 ASP 应用程序都使用 Microsoft® Visual Basic® Scripting Edition (VBScript),所以大多数用户都会选择使用 Visual Basic .NET 迁移到 ASP .NET。显然,这不是必需的。但如果决定在迁移的同时更改语言,将需要进行一些额外的工作,而且很可能还会涉及到设计和结构方面的更改。
共存性
在讨论具体的兼容性和迁移问题之前,了解一下 ASP 和 ASP .NET 如何共存非常重要。ASP 和 ASP .NET 应用程序可以同时在服务器上运行,而互不影响。这主要是由于两种技术各自使用不同的文件扩展名(.asp 与 .aspx)和不同的配置模型(配置数据库/注册表与基于 XML 的配置文件)。这两种系统还各自具有相应的处理引擎。
让某个应用程序的一部分运行 ASP,而另一部分运行 ASP .NET,这是完全可能的。如果需要将一个快速发展的大型站点一次一小部分地迁移到 ASP .NET,这种特性将对您大有益处。某些用户可能会说,最好能一次性迁移和部署整个站点。对于某些类型的 Web 应用程序来说也许是如此,但我认为,有许多站点并不能这样:考虑到站点内容和外观的绝对大小、复杂程度以及迅速变化,这种方式非常缺乏灵活性。毕竟,对于一个盈利的网站来说,那些掏腰包的人不可能允许您停止他们的新增功能,而将整个网站迁移到这种热门的新技术。另外,如果把向 ASP .NET 迁移作为一项长期投资,您将希望利用此机会尽可能多地对结构和设计做一些改进。综合这些情况,分阶段的共存性迁移是绝对必要的。
兼容性问题
将应用程序向 ASP .NET 迁移可能不是一件容易的事情;但是,也不应该很困难。ASP .NET 与 ASP 的兼容性非常好,给用户的感觉就好象 ASP .NET 是 ASP 的一个完整翻版。ASP .NET 设计者的最初目标是实现与 ASP 百分之百的向后兼容性,但在随后的工作中,他们不得不改变了这一初衷,以便彻底地改进这一平台。不过不要担心,我们尽可能进行了大量改进,应该不会需要您进行太多的工作。所发生的实际变化可以归纳为下列几类:
核心 API 的变化
结构变化
Visual Basic 语言的变化
与 COM 有关的变化
应用程序配置的变化
状态管理问题
与安全性有关的变化
数据访问
下面将详细讨论上述各个方面的变化。
核心 API 的变化
ASP 的核心 API 由几个固有对象(Request、Response 和 Server 等)及其有关方法组成。除几处简单变化之外,这些 API 在 ASP .NET 下可以继续正常运行。所有变化都与 Request 对象有关,如表 1 所示:
表 1:API 的变化
方法 变化
Request(item) 在 ASP 中,此方法返回字符串数组。在 ASP .NET 中,它返回 NameValueCollection。
Request.QueryString(item) 在 ASP 中,此方法返回字符串数组。在 ASP .NET 中,它返回 NameValueCollection。
Request.Form(item) 在 ASP 中,此方法返回字符串数组。在 ASP .NET 中,它返回 NameValueCollection。
正如您所见,对于涉及到的所有方法,其变化基本上都相同。
如果访问的 item(项)只包含特定关键字的一个值,您将不必修改自己的代码。但是,如果给定的关键字具有多个值,您将需要使用其它方法返回值的集合。另请注意,Visual Basic .NET 中的集合都是基于 0,而 VBScript 中的集合是基于 1 的。
例如,在 ASP 中,将按下列方式访问 http://localhost/myweb/valuetest.asp?values=10&values=20 请求返回的各个查询字符串值:
<% '输出“10” Response.Write Request.QueryString("values")(1) '输出“20” Response.Write Request.QueryString("values")(2)%>
在 ASP .NET 中,QueryString 属性返回 NameValueCollection 对象,在检索所需的实际项之前,将需要从该对象中检索 Values 集合。另外需要注意,集合中的第一项是使用 0 而非 1 索引进行检索的:
<% '输出“10” Response.Write (Request.QueryString.GetValues("values")(0)) '输出“20” Response.Write (Request.QueryString.GetValues("values")(1))%>
下列代码在 ASP 和 ASP .NET 中的运行结果相同:
<% '输出“10”和“20” Response.Write (Request.QueryString("values"))%>
结构变化
结构变化将影响 Active Server Pages 的布局和编码样式。您需要了解其中的一些信息,以确保您的代码能够在 ASP .NET 中运行。
代码块:声明函数和变量
在 ASP 中,可以在代码分隔符之间声明子程序和全局变量。
<% Dim X Dim str Sub MySub() Response.Write "这是一个字符串。" End Sub %>
在 ASP .NET 中,不允许以这种方式进行声明。您必须在 <script> 块中声明所有函数和变量。
<script language = "vb" runat = "server"> Dim str As String Dim x, y As Integer Function Add(I As Integer, J As Integer) As Integer Return (I + J) End Function</script>
混合编程语言
在 ASP 中,基本上有两种编程语言供您选择:VBScript 或 Microsoft® JScript®。在同一网页中,您可以随意组合和匹配各种脚本块。
在 ASP .NET 中,目前有三种语言可供您选择:C#、Visual Basic .NET 或 JScript。注意,我说的是 Visual Basic .NET,而不是 VBScript。这是因为 .NET 平台上不存在 VBScript,它已被完全集成到 Visual Basic .NET 中。虽然可以自由选择其中的任意一种语言,但需要注意的是,您不能像在 ASP 中那样在同一网页中使用多种语言。您的确可以在同一个应用程序的 Page1.aspx 中使用 C# 代码,而在 Page2.aspx 中使用 Visual Basic .NET 代码,只是您不能在同一页中混用它们。
新增的 Page 指令
在 ASP 中,必须将所有指令置于网页中同一分隔块内的第一行。例如:
<%LANGUAGE="VBSCRIPT" CODEPAGE="932"%>
在 ASP .NET 中,需要将 Language 指令替换为 Page 指令,如下所示:
<%@Page Language="VB" CodePage="932"%><%@QutputCache Duration="60" VaryByParam="none" %>
可以根据需要包含任意多行指令。指令可以位于 .apsx 文件中的任意位置,但标准做法是将其置于文件的最开头。
在 ASP .NET 中新增了几个指令。我鼓励您在 ASP .NET 文档中查看一下这些指令,了解它们可以为您的应用程序带来什么样的好处。
生成函数不再有效
开发者指出,在 ASP 中,他们可以使用“生成函数”灵活处理一些问题。“生成函数”基本上是一个子程序,在其主体中嵌入了大量 HTML。例如:
<%Sub RenderMe()%><H3> 这是正在生成的 HTML 文本。</H3><%End SubRenderMe%>
虽然使用这类函数能够实现非常酷的功能,但 ASP .NET 中不允许使用这类编码。这可能是出于优化性能的考虑。我想您肯定遇到过,像这样将代码与 HTML 混在一起时,有些函数很快就变得可读性极差,而且难以管理。在 ASP .NET 中,实现此目的的最简单方法是调用 Response.Write 来代替 HTML 输出,如下所示:
<script language="vb" runat="server"> Sub RenderMe() Response.Write("<H3> 这是正在生成的 HTML 文本。</H3>") End Sub</script><% Call RenderMe()%>
注意,我说的是“最简单的方法”,但并不一定表示是最佳方法。根据生成代码的复杂程度和数量,使用自定义 Web 控件效果可能更好,这种控件允许您通过编程设置 HTML 属性,并将代码与内容真正分开,使代码可读性更强。
Visual Basic 语言的变化
正如我前面提到过的,VBScript 已集成到了更完整、功能更强大的 Visual Basic .NET 中。这一节,我将重点讲述您可能会遇到的与 Visual Basic 语言变化有关的一些问题。但需注意,这并不是详尽的 Visual Basic 变化列表。我只是着重讲述作为一名 ASP/VBScript 程序员,在使用 Visual Basic .NET 向 ASP .NET 迁移时可能会遇到的一些问题。有关所有语言变化的详尽列表,请参见 Visual Basic .NET 文档。
告别 Variant 数据类型
我们熟悉它、喜欢它,对它又爱又恨。当然,我说的是 VARIANT 数据类型。.NET 中没有 VARIANT,因此 Visual Basic .NET 不支持这种数据类型。这意味着,您的所有 ASP 变量将悄悄地由 VARIANT 类型更改为 Object 类型。根据需要,应用程序中使用的大量变量可以而且应该更改为相应的基元类型。如果您的变量实际上是 Visual Basic 中的 object 类型,则只需在 ASP .NET 中将其显式声明为 Object 类型。
Visual Basic Date 类型
值得特别注意的一种 VARIANT 类型是 VT_DATE,它在 Visual Basic 中以 Date 类型出现。在 Visual Basic 中,使用四个字节以 Double 格式存储 Date。在 Visual Basic .NET 中,Date 使用公共语言运行库 DateTime 类型,该类型使用八个字节整数表示。
由于 ASP 中的所有类型都是 VARIANT,对于所需的 Date 变量,将根据它们的使用方式进行编译并可以继续使用。但是,使用变量执行某些操作时,由于基本类型已发生变化,所以可能会遇到一些意想不到的问题。在将日期值作为长整型值传递给 COM 对象时,或使用 CLng 对日期类型执行某些计算时,需特别注意。
Option Explicit 现在是默认值
在 ASP 中,可以使用 Option Explicit 关键字,但它不是默认值。在 Visual Basic .NET 中,情况有所不同。Option Explicit 现在是默认值,因此,所有变量都需要声明。更严格地要求声明并将设置更改为 Option Strict 是一种比较明智的作法。这样做将迫使您将所有变量声明为特定的数据类型。乍看起来这是一项额外的工作,但实际上这是正确的做事方式。如果不这样做,您的代码将达不到最优状态,因为所有未声明的变量都将更改为 Object 类型。大多数隐式约定仍然有效,但如果将所有变量显式声明为所需类型,则能达到更好的效果,而且更安全。
不再支持 LET 和 SET
可以将一个对象直接赋值给另一对象,如 MyObj1 = MyObj2,而不再需要使用 SET 或 LET 语句。如果使用了这些语句,必须将其删除。
在方法调用中使用括号
在 ASP 中,您可以任意调用对象方法,而不必使用括号,如下所示:
Sub WriteData() Response.Write "这是数据"End SubWriteData
在 ASP .NET 中,所有调用都必须使用括号,即使是调用不带任何括号的方法。如下例所示编写代码,使其在 ASP 和 ASP .NET 中都可以正确运行。
Sub WriteData() Response.Write("这是数据")End SubCall WriteData()
ByVal 现在是默认值
在 Visual Basic 中,默认情况下,所有参数都通过引用或 ByRef 进行传递。在 Visual Basic .NET 中,情况有所不同。现在,默认情况下,所有参数都通过值或 ByVal 进行传递。如果仍要使用 ByRef,必须在参数前面显式使用 ByRef 关键字,如下所示:
Sub MyByRefSub (ByRef Value) Value = 53;End Sub
这一点必须特别注意。向 ASP .NET 迁移代码时,建议您仔细检查方法调用中使用的每个参数,确保这种变化是您真正需要的。我想您可能需要更改其中的某些参数。
不再有默认属性
在 Visual Basic .NET 中,不再存在默认属性的概念。这就意味着,如果您的 ASP 代码依赖于某个对象提供的默认属性,则需要更改为显式引用所需属性,如下列代码所示:
'ASP 语法(隐式检索 Column Value 属性)Set Conn = Server.CreateObject("ADODB.Connection")Conn.Open("TestDB")Set RS = Conn.Execute("Select * from Products")Response.Write RS("Name")'ASP.NET 语法(显示检索 Column Value 属性)Conn = Server.CreateObject("ADODB.Connection")Conn.Open("TestDB")RS = Conn.Execute("Select * from Products")Response.Write (RS("Name").Value)
数据类型的变化
在 Visual Basic .NET 中,Integer 值现在是 32 位,Long 类型已变成 64 位。
从 ASP .NET 中调用 COM 对象方法时,或调用自定义 Visual Basic 组件中的 Microsoft® Win32® API 调用时,可能会出现问题。应特别注意需要的实际数据类型,确保传递或计算的值正确。
结构化异常处理
虽然人们所熟悉的 On Error Resume Next 和 On Error Goto 错误处理技术在 Visual Basic .NET 中仍可使用,但它们不再是进行错误处理的最佳方法。Visual Basic 现在具有一种完善的结构化异常处理方法,它使用 Try、Catch 和 Finally 关键字。如果可能,您应该迁移到这种新模式进行错误处理,因为它具有更强大、更一致的应用程序错误处理机制。
与 COM 有关的变化
随着 .NET 框架和 ASP .NET 的诞生,COM 实际上没有发生任何变化。但这并不表示在 ASP .NET 中使用 COM 对象时不必担心和考虑他们的行为。有一些基本情况,您必须了解。
线程模式的变化
ASP .NET 线程模式是多线程单元 (MTA)。这就意味着,对于目前使用的为单线程单元 (STA) 创建的组件,如果不采取额外的措施,将不能在 ASP .NET 中可靠地执行或运行。其中包括但不限于使用 Visual Basic 6.0 及其更低版本创建的所有 COM 组件。
ASPCOMPAT 属性
您将很高兴听到这样一个消息:仍然可以使用这些 STA 组件,而不需要更改任何代码。您需要做的工作只是在 ASP .NET 网页的 <%@Page> 标记中包含兼容性属性 aspcompat=true,如 <%@Page aspcompat=true Language=VB%>。使用此属性将强制网页以 STA 模式执行,从而确保您的组件可以继续正确运行。如果试图使用 STA 组件但没有指定此标记,运行时将会发生异常情况。
将此属性的值设置为 true 时,将允许网页调用 COM+ 1.0 组件,该组件需要访问非管理的 ASP 内置对象。可以通过 ObjectContext 对象进行访问。
如果将此标记的值设为 true,性能会稍微有些下降。建议只在确实需要时才这样做。
早期绑定与后期绑定
在 ASP 中,对 COM 对象的所有调用都是通过 IDispatch 接口进行的。这种行为被称为“后期绑定”,因为对实际对象的调用是在运行时通过 IDispatch 间接处理的。在 ASP .NET 中,只要您愿意,可以继续以这种方式调用您的组件。
Dim Obj As ObjectObj = Server.CreateObject("ProgID")Obj.MyMethodCall
仍然可以使用这种方式访问您的组件,但这不是首选方式。现在,在 ASP .NET 中,您可以利用早期绑定直接创建对象,如下所示:
Dim Obj As New MyObjectMyObject.MyMethodCall()
使用早期绑定,可以通过类型安全的方式与组件交互。为了在 COM 组件中使用早期绑定,您需要像在 Visual Basic 6.0 项目中添加 COM 引用一样,在项目中添加一个引用。假设您正在使用 Visual Studio .NET,将在 COM 组件之上后台创建一个管理的代理对象,给您的感觉就好像是直接在处理一个 .NET 组件,而不是 COM 组件。
现在,您可能会担心性能问题。由于代理对象而引入了一个额外的层,所以使用 COM 协同操作时确实会存在一些问题。但是,大多数情况下,应该不会遇到什么问题,因为进行协同操作的实际 CPU 指令数仍然远远小于间接 IDispatch 调用的要求。您所得到的将远远超出您所失去的。当然,理想情况是使用最新创建的管理对象,但我们知道,由于我们在 COM 组件上的投入所限,并不总是能够立即做到这一点。
OnStartPage 和 OnEndPage 方法
需要特别注意的是对旧版 OnStartPage 和 OnEndPage 方法的使用。如果您依赖于这些方法访问 ASP 固有对象,将需要使用 ASPCOMPAT 指令和 Server.CreateObject 以早期绑定方式创建组件,如下所示:
Dim Obj As MyObjObj = Server.CreateObject(MyObj)Obj.MyMethodCall()
注意,我们并没有使用“ProgID”,而是以早期绑定方式使用实际类型。为了让这种方式有效,您需要在 Visual Studio 项目中添加 COM 组件引用,这样才能创建早期绑定的包装类。这是唯一必须继续使用 Server.CreateObject 的情况。
COM 总结
表 2 总结了为继续有效使用 COM 组件而必须完成的一些工作。
表 2:旧版 COM 对象的 ASP .NET 设置
COM 组件类型/方法 ASP .NET 设置/过程
自定义 STA(标记为“Apartment”的 Visual Basic 组件或其它组件) 使用 ASPCOMPAT 和早期绑定
自定义 MTA(标记为“Both”或“Free”的 ATL 或自定义 COM 组件) 不使用 ASPCOMPAT,使用早期绑定
固有对象(通过 ObjectContext 访问) 使用 ASPCOMPAT 和早期绑定
OnStartPage 和 OnEndPage 使用 ASPCOMPAT 和 Server.CreateObject(Type)
无论您的组件是否部署在 COM+ 中,都将同样应用这些设置。
应用程序配置的变化
在 ASP 中,所有 Web 应用程序配置信息都存储在系统注册表和 IIS 配置数据库中。由于服务器上经常未安装适当的管理工具,使得查看或修改设置变得非常困难。ASP .NET 引入了一整套全新的配置模型,这套模型以简单的、易读的 XML 文件为基础。每个 ASP .NET 应用程序都有自己的 Web.Config 文件,该文件位于主应用程序目录中。可以通过此文件控制 Web 应用程序的自定义配置、行为和安全性。
如果您与我一样,您可能会通过“Internet 服务管理器”管理单元检查和更改 ASP .NET 应用程序的设置。但是,您必须了解,现在我们拥有两种完全不同的配置模型。除一些安全性设置外,ASP .NET 应用程序将忽略使用 IIS 管理工具配置的其它大部分设置。您需要将这些配置设置保存在 Web.Config 文件中。
有关 .NET 的应用程序配置将在另一篇文章中详细讨论,此处就不详细介绍了。表 3 说明了可以在自己的文件中配置的一些更有意义的设置。记住,还有更多设置。
表 3:Web.Config 设置示例
设置 说明
<appSettings>
配置自定义应用程序设置。
<authentication>
配置 ASP .NET 身份验证支持。
<pages>
标识网页特定的配置设置。
<processModel>
配置 IIS 系统中的 ASP .NET 进程模型设置。
<sessionState>
指定会话状态选项。
在 .NET 基本类库中还有其它一些类可用,它们简化了对这些设置的编程访问。
状态管理
如果应用程序使用 Session 或 Application 固有对象存储状态信息,则在 ASP .NET 中可以继续使用这些对象,而不会出现任何问题。随之带来的好处是,现在提供了更多的状态存储位置选项。
状态管理选项
ASP .NET 中还包含其它一些状态管理模型选项,最终可使您管理不止一个 Web 服务器,并支持通过 Web 场进行状态管理。
可以在 web.config 文件的 <sessionState> 一节中配置状态管理选项,如下所示:
<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"/>
模式属性指定将在何处存储状态信息。可用选项有 Inproc、StateServer、SqlServer 或 Off。
表 4:会话状态存储信息
选项 说明
Inproc 会话状态本地存储在此服务器中(ASP 样式)。
StateServer 会话状态远程(或本地)存储在状态服务进程中。
SqlServer 会话状态存储在 SQL Server 数据库中。
Off 会话状态被禁用。
如果使用这些选项之一,StateConnectionString 和 sqlConnectionString 无疑将成为至关重要的参数。每个应用程序只能使用一个存储选项。
存储 COM 组件
需记住的的一点是,如果您依赖于对 Session 或 Application 对象中旧版 COM 组件的存储引用,将无法在应用程序中使用新的状态存储机制(StateServer 或 SqlServer)。您将需要使用 Inproc。部分原因是对象需要在 .NET 中实现自我串行,很显然,COM 组件无法做到这一点。另一方面,新创建的管理组件可以相对轻松地实现这一点,因此可以使用新的状态存储模式。
性能
当然,就性能而言,每前进一步都将付出相应的代价。但您完全可以相信,大多数情况下,使用 Inproc 依然是最佳选择,其后依次是 StateServer 和 SqlServer。您自己应该对应用程序进行测试,确保选定的选项可以达到您的性能目标。
ASP 和 ASP .NET 之间的共享状态
需要考虑的另外一个重要问题是,虽然应用程序可以同时包含 ASP 和 ASP .NET 网页,但您无法共享固有 Session 或 Application 对象中存储的状态变量。可能需要将这些信息复制到这两个系统中或提出其它自定义解决方案,才能完全迁移您的应用程序。最好的情况是您未使用 Session 和 Application 对象。另一方面,如果您大量使用了这些对象,您需要一直小心谨慎,或许可以提出某种自定义的短期解决方案来共享状态。
与安全性有关的变化
安全性是需要特别注意的另一个重要问题。下面简要介绍了 ASP .NET 安全性系统。有关安全性问题更完整的研究,请参见 ASP .NET 安全性文档。
ASP .NET 安全性主要受 web.config 文件中安全性部分的设置控制。ASP .NET 与 IIS 协同工作,为您的应用程序提供完善的完全性模型。IIS 安全性设置是实际携带并应用于 ASP .NET 应用程序的少数几个应用程序设置,其携带和应用方式与在 ASP .NET 中相似。当然,在很多方面都得到了改进。
身份验证
对于身份验证,ASP .NET 支持表 5 中所示的选项。
表 5:ASP .NET 身份验证选项
类型 说明
Windows ASP .NET 使用 Windows 身份验证。
Forms 基于 Cookie 的自定义登录表单。
Passport 非 Microsoft 提供的 Passport Service。
None 不执行身份验证。
除新增加的 Passport 身份验证选项之外,其它选项都与 ASP 中的选项相同。例如,下列配置对应用程序启用基于 Windows 的身份验证。
<configuration> <system.web> <authentication mode="Windows"/> </system.web></configuration>
授权
用户通过身份验证后,将集中考虑允许他们访问哪些资源。在下例中,授予了“jkieley”和“jstegman”访问权限,而其他所有人都被拒绝访问。
<authorization> <allow users="NORTHAMERICA\jkieley, REDMOND\jstegman"/> <deny users="*"/></authorization>
模拟
做为刷新程序,模拟是指这样一个过程:对象以它所代表的实体的标识执行代码。在 ASP 中,模拟允许您的代码代表通过身份验证的用户运行。或者,用户也可以通过特定标识匿名运行。默认情况下,ASP .NET 不会针对每个请求进行模拟。这一点与 ASP 不同。如果您依赖于这种功能,则需要在 web.config 文件中启用它,如下所示:
<identity> <impersonation enable = "true"/></identity>
数据访问
迁移过程中,需要重点考虑的另一个关键问题是数据访问。随着 ADO .NET 的诞生,现在您具有了一种访问数据的强有力的全新方法。由于数据访问本身就是一个很大的主题,本文就不详细讨论了。大多数情况下,您可以像过去一样继续使用 ADO,但是我极力推荐您了解一下 ADO .NET,并通过它改善 ASP .NET 应用程序中的数据访问方法。
准备向 ASP .NET 迁移
现在您已了解了可能会遇到的大多数问题,您可能会想:目前我需要做好哪些准备工作以备将来最终迁移到 ASP .NET 呢?目前确实需要完成几项工作,以确保将来的迁移过程顺利进行。其中的许多建议对您的 ASP 代码大有益处,即使目前不打算向 ASP .NET 迁移。
使用 Option Explicit
这始终是一个不错的建议,但至今仍然有许多人没有使用它。通过使用 Option Explicit,强制在 ASP 中声明变量,您至少可以控制在何处定义每个对象以及如何使用变量。迁移到 ASP .NET 之后,我建议使用 Option Strict。在 Visual Basic .NET 中,默认使用 Option Explicit,但是使用更具强制性的 Option Strict,可以确保所有变量都声明为正确的数据类型。这样做确实需要增加一些额外的工作,但从长期考虑,您将发现还是很值得这样做的。
避免使用默认属性
我们前面已讨论过,不再允许使用默认属性。显式访问属性并不是什么难事。它将增强代码的可读性,而且可以在将来节省您的时间。
使用括号和 Call 关键字
正如本文前面详细讨论过的,应尽可能使用括号和 Call 语句。在 ASP .NET 中,将强制使用括号。现在使用 Call 语句有助于您熟悉一些规则,为将来的工作打好基础。
避免嵌套的包含文件
这一点可能说起来容易做起来难,但还是应尽可能避免嵌套包含文件。我的意思是说,应该努力避免在包含文件中包括其它包含文件。随着时间的推移,可能会碰到的一种情况是,您的代码不再依赖于在其它某处的包含文件中定义的全局变量,您需要访问的原因仅仅是因为其中嵌套了包含您真正需要的全局变量的另一个文件。
向 ASP .NET 迁移时,您很有可能会将全局变量和程序迁移到类库中,这种情况下,如果您清楚地了解每个对象的访问位置,迁移起来就很容易。您不需要将一些对象移来移去,也不需要更改多个文件中相同的那些程序名称。
将实用函数合并到单个文件中
迁移过程中的一个策略是将服务器端包含文件中包含的所有实用函数和代码迁移到 Visual Basic 或 C# 类库中。这样,您最终可以将所有代码放到所属对象中,这一点与多解释的 ASP 文件不同。提前组织好代码,可以节省将来的迁移时间。理论上讲,您应该可以将子程序组合到逻辑文件中,从而使您可以轻松地创建一组 VB 或 C# 类。这些函数可能应位于 COM 对象中。
如果服务器端包含文件中存在一大堆全局变量或常量,也最好考虑将他们组合到单个文件中。一旦迁移到 ASP .NET 后,您就可以轻松创建一个类来存放全局或常量数据。这将使系统更干净、更易维护。
尽可能将代码与内容分开
这又是一件说起来比做起来容易的工作,但是您应该尽量将代码与 HTML 内容分开。清理一下主体中即有代码、又有脚本的那些函数。这样做使您处于非常有利的位置,可以充分利用代码--无论怎么说,这是 ASP .NET 中的最佳模式。
不要在 <% %> 块声明函数
ASP .NET 不支持在 <% %> 块声明函数。应该在 <script> 块进行声明。有关此技术的示例,请参阅本文前面的结构变化一节。
避免使用生成函数
如前所述,应该尽量避免使用“生成函数”。如果现在可以更改或准备代码,应在构造这类函数时使用 Response.Write 块。
显式释放资源(调用 Close 方法)
确保对使用的对象和资源中存在的 close() 或清理方法进行显式调用。我们都知道,Visual Basic 和 VBScript 在清理方面的容错能力很强。通常情况下,他们能够立即清理对象。但迁移到 .NET 后,您将无法准确掌握对象何时会被清理,就像您无法确定垃圾堆中的垃圾何时会被清理一样。如果您能够显式清理和释放资源,最好显式地进行清理和释放。
避免混用语言
应该尽量避免在同一网页中混用服务器端 VBScript 和 JScript。一般而言,这是一种不太明智的编程方式。而且向 ASP .NET 迁移时还会存在问题,因为由于采用了新的编译模式,每个网页只要求一种内嵌 <% %> 语言。但仍然可以使用过去的方式生成客户端脚本。
总结
正如我们已经了解的,在向 ASP .NET 迁移应用程序之前,有许多问题需要考虑。我在此文中归纳了迁移前后会发生的大多数变化,这应该能使您的迁移过程变得相对简单一些。
如果您拥有一个大型站点,完成此进程之后,您可能会对遇到并修正了如此多的死代码、无效代码以及所有 Bug 而惊奇不已。另外,通常您还可以充分利用 ASP .NET 和 .NET 平台中大量强大的新增功能。