常见的 ASP.NET 2.0 转换问题和解决方案
简介
将 ASP.NET 1.x 应用程序转换到新的 ASP.NET 2.0 框架时,您可能会遇到由于 2.0 框架的更改而引起的问题。在本文中,我们将着眼于转换过程本身以及您在转换过程中可能遇到的某些常见问题。
什么是 ASP.NET 2.0?
ASP.NET 2.0 在 ASP.NET 1.x 框架基础上进行了重要更新。ASP.NET 2.0 不仅引入了许多新增功能,还从根本上改变了 ASP.NET 应用程序的设计、编译和部署方式。尽管 ASP.NET 1.1 应用程序不必进行重新编译就可以在 ASP.NET 2.0 上运行,但是您会发现升级后使用 ASP.NET 2.0 的新增功能既可以简化开发过程,又为您提供了更多种编译和部署代码的方法。如果您不熟悉 ASP.NET 2.0 或不了解升级的好处,请阅读从 ASP.NET 1.x 迁移到 ASP.NET 2.0。
就升级应用程序的过程而言,您需要了解将会影响应用程序的编译和部署方式的操作问题。另外,还需要了解新增编码功能对转换过程的影响,以及如何使用新增功能改进应用程序。
操作方面的更改
操作方面的更改会影响您开发、配置和部署 ASP.NET 应用程序的方式。无论您是开发人员还是网站管理员,都需要了解这些更改,以便正确地创建、部署和维护 ASP.NET 2.0 应用程序。
• |
没有项目文件。ASP.NET 1.x 应用程序与 2.0 应用程序之间最明显的差别就是后者没有项目文件(例如 *.vbproj 或 *.csproj)。在 1.x 应用程序中,项目文件包含生成设置、对外部程序集的引用以及项目中的文件列表。而在 2.0 应用程序中,不再需要版本设置和文件列表,因为 Web 项目目录下的所有文件都被视为 Web 项目的一部分。 |
• |
特殊目录。ASP.NET 1.x 应用程序具有一个必需的目录 (\bin),用于包含程序集。ASP.NET 2.0 应用程序中则定义了一种更大的目录结构。新目录均以前缀“App_”开头,用于存储资源、程序集、源代码和其他组件。使用这种新的目录结构将不再需要项目文件,并且还可以选用某些新的部署方法。 |
• |
代码分离模式。在 ASP.NET 1.x 中,代码分离模式使内容(例如 foo.aspx)与代码(例如 foo.aspx.vb)分离。内容页面从代码分离页面继承而来,代码分离页面包含用户和设计器生成的代码。ASP.NET 2.0 通过使用局部类来增强代码分离模式,它允许一个类跨越多个文件。在新的代码分离模式中,内容页面从编译的类继承而来,它由相应的代码分离页面以及自动生成的存根文件组成,存根文件用于为内容页面中使用的控件定义字段声明。此项更改使自动生成的代码与用户的代码分离,并且使代码分离页面显著变小且更加简洁。局部类结构还降低了由于编辑设计器生成的代码而不小心破坏页面的风险。 |
• |
编译模式(一个程序集对多个程序集)。在 ASP.NET 1.x 中,所有的内容页面、代码分离页面和支持代码都预先编译到具有固定名称的单个程序集中。在 ASP.NET 2.0 中,则即时(默认)创建文件名各不相同的多个程序集。例如,每个 ASPX 页面(由内容页面、代码分离页面和隐藏的设计器页面组成)将被编译到各自的程序集中。App_Code 目录会自动把公共源代码编译到它自己的程序集中。这种新的编译模式使 ASP.NET 应用程序的结构发生了一些变化,但大大丰富了部署方式,以及在 Web 服务器上提供 Web 应用程序的方式。 |
• |
部署方式(预编译、完整编译、可更新站点等)。在 ASP.NET 1.x 中,Web 应用程序是作为一个大型程序集而预编译和部署的。内容页面(例如 *.aspx)不在服务器上编译,但可以在服务器上编辑。借助新的页面编译模式和目录结构,您就可以使用多种不同的配置来部署 ASP.NET 2.0 应用程序。在一种极端的情况下,您可以预编译所有的 ASPX 页面并部署由完全编译好的程序集组成的 Web 应用程序。在这种模式下,您不能在服务器上轻松地更改该应用程序。在另一种极端情况下,您可以在不预编译任何代码的情况下部署应用程序。在这种配置下,您可以直接在服务器上更改该应用程序中的 .aspx 页面、代码分离文件或其他任何代码。当用户请求服务器上的页面时,页面将被动态编译。 |
以上每项更改都可能需要您在转换 Web 应用程序之前或之后修改应用程序的体系结构和部署过程。
新增功能
将 Web 应用程序转换到 ASP.NET 2.0 会使该应用程序更加强大、灵活和易于维护。尽管本文着重于转换应用程序的技术细节,但是您可以通过下列链接了解有关 ASP.NET 2.0 新增功能的更多信息:
• |
Feature Overview |
• |
Personalization |
• |
Data Access |
• |
Master Pages |
• |
ASP.NET Development Server |
一般来讲,在尝试执行任何新增功能之前,您都需要将 ASP.NET 1.x 应用程序转换到 ASP.NET 2.0。每个转换过程都包括两个步骤。第一步,达到功能上的等效,第二步,使用新增功能。将 ASP.NET 应用程序从 1.x 转换到 2.0 也是这样。首先,您需要使应用程序能够在 2.0 环境下运行。然后,您需要对应用程序进行评估,以找出需要使用 ASP.NET 2.0 的新增功能和控件的位置。
转换应用程序
将应用程序从 ASP.NET 1.x 转换到 ASP.NET 2.0 不仅仅涉及到更改对 Framework 版本的引用。事实上,主要有三个方面的更改会影响应用程序的构建方式:
1. |
ASP.NET 2.0 Web 应用程序不使用项目文件(.vbproj 或 .csproj)。项目文件内容已被消除或转变为 web.config 文件。 |
2. |
编译模式发生了多方面的变化。不仅代码分离文件与 ASPX 页面之间的关系发生了变化,而且应用程序不再编译到单个程序集中。 |
3. |
创建了新的目录结构以便可以使用新的编译模式和部署选项。所有资源文件、引用、代码分离文件和其他代码产物都必须移到各自的新目录下。 |
所幸的是,许多由于 ASP.NET 框架的更改而必须实施的应用程序更改已在转换向导中自动实施。
事先的计划
在转换应用程序之前,您应该通读本白皮书中的常见转换问题部分,然后检查您的应用程序。您可能会发现需要更改 1.1 代码以帮助改进转换过程的区域。您还可能希望着眼于转换应用程序所需的时间和培训,以及计划如何对服务器进行更新以支持 ASP.NET 2.0。
前提条件
转换应用程序之前,需要确保满足以下条件:
1. |
所有开发人员都可以使用 Visual Studio 2005。 |
2. |
目标服务器上已安装了 .NET Framework 2.0。(请注意,由于已经使用 ASP.NET 2.0 对捆绑的 ASP.NET Development Server 进行了配置,因此您可以立即开发和运行 Web 应用程序。) |
3. |
已验证现有的所有 ASP.NET 1.x 应用程序都运行正常。 |
您可以阅读本白皮书结尾的“更新服务器”部分来了解有关配置生产服务器的信息。
转换向导
Visual Studio 2005 具有一个内置的转换向导,此向导有助于转换 ASP.NET 1.x 应用程序。此向导将自动执行许多必需的基本步骤,能使应用程序满足 ASP.NET 2.0 中内置的新增结构要求和编码要求。
运行转换向导
当您在 Visual Studio 2005 中打开 ASP.NET 1.x Web 应用程序时,将会自动调用转换向导。该向导将检测应用程序目录下是否存在项目文件(例如 *.vbproj 或 *.csproj),并自动启动转换过程。
![](http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/upgradingaspnet01.gif)
图 1:转换向导
您要做出的第一个选择是,要执行在位转换还是要在转换之前创建应用程序的备份。
![](http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/upgradingaspnet02.gif)
图 2:备份应用程序
如果您选择创建备份,Visual Studio 2005 将会在您选择的目录下自动创建 ASP.NET 1.x 应用程序的副本。
接下来,您将会看到转换过程的摘要屏幕,这是最后一个可以停止转换的机会。
![](http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/upgradingaspnet03.gif)
图 3:摘要屏幕
转换需要花费几分钟时间,这取决于应用程序的大小。但是,当转换完成时,您将看到一条消息,指明代码已转换。还可能会看到一条关于某些警告或错误的消息。当转换向导进行的更改可能会修改应用程序的行为时,或者当转换向导无法将应用程序完全更新到 ASP.NET 2.0 时,就会出现警告和错误。
![](http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/upgradingaspnet04.gif)
图 4:转换完成
转换完成后,您就可以查看转换报告,从而检查是否需要执行任何其他步骤以完成从 ASP.NET 1.x 到 2.0 的转换。
转换报告
当转换向导完成对项目的升级后,它会在显示 XML 版本的转换报告之前自动生成 XML 版本和文本版本的转换报告。此报告将向您显示转换向导所遇到的任何问题,以及您可能需要执行其他步骤以完成转换的代码区域。
![](http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/upgradingaspnet05S.gif)
图 5:转换报告
报告根据转换的每个解决方案和项目分成几个部分。解决方案报告部分几乎始终不会出现错误。但是项目报告部分可能会列出有关项目中每个文件的多个问题。
如果您关闭转换报告,则始终可以在已转换项目的顶层找到文本版本的转换报告。
通知类型
报告中的每一项都属于以下三种类别之一:
• |
通知:通知项仅通知您转换向导所执行的操作。您将看到许多关于已删除或移动的文件以及已删除或注释掉的代码的通知。正如您将在下列几个部分中看到的,向导会对每个文件执行特定的标准操作。这些操作对于转换而言是必要的,但是不需要您执行任何其他操作。 |
• |
警告:每当向导不得不采取可能会导致应用程序的行为改变的操作时,就会生成警告项。您需要检查警告项,但是可能不需要执行相应的操作。例如,如果向导不得不更改对某一条代码的访问级别,您就会看到一条警告。您应该检查此项更改以确保它不会造成任何意外结果。但是通常情况下只需检查警告,然后就可以将其忽略。 |
• |
错误:当向导遇到某些不能自动转换的内容时,就会生成错误项。这些项要求您执行某些操作以完成转换。通常,错误是当您尝试运行应用程序时会生成编译错误的内容。 |
请记住,转换报告是用来说明对 Web 项目进行的更改的日志文件。大部分通知可以忽略掉,除非您确实想了解对 Web 应用程序进行了哪些更改。您应当先检查错误和警告,因为这些项指出了可能需要您更改代码以完成转换的区域。
进行了哪些更改
转换向导将对 ASP.NET 1.x 应用程序执行一系列检查和转换。这些检查全都设计为自动执行大部分常见的转换任务。但是,转换向导可能无法完全转换应用程序。在阅读了有关转换向导可以执行的操作的内容之后,您应当通读本白皮书的常见问题部分,以查明可能需要执行的其他操作。
对代码分离文件的更改
在 ASP.NET 1.x 中,通常使用 .aspx 页面和代码分离文件将图形组件与编码组件分开。.aspx 页面是从代码分离文件派生而来的。这意味着您必须声明这两类的所有控件,以便正确绑定回调事件。这种继承关系还引发了有关使两类同步的某些问题,尤其是当开发人员对 .aspx 页面进行了更改(例如,添加一个控件)而没有对代码分离文件进行必要的更改也没有重新编译应用程序时。
在 ASP.NET 2.0 中,由于局部类这一概念的出现,代码分离模式已发生了变化。使用 partial 关键字可以将单个类的代码分隔到两个独立的文件中。代码分离文件定义了一个包含用户代码的局部类。设计器还将生成存根文件,其中包含一个局部类,用于定义 .aspx 页面中使用的控件对应的字段声明。编译后,.aspx 页面将从合并的局部类派生而来,并且被编译到它自己的页面程序集中。这种设计降低了由于编辑设计器生成的代码而不小心破坏页面的风险。
对应用程序的更改
转换向导将在下列几个方面对应用程序进行更新:
• |
将 .aspx 页面中的所有 CodeBehind 属性更改为 CodeFile 属性。 |
• |
更改所有代码分离类定义以执行 partial 关键字。 |
• |
如果在 .aspx 页面上声明了所有控件,则从代码分离文件中删除所有控件声明。 |
• |
(仅限于 C#)将事件挂钩代码从代码分离文件的 InitialzeComponent 函数移到 .aspx 页面中。请注意,此操作不适用于自动调用的事件,包括 Page_Init、Page_Load、Page_DataBind、Page_PreRender、Page_Unload、Page_Error、Page_AbortTransaction 和 Page_CommitTransaction。 |
独立的代码文件
在 ASP.NET 1.x 中,所有源代码都编译到单个程序集中。此程序集存储在应用程序目录的 /bin 目录下。为了支持新的编译选项,并针对部署提供某些增强功能,ASP.NET 2.0 实际为每个 ASP.NET Web 页面和用户控件创建了单个程序集。此外,还创建了一个单独的程序集用来保存所有独立的代码文件(即,非代码分离的代码文件)。
对应用程序的更改
转换向导将在下列几个方面对应用程序进行更新:
• |
将所有独立的代码移到 App_Code 目录下。 |
• |
将所有的默认、Friend 和 Internal 范围的声明更改为 Public。需要进行此项更改是因为代码分离文件不再与共享代码位于同一个程序集中。因此,必须更改访问级别以便与新的多程序集结构相匹配。 |
• |
将所有 Type.GetType() 调用更改为 System.Web.Compilation.BuildManager.GetType()。这种新方法可自动识别要访问哪个程序集来查找类的类型。如果您试图在代码分离文件中使用 Type.GetType(),将很可能遇到 TypeLoadException,因为代码分离文件与独立的代码位于不同的程序集中。 |
资源
由于 ASP.NET 2.0 中的新目录结构,资源文件的位置和存储已发生了变化。尤其是,ASP.NET 2.0 应用程序现在具有一个 App_GlobalResources 目录,专门用于保存资源文件。转换向导将自动把必需的资源文件重新定位到相应的位置。在 ASP.NET 2.0 中,不再需要与 Web 窗体相关联的资源文件,因此将不对其进行修改。
对应用程序的更改
转换向导通过将所有独立的资源文件移到 App_GlobalResources 目录下,对应用程序进行更新。此目录下的所有文件将内置在单个程序集中。
请注意,必须进行某些其他的代码更改,以便访问资源文件。这些代码更改在“常见转换问题”部分的“资源文件”中进行了概要介绍。
引用
在 ASP.NET 1.x 中,有三种类型的外部程序集引用方式:
• |
全局程序集缓存 (GAC):Web 应用程序依赖于位于系统的 GAC 中的某个程序集。以这种方式引用的程序集存储在项目文件中,编译器在运行时会将 Web 应用程序链接到 GAC 中的该程序集。 |
• |
项目对项目 (P2P):在转换过程中,如果解决方案中的所有项目同时转换,将保持 P2P 引用方式。 |
• |
本地:Web 应用程序依赖于在 Web 项目的解决方案外创建的某个基于文件的程序集。以这种方式引用的程序集存储在项目文件中,Visual Studio 将把该程序集的一个版本复制到 bin 目录下。如果 CopyLocal 设置为 true,则将用该程序集的最新版本来更新 bin 目录。编译器会将 Web 应用程序链接到 bin 目录下的该程序集。 |
ASP.NET 2.0 使用 bin 目录存储以 P2P 和本地方式引用的程序集。此目录不仅包含针对应用程序自动生成的程序集,还可以存储应用程序需要引用的任何其他可执行代码。
对应用程序的更改
由于 ASP.NET 2.0 应用程序没有项目文件,因此必须移动对外部程序集的引用。
• |
GAC 引用被移到 web.config 文件中。例如: <system.web> <compilation> <assemblies> <add assembly="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/> </assemblies> </assemblies> ... Other tags </compilation> ... Other tags </system.web> 对 GAC 中的程序集的 web.config 引用 |
• |
P2P 引用存储在解决方案文件中。在转换过程中,如果解决方案中的所有项目同时转换,则 P2P 引用将保持为 P2P。 |
• |
在 Visual Studio 2005 的 Beta 2 版中,本地引用的程序集不可更新。在 Visual Studio 2005 的最终版本中,通过添加 Refresh 文件修复了此行为。此文件存储在 bin 目录下,其文件名采用程序集名称加上“.refresh”的方式来生成。Refresh 文件包含指向外部引用的程序集的路径,其存在向编译器指明,如果原始程序集的时间戳时间较晚,则需要刷新此程序集及其依赖的程序集。这与 Visual Studio .NET 2003 中的“复制本地”行为相似。 |
以 P2P 和本地方式引用的程序集都被复制到 Bin 目录下。
Web 引用
与常规引用不同,Web 引用指向 Web 服务。在 Visual Studio .NET 2003 中,当您在 ASP.NET 1.x 应用程序中创建了 Web 引用后:
1. |
就在该应用程序的 Web References 目录下创建了一个目录 |
2. |
就创建了一个引用类,其中包含 Web 服务的 WSDL 中为每个对象定义的代理类。 |
3. |
就创建了一个名为 reference.map 的 discovery 文件,其中包含有关如何创建和更新 Web 引用的信息。 |
ASP.NET 2.0 更改了此过程以构成新的目录结构以及 Web 服务在 .NET Framework 2.0 中的处理方式的一些更改。
对应用程序的更改
转换向导将在下列几个方面对应用程序进行更新:
• |
将所有 Web 引用目录从 Web References 目录移到 App_WebReferences 目录下。 |
• |
在 App_Code 目录下放置 WSDL 文件的一个副本。WSDL 文件的版本提供程序将自动生成 Web 服务代理类,这些代理类已编译,并且可通过任何 Web 页面访问,因为它们存储在 App_Code 目录下。 |
• |
删除由 Visual Studio .NET 2003 生成的代理类。旧的 1.x 代理类不再是必需的,因为这些代理现在可在 App_Code 目录下自动生成。 |
• |
将 discovery 文件的扩展名 .map 更改为 .discomap。 |
Web 服务
在 ASP.NET 1.x 中,Web 服务 (.asmx) 自动拆分到空白标题页面 (.asmx) 和包含实际方法的代码分离文件中。
对应用程序的更改
转换向导将在下列几个方面对应用程序进行更新:
• |
将代码分离类移到 App_Code 目录下,以便使其自动变为可通过应用程序中的任意 ASP.NET 页面访问。 |
• |
更改 .asmx 文件中的 CodeBehind 属性,以便指向新位置。(请注意,代码分离文件不使用局部类,因此继续使用 CodeBehind 属性。) |
• |
将所有的默认、Friend 和 Internal 范围的声明更改为 Public。 |
Global.Asax
在任一 ASP.NET 应用程序中,您都可以使用 Global.asax 文件捕获特定的应用程序级事件,包括启动、关闭、会话周期、请求周期和错误消息。此文件与 Web 服务文件十分相似,它具有简单的 shell 标题页面 (.asax) 和代码分离文件。
对应用程序的更改
转换向导将在下列几个方面对应用程序进行更新:
• |
将代码分离文件移到 App_Code 目录下,以便使其自动变为可通过应用程序中的任意 ASP.NET 页面访问。 |
• |
“Code-behind”属性将从 ASAX 文件的指令中删除。 |
• |
(对于 Visual Basic)向该类文件中添加一条命名空间语句。命名空间由 Web 项目中的根命名空间定义。 |
数据集
在 ASP.NET 1.x 中,使用内置的向导或 xsd.exe 命令行工具来生成类型化 DataSet 对象。生成的代理对象存储在顶层目录下。而在 ASP.NET 2.0 中,这些 DataSet 对象以不同的方式生成和存储。
对应用程序的更改
转换向导将在下列几个方面对应用程序进行更改:
• |
将 .xsd 文件(DataSet 描述符)移到 App_Code 目录下。运行时将自动根据此文件生成类型化数据集。 |
• |
删除旧的代理文件。 |
源代码控制中的 Web 项目
转换向导假定从 ASP.NET 1.x 到 ASP.NET 2.0 的转换是一项非常重大的更改,以致于您需要对开发过程进行分叉。基于这种假定,转换向导将会在开始转换之前检出整个应用程序,然后从源代码控制树删除生成的代码。完成转换后,您必须将项目添加回源代码控制系统。
对应用程序的更改
如果项目位于与 Visual Studio 2005 集成的源代码控制系统中,则转换向导将执行下列操作:
• |
检出与当前项目相关联的每个文件。 |
• |
执行转换。 |
• |
从源代码控制删除生成的代码。请注意,Microsoft FrontPage Web 应用程序将保留在源代码控制中(FrontPage 工作方式结果)。 |
• |
转换后,您需要将站点添加回源代码控制。 |
常见转换问题
尽管 ASP.NET 2.0 可以处理在 ASP.NET 1.x 中开发的代码,但是您仍然可能会遇到一个或多个常见转换问题。在本部分中,我们将着眼于几个最常见的问题。
代码分离 (CB-CB) 破坏的引用
注意:CB 是表示用于 Web 窗体或用户控件的代码分离文件(*.aspx 或 *.ascx)的缩写词。
新的 ASP.NET 2.0 编译模式使用通常在服务器上动态编译的多个程序集。此模式改善了 Web 站点的性能和可更新性。
但是如果 ASP.NET 1.x 代码分离文件引用另一个代码分离文件,那么引用将被破坏,因为引用的代码分离文件将不再位于同一个程序集中。
下面列出了可能导致这种问题的常见情况:
• |
使用 LoadControl() 并将结果转换到另一个用户控件,例如 |
• |
创建 Web 窗体类的实例,例如 |
如何修复
要解决此问题,需要更改应用程序以使其能够找到引用。既然这是一个 CB-CB 破坏的引用,因此解决问题的最简单的方法就是向进行引用的 Web 窗体或用户控件添加一个引用指令。此方法将告知编译器要链接到的程序集。
假定您处于以下情况:
原 ASP.NET 1.x 代码 | |
文件(位于 WebAppRootFolder 下) | 代码 |
Page1.ascx |
|
- Page1.ascx.cs |
Control1 c = (Control1)LoadControl("~/Control1.ascx"); |
Control1.ascx |
|
- Control1.ascx.cs |
更改代码以使用引用指令:
ASP.NET 2.0 版本 | |
文件(位于 WebAppRootFolder 下) | 代码 |
Page1.ascx |
<%@ Reference Control="~/Control1.ascx" %> |
- Page1.ascx.cs |
Control1 c = (Control1)LoadControl("~/Control1.ascx"); |
Control1.ascx |
|
- Control1.ascx.cs |
通过使用该引用指令,明确地告知编译器查找要使用的 Web 窗体或控件的位置。请注意,在 Visual Studio 2005 的最终版本中,转换向导将自动执行此操作。
独立类文件 (SA?"CB) 破坏的引用
注意:SA 是表示独立类文件的缩写词。
如果某个独立类文件引用了代码分离文件中的代码,则您可能会遇到另一种破坏的引用。这种引用与 CB-CB 破坏的引用相似,只不过 App_Code 目录下的某个独立类文件试图引用单独的页面程序集。同样,会导致这种问题的常见情况包括使用 LoadControl() 调用或创建 CB 类的实例。
如何修复
修复 SA-CB 破坏的引用要复杂的多。既然问题发生在 SA 文件中,您就不能使用引用指令来查找该引用。而且,转换之后,SA 文件将移到 App_Code 目录下,因此您只能在 App_Code 程序集被编译后访问该程序集。
解决方案是在 App_Code 目录下创建要在编译时引用的抽象基类,这将在运行时从页面程序集加载实际类。
假定您处于以下情况:
原 ASP.NET 1.x 代码 | |
文件(位于 WebAppRootFolder 下) | 代码 |
Control1.ascx |
inherits="Control1" |
- Control1.ascx.cs |
class Control1 :System.Web.UI.Page { |
Code1.cs |
Control1 c = (Control1)LoadControl("~/Control1.ascx"); |
更改代码以使用引用指令:
ASP.NET 2.0 版本 | |
文件(位于 WebAppRootFolder 下) | 代码 |
Control1.ascx |
inherits="d_Control1" |
- Control1.ascx.cs |
class d_Control1 :Control1 { |
App_Code\Code1.cs |
Control1 c = (Control1)LoadControl("~/Control1.ascx"); |
App_Code\Stub_Control1.cs |
abstract class Control1 :System.Web.UI.Page { |
由于抽象集类现在位于 App_Code 目录下,因此它将允许独立类文件和 CB 文件在编译过程中查找类(在本示例中名为 Control1)。但是,在运行时,独立类文件将使用后期绑定来加载原始类(在本示例中重命名为 d_Control1)。请注意,在 Visual Studio 2005 的最终版本中,转换向导将自动为您创建此代码。
代码分离文件中的附加类型
在 ASP.NET 1.x 中,通过将类型(例如,结构、枚举、界面和模块等)存储在一个用于 Web 窗体或用户控件的代码分离文件中,可以在不同的页面之间共享这些类型。
在 ASP.NET 2.0 中,由于 Web 窗体和用户控件被编译到各自的程序集中,因此此模式被破坏,无法再发现附加类型。
如何修复
当转换向导转换完应用程序之后,只将任一非私有附加类型移到它在 App_Code 目录下专用的独立代码文件中。您还需要将该类型的访问修改符更改为 public,因为该类型必须在多个程序集中工作。共享类型将自动编译,并且可通过 Web 应用程序发现。
请注意,在 Visual Studio 2005 的最终版本中,转换向导将自动执行此操作。生成的独立文件将位于 Migrated 子目录下,该文件的文件名将基于在其中找到附加类型的文件以及所找到的类型的名称。您可以根据需要随意重命名此文件,只需将其保留在 App_Code 目录下即可。
同一位置处的多个 Web 项目
如果在同一解决方案中有多个 Web 项目共享同一个目录位置,则 Visual Studio 2005 将把在该位置找到的所有文件都视为单个 Web 应用程序的一部分。尽管向导会自动将所有程序集引用移到 web.config 文件中,您仍然可能遇到下列问题:
• |
由项目合并导致的命名冲突。 |
• |
如果一个 Web 项目引用另一个 Web 项目,并且两个项目合并到一起,则会产生引用问题。 |
如何修复
在转换项目之前将它们分隔开,即,将它们放在各自单独的目录位置。
模糊引用和命名冲突
.NET Framework 2.0 添加了许多新的命名空间和类。其中一些有可能导致与 ASP.NET 1.x 应用程序的冲突。例如,新的个性化功能引入了名为 Profile、Membership 和 MembershipUser 的类。Profile 名称对于要跟踪用户信息的开发人员来说是特别常用的。因此,如果应用程序中具有 Profile 类,并且您尝试使用任一新增个性化功能,则可能会遇到关于模糊类引用的编译器警告。
如何修复
针对命名冲突进行事先计划是相当困难的。您需要快速浏览新的 ASP.NET 类。如果看到可能会与应用程序中的某些内容冲突的任何名称,则需要考虑使用明确命名。例如,使用 System.Web.Security.Membership 而不导入/使用 System.Web.Security,然后使用 Membership 类。
设计视图问题
Visual Studio 2005 中内置的新增 Visual Web Designer 能够比 Visual Studio .NET 2003 得到更加严格的 HTML。如果 .aspx 页面包含不匹配的标记或格式不佳的 HTML,那么设计器将不允许您切换到 Visual Studio 2005 内的设计视图,而只能切换到代码视图,直到修复了问题为止。发生此问题是由于 Visual Studio 2005 内置的新增源代码保存和验证函数。
如何修复
避免此问题的唯一方法就是确保 .aspx 页面中的标记格式正确。如果在转换后从代码视图切换到设计视图时遇到了问题,那么几乎可以肯定是标记错误问题。
多次调用事件处理程序
由于转换向导合并代码分离文件与 .aspx 页面的方式,您可能会遇到自动调用的事件被两次调用(例如,页面加载)的情况。如果事件绑定代码不位于代码分离文件的 InitializeComponent 方法中,则会发生这种情况。转换向导只有在绑定位于 InitalizeComponent 方法中的情况下才能够删除重复的绑定。
您可能很难注意到这个错误,因为在大多数情况下,第二次事件激发不会带来危害。但是,如果您确实发现某个自动调用事件多次发生,则应检查转换后的代码分离文件,以查看处理程序是否两次被绑定到事件。如果是这样,则必须手动删除第二个绑定。
如何修复
通过浏览现有代码,并确保所有事件绑定都包含在代码分离文件的 InitialzeComponent 函数中,或者通过在页面中设置 AutoEventWireUp=False,即可完全避免此问题。
错误列表错误“错误: 无法分析文件名”
当转换报告中通知您不能分析文件时,您可能会看到这条更加模糊的错误消息。产生这种错误的实际原因有很多,其中包括:
• |
页面格式不正确。如果项目中含有格式不正确的 .aspx 页面,则向导可能无法读取该页面,也无法将其识别为 .aspx 页面。 |
• |
未找到“Codebehind”属性或“src”属性。如果 .aspx 页面不包含这两个属性中的任何一个,则向导将找不到匹配的代码分离文件,并且不能转换该页面。如果普通的 HTML 页面发生这种情况,则可以将其忽略。如果应用程序包含使用 .aspx 扩展名的纯 HTML 页面,那么您会经常遇到此错误。 |
• |
未找到代码分离文件。如果 .aspx 页面应含有代码分离文件,但在项目目录中找不到该文件,则可能会看到此错误。在这种特定情况下,您还会看到另一条错误消息:“未找到代码分离文件的文件名”。这两个错误都与同一个页面相关。第一个错误指示无法处理 .aspx 部分,第二个错误指示未找到代码分离文件。 |
• |
文件在项目文件(.csproj、.vbproj)中列出了,但不在指定的目录下。如果您添加、删除、重命名或移动 ASP.NET 项目文件内容,ASP.NET 项目文件经常会过期。如果您确定列出的文件不应是项目的一部分,则可以忽略此错误。 |
如何修复
为了避免这些问题,请在开始转换之前确保项目完整,并且项目中列出的所有文件都在指定的目录下。
移到 App_Code 目录下的代码分离文件
运行转换向导之后,您可能会发现某些代码分离文件(例如,*.aspx.cs 或 *.ascx.vb)被移到 App_Code 目录下。这表明代码分离文件的内容页面含有格式不正确的 Codebehind 指令,并且没有进行正确设置。也就是说,转换向导不能确定该代码分离文件是否实际绑定到某个特定的 .aspx 页面。
转换向导会自动将所有独立类文件(例如,*.cs 或 *.vb)移到 App_Code 目录下。如果有格式不正确的 Codebehind 指令,那么代码分离文件将被视为独立类文件,并且被移到 App_Code 目录下。
请注意,Web 服务文件(例如,*.asmx 和 *.asmx.cs)与普通的内容页面及其代码分离页面不同。Web 服务文件的代码分离页面预计位于 App_Code 目录下,因此如果在此发现一个代码分离页面,它并不是错误。
如何修复
在转换之前,确保在所有内容页面中正确设置了 Codebehind 指令,即可避免此问题。
转换之后,将代码分离文件与相关联的内容页面移到同一目录下,并更正内容页面的 Codefile 指令(在 ASP.NET 2.0 中已重命名),以便指向该代码分离文件。
不再排除以前排除的文件
在 Visual Studio .NET 2003 中,您必须明确决定是否在 Web 项目中包含各个文件。如果未明确将某个文件列为包含文件,就会从项目中排除该文件。您还可以将代码文件的生成操作设置为“无”,从而停止生成该代码文件。此信息将存储在项目文件中。
在 Visual Studio 2005 中,在 Web 应用程序目录下找到的所有文件都被作为 Web 项目的一部分而隐式包含。由于没有项目文件,因此无法明确列出要排除的文件,也无法阻止将它们内置到项目中。这样一来,Web 项目中现在就可能包含额外的文件。编译器可能会根据文件的扩展名尝试编译文件,这将导致应用程序中产生冲突。
如果将文件的生成操作设置为“无”,则转换向导将不转换这些文件。由于这些文件被视为排除文件,因此转换向导无法确定这些文件是否必要。由于这个原因,向导将在转换报告中记录一条警告,指出没有转换项目结构中的某些文件。
如何修复
如果要转换排除文件,应在转换之前将该排除文件明确包含在 Web 项目中,并确保其生成操作没有被设置为“无”。
转换之后,您可以从项目中删除任何不想要的、以前排除的文件。还可以用安全的扩展名(例如“.exclude”)对它们进行重命名,以便有效地从 Web 应用程序中删除它们。重命名这些文件后,它们仍然是 Web 项目的一部分,但不能进行编译。
Visual Studio 2005 的最终版本将包含一个使您可以使用重命名机制排除和包含文件的上下文菜单项。最终版本还将做出一些更改,这些更改将阻止发布站点和命令行生成引擎 (MSBuild) 发布已排除的文件。ASP.NET 还将被配置为不使用 .exclude 扩展名提供文件。
部分转换的解决方案
在 ASP.NET 1.x 和 2.0 中,都有可能具有包含 Web 项目和客户端项目(例如 C# 类库或 Visual Basic 类库,或 Windows 应用程序)的解决方案。
如果您正在使用某个 Express 产品,例如 Visual Web Developer (VWD) 或 Visual Basic Express Edition,则只能在与该 Express 产品相关的解决方案中转换项目。例如,如果您正在使用 VWD 并打开一个含有 Web 项目和 Visual Basic 类库项目的解决方案,则只有 Web 项目会被转换,从而给您留下了一个部分转换的解决方案。
如何修复
您应使用 Visual Studio 2005 的 Standard、Professional 或 Team System 版本来转换包含多种混合项目类型的解决方案。
如果做不到这一点(您只有 Express Edition),则应创建一个仅包含该项目类型的新解决方案。
更新服务器
在将已转换的 ASP.NET 2.0 Web 应用程序部署到生产服务器之前,需要将 .NET Framework 2.0 部署到目标服务器。在本文的这一部分,我们将着眼于安装 .NET Framework 2.0 的步骤,以及一旦部署了该框架,如何将应用程序配置为使用该框架。
部署 .NET Framework 2.0
使用 ASP.NET 2.0 的第一步是部署已更新的 .NET Framework。由于 .NET Framework 的设计方式,您无需破坏当前安装的 1.0 或 1.1 框架就可以部署 2.0 框架。
获取框架
目前,您可以直接从 Microsoft 获取 NET Framework 2.0 安装程序。如果您是订阅了 MSDN,还可以从最近的 MSDN DVD 上找到各个版本。安装程序的大小为 22.4 MB。
请注意,该框架安装程序仅用于安装该框架,而不包含 Visual Studio 2005。您将使用此包在服务器上安装新的框架。如果需要在开发人员的计算机上安装新框架,则应注意安装 Visual Studio 2005,其中也包含 .NET Framework 2.0。
Go-Live 许可证
如果您计划在生产站点上使用 ASP.NET 2.0,则需要获取 Microsoft Visual Studio 2005 Beta 2 Go-Live 许可证。此许可证对使用规定进行了补充,使您可以将使用 Visual Studio 2005 生成的应用程序部署到生产中。请转到 Visual Studio 2005 Beta 2 Go-Live License 页面,以阅读许可证条款、查看所包含产品的列表、阅读了解许可证限制,以及使用 Microsoft Passport 帐户签署 Go-Live 许可证。
安装框架
下载了框架之后,您需要将其安装到目标服务器上。请记住,.NET Framework 2.0 与 1.1 框架完全兼容。此外,安装新框架不会破坏任何现有的应用程序,因为它们将继续在 ASP.NET 1.1 框架上运行,直到您专门将它们配置为在 ASP.NET 2.0 上运行为止。
使用 IIS MMC 管理单元配置 ASP.NET 2.0
一旦您在服务器上安装了该框架并使用 IIS 设置了基本扩展之后,下一组选择将涉及为每个 ASP.NET 应用程序指定特定的 .NET Framework 版本。默认情况下,1.x 应用程序将继续使用 1.x 框架。但是您必须将转换过的应用程序配置为使用 2.0 框架。
ASP.NET 2.0 将为 IIS 部署一个特殊的 Microsoft 管理控制台 (MMC) 管理单元,使您可以确定哪些应用程序应使用哪些版本的 .NET Framework。
![](http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/upgradingaspnet06S.gif)
图 6:ASP.NET 应用程序的 MMC 显示
MMC ASP.NET 选项卡使您可以选择您的应用程序使用哪个版本的 ASP.NET 并显示 Web.config 的位置。
除了管理框架版本之外,该控制台还具有一个“编辑配置”按钮,使您不必直接操作 Web.config XML 文件就可以直观地编辑大部分 Web.config 或 machine.config 设置。如果您是管理员,将会发现此 MMC 管理单元提供了一个用于在单个服务器上配置和管理多个 ASP.NET 应用程序的非常有用的工具。
总结
将应用程序从 ASP.NET 1.x 转换到 ASP.NET 2.0 通常是一个顺利的过程。但是您必须确保正确地配置了开发和部署环境。您还必须评估转换报告,以确保转换后的应用程序能够正常运行。还可能需要提前检查应用程序,并事先进行计划以避免已知的转换问题。
即将发布的 .NET Framework 2.0 最终版本
RTM 版本的转换向导所遵循的基本过程与本文所介绍的过程相同。但某些特定细节可能会有所不同。例如,通过自动实施必要的更改,RTM 向导可能能够更好地避免当前已知的某些问题。