分享

ASP 到 ASP.NET 的移植

 趋明 2012-02-20
foci 的Blog - 悠云蓝天
 
作者:foci
发表时间:
2006-10-24 19:28:55
更新时间:
2007-08-02 00:07:36
浏览:797次
主题:电脑技术
评论:0篇
地址:220.194.27.*


:::栏目:::
移植概述

安装 ASP.NET 不会破坏现有的 ASP 应用程序。它使用单独的文件扩展名(.aspx 而不是 .asp)、单独的配置设置以及完全独立的公共语言运行库(Asp.dll 没有修改)。ASP 页和应用程序可以继续使用现有的 ASP 引擎,不会受 ASP.NET 的干扰。这表明,将现有应用程序移植到 ASP.NET 的好处是巨大的。ASP.NET 轻松提供比传统 ASP 多许多倍的功能,而且将 ASP 应用程序移动到新的平台也提供了极大的改进机会。可以利用的新功能包括:

提高的性能和可缩放性
网络场支持和 XCopy 部署
输出缓存和自定义安全
Web 窗体页控件
XML Web 服务基础结构
ASP.NET 旨在帮助您保留在传统 ASP 和 COM 技术上的投资。您希望支持现有的 ASP 语法和语义,同时需要可以很好地持续到下一代 Internet 应用程序开发的前瞻性平台,而 ASP.NET 正是在这两者间实现平衡。尽管 ASP.NET 保留 ASP 功能集的多数内容,但如果平台要发展,就不可能实现二者间的完全兼容,因此对以往的工作方式有一些改动。

好的方面是您的 ASP 技能可以很容易转换为 ASP.NET。仅存在少数差异,通常很容易解决。但是,将 ASP 应用程序移植到 ASP.NET 确实需要做一些工作。相对简单的页可能不需更改即可移植,但较为复杂的应用程序可能需要一些修改。以下各节描述这些更改,以及它们可能影响现有应用程序代码的方式。还说明了一些可以在 ASP.NET 中重用 ASP 和 COM 代码的方法。

语法和语义
ASP.NET 与传统的 ASP 在 API 方面完全兼容,但有以下三处不同:

Request():ASP 返回字符串数组;ASP.NET 返回字符串。
Request.QueryString():ASP 返回字符串数组;ASP.NET 返回字符串。
Request.Form():ASP 返回字符串数组;ASP.NET 返回字符串。
在 ASP 中,Request、Request.QueryString 和 Request.Form 集合从查找返回字符串数组。例如,在传统的 ASP 中,按如下所示访问从请求到 http://localhost/test/Test.asp?values=45&values=600 的查询字符串值:

<%
' Below line outputs: "45, 600"
Response.Write Request.QueryString("values")

' Below line outputs: "45"
Response.Write Request.QueryString("values")(1)
%>

在 ASP.NET 中,这些集合需要显式方法来获取数组访问。这些数组现在也是从 0 开始索引。例如,在 ASP.NET 中,按如下所示访问从请求到 http://localhost/test/Test.aspx?values=45&values=600 的查询字符串值:

<%
// Below line outputs: "45, 600"
Response.Write(Request.QueryString["values"]);

// Below line outputs: "45"
Response.Write(Request.QueryString.GetValues("values")[0]);
%>

<%
' Below line outputs: "45, 600"
Response.Write(Request.QueryString("values"))

' Below line outputs: "45"
Response.Write(Request.QueryString.GetValues("values")(0))
%>

<%
// Below line outputs: "45, 600"
Response.Write(Request.QueryString["values"]);

// Below line outputs: "45"
Response.Write(Request.QueryString.GetValues("values")[0]);
%>


C# VB JScript

这些数组最常用于从多项选择列表框 (<select multiple>) 传递窗体值或多个复选框具有相同名称的情况。

ASP.NET 和 ASP 之间的语义差异
ASP.NET 页与现有的 ASP 页相比还有几处语义变化。下列问题最有可能影响您:

ASP.NET 页仅支持单语言。
ASP 允许在单页上使用多种语言,这对脚本库方案有用。由于 ASP.NET 的已编译特性,它在一页上仅支持单语言。然而,在单个应用程序内仍然可以有多个使用不同语言的页。用户控件还可以具有不同于包含它们的页所使用的语言。这使您能够在单页内集成用不同语言编写的功能。这足以替代传统 ASP 应用程序中普遍使用的多语言包含文件。

