使用 .NET 框架将现有代码作为 Web 服务提供 使用 .NET 建立分布式应用程序
Steve Kirk 和 Priya Dhawan
Microsoft Developer Network
摘要:本文介绍了使用 ASP.NET 将现有 Microsoft Visual Basic 6.0 代码作为 Web 服务提供时所进行的数据转换。适用于 Microsoft .NET SDK 和 Microsoft Visual Studio.NET 的 Beta 1 版。
目录
简介
.NET 框架简化了将 .NET 代码作为 Web 服务提供的任务。.NET 框架开发人员指南中的 ASP.NET Web 服务和 ASP.NET Web 服务客户机(英文)对此进行了说明。之所以能够实现这种简化,其中一个原因是 .NET 框架提供了一系列规则,用于将复杂的 .NET 数据类型转换为 XML(序列化)以及反向转换(反序列化)。
编写为 .NET 之前的类的现有代码通过特定于语言的数据类型或 COM 对象来传递数据,因此不能依赖于相同的标准规则将这些数据类型序列化为 XML。本文介绍了将现有 Microsoft® Visual Basic 6.0 代码作为 ASP.NET Web 服务提供时所需的数据转换。
评估现有代码是否适合于作为 Web 服务提供时,本文讨论的数据转换问题并不是唯一需要考虑的问题。应考虑的其它因素包括对象和状态模型、返回的数据大小、如何表示已经成功、如何返回错误信息、安全模型(包括访问控制、身份验证和加密)、执行模型(同步或异步)、如何分发代码,以及事务模型(COM+ 事务或声明型事务),等等。这些问题将在即将发表的体系结构主题(英文)文章中进行讨论。
现有代码提供的数据类型
讨论现有代码传递的所有数据类型的转换将是一个相当大的工程,因此本文只介绍一些最常用的数据类型,以及 XML(作为字符串),因为如果使用 XML 对现有代码进行扩展,那么 XML 就可以涵盖几乎所有其它的数据类型。本文讨论以下数据类型的转换方法:
ADO 2x Command 对象
ADO2x Recordset 对象
Stream 对象
XMLDOM 对象
XML
ADO 2x Command 对象
直接访问数据库的现有代码经常会提供 Microsoft ActiveX® 数据对象 (ADO) 的 Command 对象。虽然不能在运行于不同进程中的应用程序层之间传递 Command 对象,但可以在同一进程内传递该对象。对于单行数据实体,通过 Command 对象的输出参数返回数据比通过 ADO 记录集返回数据效率更高。因此,ADO Command 对象对于返回单行实体数据十分有用。
读数据
以下示例中的现有代码返回一个 ADO Command 对象,它包含作为输出参数的数据。Command 对象的 Parameters 集合转换为 XML 并返回给 Web 服务的客户:
' 现有代码返回 ADO Command 对象
Cmd = CType(EC.Example1(), ADODB.Command)
' 使用 XmlTextWriter 和 StringWriter 转换 Command 对象的 Parameters 集合
' 初始化 stringwriter 和 xmlwriter 以返回 xml 字符串
strWriter = New StringWriter()
xmlWriter = New XmlTextWriter(strWriter)
' 在 Parameters 集合内循环,写入名称和值
For i = 0 To Cmd.Parameters.Count - 1
xmlwriter.WriteElementString(Cmd.Parameters(i).Name.Substring(1),_
Cmd.Parameters(i).Value.ToString)
Next
' 将 xml 作为字符串返回
Example1 = strWriter.GetStringBuilder.ToString()
写数据
将数据作为 Command 对象的参数传递是一种非常有效的数据传递方法。它还可以进行扩展,并提供了一些类型检查功能。不幸的是,由于 Beta 1 中存在缺陷,Command 对象产生的数据无法传递到现有代码。Beta 2 中解决了这个问题。Beta 1 的解决方法是对现有的 VB 6 代码进行扩展,接受 XML。
ADO2x Recordset 对象
ADO 2x 断开连接的记录集通常用于在多层应用程序的各层之间传递数据。数据可以是单行、多行或分层次的行。
读数据
本示例中,现有代码返回一个 ADO Recordset 对象,它包含的层次行数据将被转换为 XML,然后由 Web 服务返回:
' 现有代码返回记录集
RS = CType(EC.Example3(), ADODB.Recordset)
' 实例化一个接收记录集数据的流
Stream = New ADODB.Stream()
' 将记录集的 XML 表示写入流
RS.Save(Stream, ADODB.PersistFormatEnum.adPersistXML)
' 将 XML 作为字符串从流返回
Example3 = Stream.ReadText
写数据
以下示例中,使用表示层次行数据的 XML 填充 ADO Recordset 对象,该对象将被传递到现有代码:
' 实例化一个记录集对象
RS = New ADODB.Recordset()
' 实例化一个流对象
Stream = New ADODB.Stream()
' 打开流对象
Stream.Open()
' 将 XML 写入流
Stream.WriteText(RsXML)
' 将指针定位到流的开头
Stream.Position = 0
' 使用流中的 XML 数据打开记录集
RS.Open(Stream)
' 将记录集传递到现有代码
EC.Example4(RS)
Stream 对象
流提供了一种在应用程序的本地层之间传递数据的有效方法。它是从 Microsoft SQL Server™2000 中读取 XML 的主要方法。
读数据
以下示例中,现有代码返回表示层次行数据的 XML 流,它被作为字符串读取,并由 Web 服务返回:
Dim Stream As ADODB.Stream
Stream = CType(EC.Example5(), adodb.stream)
Example5 = Stream.ReadText
XMLDOM 对象
XMLDOM 对象是一种在多层应用程序的本地层之间传递数据的好方法。它提供了接口可扩展性、类型检查和架构验证功能。
读数据
以下示例中,现有代码返回一个 XML 文档对象模型 (XMLDOM),它被转换为 XML 字符串并由 Web 服务返回:
Dim Doc As MSXML2.DOMDocument
' 现有代码返回 XMLDOM 对象
Doc = CType(EC.Example6(), msxml2.DOMDocument)
' 从 DOM 对象返回 XML
Example6 = Doc.xml
写数据
以下示例中,使用表示层次行数据的 XML 填充 XMLDOM 对象,并将该对象传递到现有代码:
Dim Doc As MSXML2.DOMDocument
' 实例化一个 XMLDOMDocument 对象
Doc = New MSXML2.DOMDocument()
' 将 XML 载入 DOM
Doc.loadXML(orderXML)
' 将 DOM 传递到现有代码
EC.Example7(Doc)
XML 字符串
XML 是一种在层与层之间传递数据的简单方法。它还将数据的 XML 转换过程推到 COM 互操作边界的“现有代码”端,根据接口的不同,这可能会比在 COM 互操作边界将数据转换为 XML 更有效。
读数据
以下示例中,现有代码返回一个包含 XML 数据的字符串,然后,该字符串由 Web 服务传递给客户:
EC = New ExCode.ExClass()
' 将 XML 字符串直接从现有代码传递给客户
Example8 = EC.Example8()
写数据
以下示例中,层次行数据的 XML 表示作为字符串传递到现有代码:
EC = New ExCode.ExClass()
' 将 XML 字符串直接从客户传递到现有代码
EC.Example9(orderXML)
总结
本文及附带的示例介绍了有关数据转换的信息。通过数据转换,可以使用 ASP.NET 将现有代码作为 Web 服务提供。本文讨论了一些常用的接口对象,其中包括 XML 字符串,如果使用相应的接口对现有代码进行扩展,它可以涵盖大多数数据。
这些解决方案的性能各异,并且受所传递的数据大小影响。在本系列后面的文章中,我们将对这些实现方法进行比较。
评估现有代码是否适合作为 Web 服务时,接口只不过是应当考虑的诸多因素之一。应考虑的其它因素包括安全性(包括授权、身份验证和加密)、事务模型、状态模型、返回错误和结果的方式,以及代码是同步还是异步执行,等等。