ASP.NET 页函数必须在 <script runat=server> 块中声明。
在 ASP 中,页函数可以在 <% %> 块中声明:

<%
Sub DoSomething()
Response.Write "Hello World!"
End Sub

DoSomething
%>

在 ASP.NET 中,页函数必须在 <script runat=server> 块中声明:

<script language="C#" runat=server>

void DoSomething() {
Response.Write("Hello World!");
}

</script>

<%
DoSomething();
%>

<script language="VB" runat=server>

Sub DoSomething()
Response.Write ("Hello World!")
End Sub

</script>

<%
DoSomething()
%>

<script language="JScript" runat=server>

function DoSomething() : void {
Response.Write("Hello World!");
}

</script>

<%
DoSomething();
%>


C# VB JScript


ASP.NET 不支持页呈现函数。
在 ASP 中,可以用 <% %> 块声明页呈现函数:

<% Sub RenderSomething() %>
<font color="red"> Here is the time: <%=Now %> </font>
<% End Sub %>

<%
RenderSomething
RenderSomething
%>

在 ASP.NET 中,这必须重写:

<script language="C#" runat=server>

void RenderSomething() {
Response.Write("<font color=red> ");
Response.Write("Here is the time: " + DateTime.Now);
}

</script>

<%
RenderSomething();
RenderSomething();
%>

<script language="VB" runat=server>

Sub RenderSomething()
Response.Write("<font color=red> ")
Response.Write("Here is the time: " & Now)
End Sub

</script>

<%
RenderSomething()
RenderSomething()
%>

<script language="JScript" runat=server>

function RenderSomething() : void {
Response.Write("<font color=red> ");
Response.Write("Here is the time: " + DateTime.Now);
}

</script>

<%
RenderSomething();
RenderSomething();
%>


C# VB JScript


本节小结
除了三处例外,ASP.NET 与传统的 ASP 在 API 方面完全兼容。API 的变化是:Request()、Request.QueryString() 和 Request.Form() 现在都返回个别的字符串而不是字符串数组。
ASP.NET 页仅支持单语言。
ASP.NET 页函数必须在 <script runat=server> 块中声明。
不支持页呈现函数。

语言兼容性
ASP 中使用的 VBScript 与 ASP.NET 中使用的 Visual Basic .NET 语言之间的差别是到目前为止所有潜在移植问题中最广泛的。在此发布版中,不仅 ASP.NET 从 VBScript 语言分离出来成为“真正的”Visual Basic,而且 Visual Basic 语言本身也经历了重大改变。这些改变旨在:

通过将具有相似用途的语言功能集中在一起,使语言更具一致性。
通过重新设计使 Visual Basic 不够“基本”的功能来简化语言。
通过重新设计向程序员隐藏了太多重要细节的功能,提高可读性和可维护性。
通过执行更好的做法(如类型安全编程)来提高可靠性。
本节重点介绍开始使用新的 Visual Basic 语言时可能遇到的一些常见问题。

不再使用 Set 和 Let,而是使用简单的变量赋值。
<%
' Old ASP syntax.
Dim MyConn
Set MyConn = Server.CreateObject("ADODB.Connection")

' New ASP.NET syntax.
Dim MyConn
MyConn = Server.CreateObject("ADODB.Connection")
%>

不再使用非索引默认属性。非索引默认属性使通常引用对象的表达式能够转而引用对象的默认属性。支持默认属性的令人遗憾的结果是使程序更难读,因为表达式的含义取决于其上下文。在 Visual Basic .NET 中,非索引属性必须始终在代码中显式指定。
<%
' Old ASP syntax (retrieving recordset column value).
Set MyConn = Server.CreateObject("ADODB.Connection")
MyConn.Open("TestDB")
Set RS = MyConn.Execute("Select * from Products")
Response.Write RS("Name")

' New ASP.NET syntax (retrieving recordset column value).
MyConn = Server.CreateObject("ADODB.Connection")
MyConn.Open("TestDB")
RS = MyConn.Execute("Select * from Products")
Response.Write RS("Name").Value
%>

仍然支持索引默认属性:

<%
Dim RS As RecordSet

' This is allowed (indexed).
RS.Fields(1).Value = RS.Fields(2).Value

' But these are not allowed (non-indexed).
RS(1) = RS(2)
RS(1).Value = RS(2).Value
%>

调用子例程现在需要使用括号。Visual Basic 现在支持与调用子例程和函数完全相同的语法。
' Note parentheses with Response.Write.
Sub DoSomething()
Response.Write("Hello World!")
End Sub

' Note parenthesws with DoSomething.
DoSomething()

新默认值是按值参数。 在 Visual Basic 6 中,如果用户没有在参数声明中显式指定 ByVal 或 ByRef,调用约定默认为 ByRef。在新的 Visual Basic .NET 中,默认值为 ByVal。这对常规参数(其默认值通过显式指定 ByRef 可重写)和传递给 ParamArray 参数的参数(其默认值不能重写)都适用。但这已经改变,因为比这常见得多的做法是将参数仅用于将值传入过程,而不是改变传入的变量。将默认值更改为 ByVal 可提高性能并减少意外副作用的可能性。
仍然可以通过显式使用 ByRef 修饰符来使用按引用参数:

<script language="VB" runat=server>

Sub DoSomething(ByRef value)
value = 4343
End Sub

</script>

<%
Dim number = 55
DoSomething (number)
Response.Write ("Number: " & number)
%>

注意: Visual Basic 6 和 Visual Basic .NET 之间还存在其他许多差异。请参考语言文档以获取更多信息。
本节小结
ASP 中使用的 VBScript 与 ASP.NET 中使用的 Visual Basic .NET 语言之间的差别是到目前为止所有潜在移植问题中最广泛的。做了更改以简化语言并提高一致性、可读性、可维护性和可靠性。
Visual Basic .NET 中不再支持 Set 和 Let 赋值。改为使用标准的变量赋值。
Visual Basic .NET 中不支持非索引默认属性。但仍然支持索引默认属性。
在 Visual Basic .NET 中调用子例程时需要使用括号。
新默认值是按值参数。仍然可以通过显式使用 ByRef 修饰符来使用按引用参数。

COM 互操作性
公共语言运行库使 .NET 对象能够无缝地与传统的 COM 组件相互操作。ASP.NET 向开发人员公开熟悉的 Server.CreateObject(ProgId) API 以创建 COM 的晚期绑定引用。
Dim myConn
myConn = Server.CreateObject("ADODB.Connection");

也可通过创建运行时可调用的包装 (RCW)(该包装优化非托管代码和托管代码间的调用性能),使用早期绑定的传统 COM 组件。可使用 .NET 框架 SDK 中包含的 Tlbimp.exe 实用工具创建 RCW。有关 Tlbimp.exe 的更多信息,请参阅“常见任务入门”互操作性一节。ASP.NET 性能一节包含有关比较晚期绑定与早期绑定的更多信息。
同 ASP 一样,也可以使用具有 progid 或 classid 属性的 <object> 标记来创建传统的 COM 组件。除了可以在页中使用 <object> 标记外,还可以在应用程序的 Global.asax 文件中使用该标记。在这种情况下,将对象添加到 Page.Application.StaticObjects 集合,并且只需使用它的 id 属性便可以编程方式访问它。注意,不能以静态方式在 Global.asax 文件中创建单线程单元 (STA) 对象,因为这样做会像在 ASP 中那样发生运行时错误。

此外,ASP.NET 继续支持现有的 ASP 内部接口 ObjectContext Intrinsic Flow、OnStartPage 和 OnEndPage。支持这些接口意味着可以在 ASP.NET 页中使用现有组件(Commerce Server、Exchange 等等)。默认情况下不启用这些接口,但可通过下列页指令显式打开它们:

<%@ Page ASPCompat="true" %>

该指令使 ASP.NET 创建非托管的 ASP 内部对象并将它们传递到页中使用的 COM 组件。它还在 STA 线程池中运行页。有关信息,请参阅下节。

性能注意事项
在 ASP.NET 中,默认情况下线程池是多线程单元 (MTA) 模式,这会影响传统的单元线程 Visual Basic 5 和 Visual Basic 6 组件的性能。ASPCompat="true" 属性使 STA 线程池能够基于每页解决现有 Visual Basic 组件的性能问题。
在托管和非托管组件之间调用同样会引起封送开销,这将降低页的性能。每种方案都会产生不同的性能特点,因此在决定互操作性对应用程序是否合适时进行充分地测试是重要的。然而,几乎在所有方案中,重写托管代码中的 COM 组件都会带来性能收益。有关更多信息和重要提示,请参阅 ASP.NET 性能一节。

本节小结
ASP.NET 向开发人员公开熟悉的 Server.CreateObject API 以创建 COM 的晚期绑定引用。
也可通过创建运行时可调用的包装 (RCW)(该包装优化非托管代码和托管代码间的调用性能),使用早期绑定的传统 COM 组件。
ASP.NET 继续支持现有的 ASP 内部接口 ObjectContext Intrinsic Flow、OnStartPage 和 OnEndPage。这些接口通过页指令 <%@ Page ASPCompat="true" %> 显式启用。
ASPCompat="true" 属性使 STA 线程池能够基于每页解决现有 Visual Basic 组件的性能问题。
几乎在所有方案中,重写托管代码中的 COM 组件都会提供性能收益。

MTS 事务
事务是以逻辑单元的形式成功或失败的一个或一组操作。一个典型的事务例子是将资金从一个银行帐户转移到另一个帐户。此例中,必须将资金从第一个帐户借记出来,并贷记到第二个帐户,这样方可认为操作成功。如果资金被成功地借记但没有被贷记,则必须撤销第一个帐户上的借记,以使两个帐户都正确并一致。
一般通过声明一组操作的边界来管理事务。在事务边界的上下文中执行的操作于是以单元的形式成功或失败。对于 ASP.NET,事务边界是执行对页的单个请求,而该页可能包含参与同一事务的嵌套组件。在页执行期间,如果页本身上的操作或同一事务中的嵌套组件失败,它可以调用 ContextUtil.SetAbort。它随后由当前的事务上下文获取,整个事务失败,并撤消任何已完成的操作。如果未发生失败,则提交事务。

ASP.NET 事务支持由允许页参与正在进行的 Microsoft .NET 框架事务的能力组成。事务支持通过指示所需支持级别的 @Transaction 指令公开:

<%@ Transaction="Required" %>

下表定义了受支持的事务属性。 缺少事务指令与“Disabled”的显式指令相同。与 ASP 不同,ASP.NET 没有对应于 none 的显式指令(即 Transaction="None")。

属性 说明
Required 页要求事务。如果存在现有事务,它在此事务的上下文中运行。否则将启动一个事务。
RequiresNew 页要求事务,并为每个请求启动一个新的事务。
Supported 如果存在现有事务,页在此事务的上下文中运行。否则将在无事务的情况下运行。
NotSupported 页不在事务范围内运行。处理请求时,无论是否存在活动事务,其对象上下文都在无事务的情况下创建。

可使用 System.EnterpriseServices.ContextUtil 类的静态方法显式提交或中止事务。可显式调用 SetComplete 或 SetAbort 方法提交或中止进行中的事务。

注意:假设没有其他对象与同一事务联接,则事务将在页的生存期结束时提交或中止,具体取决于最后调用的是 SetComplete 还是 SetAbort。

// Try to do something crucial to transaction completing.
if (!DoSomeWork()) {
ContextUtil.SetAbort();
}

' Try to do something crucial to transaction completing.
If (Not DoSomeWork())
ContextUtil.SetAbort()
End If

// Try to do something crucial to transaction completing.
if (!DoSomeWork()) {
ContextUtil.SetAbort();
}


C# VB JScript

本节小结
事务是以逻辑单元的形式成功或失败的一个或一组操作。
ASP.NET 事务支持由允许页参与正在进行的 Microsoft .NET 框架事务的能力组成。事务支持通过指示所需支持级别的 @Transaction 指令公开。
可使用 System.EnterpriseServices.ContextUtil 类的静态方法显式提交或中止事务。开发人员可显式调用 SetComplete 或 SetAbort 方法来提交或中止进行中的事务。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多