Export (0) Print
Expand All
Expand Minimize

Exposing Existing Code as a Web Service Using the .NET Framework

 

Steve Kirk and Priya Dhawan
Microsoft Developer Network

Revised February 2001

Summary: This article covers data transformations made to expose existing Microsoft Visual Basic 6.0 code as a Web Service using ASP .NET. (8 printed pages).

Download bdadotnet_beta2.msi.

Contents

Introduction
Data Types Exposed by Existing Code
   ADO 2x Command Object
   ADO 2x Recordset Object
   Stream Object
   XMLDOM Object
   XML String
Conclusion

Introduction

The Microsoft® .NET Framework simplifies the task of exposing .NET code as a Web Service. One reason for this simplicity is that the .NET Framework includes provisions for transforming complex .NET data types into XML (serialization) and reversing the process (de-serialization).

Existing code written as pre-.NET classes passing data in language-specific data types or COM objects is not able to rely on the same standard provisions for serializing these data types as XML. This article covers data transformations required to expose existing Microsoft Visual Basic® 6.0 code as an ASP .NET Web Service.

The data transformation issues covered in this article are not the only issues to consider when evaluating the suitability of existing code for exposure as a Web Service. Other considerations include object and state models, return data sizes, how success is indicated, how error information is returned, the security model (including access control, authentication, and encryption), the execution model (synchronous or asynchronous), how the code is to be distributed, and the transaction model (COM+ transactions or declarative transactions). These issues will be covered in upcoming Architectural Topics articles.

Data Types Exposed by Existing Code

It would be quite a project to cover transformation of all of the data types passed by existing code, so some of the most widely used are covered here, along with XML (as a string), which can cover just about any other data type providing that the existing code is extended with XML interfaces. Transformation techniques for the following data types are discussed:

  • ADO 2x Command object
  • ADO2x Recordset object
  • Stream object
  • XMLDOM object
  • XML

ADO 2x Command Object

The Microsoft ActiveX® Data Objects (ADO) Command object is often exposed by existing code that accesses a database directly. Although the Command object cannot be passed between tiers of an application operating in separate processes, it can be passed within a process. Returning data through Command object output parameters is more efficient than returning data through an ADO recordset for single-row data entities. This makes the ADO Command object useful for returning single row entity data.

Read data

Existing code in the following example returns an ADO Command object containing data as output parameters. The Parameters collection of the Command object is transformed to XML and returned to the Web Service consumer:

' Existing code returns ADO Command object
Cmd = EC.Example1()
' Transform Parameters collection of Command object using XmlTextWriter 
      and StringWriter
' Instantiate stringwriter and xmlwriter for returning xml string
strWriter = New StringWriter()
xmlWriter = New XmlTextWriter(strWriter)
' Iterate through Parameters collection writing name and value
For i = 0 To Cmd.Parameters.Count - 1             
   xmlwriter.WriteElementString(Cmd.Parameters(i).Name.Substring(1),_
   Cmd.Parameters(i).Value.ToString)
Next
' Return xml as a string
Example1 = strWriter.GetStringBuilder.ToString()

Note   See Example 1 in the BDAdotNetWebServices1.vb sample code (see top of article for download).

Write data

Passing data as Command object parameters is an efficient way to pass data. It is also extensible and offers some type checking.

' Read the XML data submitted to the Web service into the xmlreader
strReader = New StringReader(commandXML)
xmlreader = New XmlTextReader(strReader)

' Move to the Root node 
xmlreader.MoveToContent()
' Move to the first Element
xmlreader.MoveToElement()

' Read the CommandType Element
Cmd.CommandType = xmlreader.ReadElementString()
' Read the CommandText Element 
Cmd.CommandText = xmlreader.ReadElementString()

' Move to Parameters Element
xmlreader.MoveToElement()
' Read the first Parameter Element
xmlreader.Read()
Dim i As Integer
' Build the Parameters Collection of the Command object
While xmlreader.Name = "Parameter"
   Param = New ADODB.Parameter()
   With Param
      xmlreader.MoveToAttribute("Name")
      .Name = "@" + xmlreader.Value
      xmlreader.MoveToAttribute("Type")
      .Type = xmlreader.Value
      xmlreader.MoveToAttribute("Size")
      .Size = xmlreader.Value
      xmlreader.MoveToAttribute("Direction")
      .Direction = xmlreader.Value
      If .Direction = ADODB.ParameterDirectionEnum.adParamInput Then
         xmlreader.MoveToAttribute("Value")
         .Value = xmlreader.Value
      End If
   End With
   Cmd.Parameters.Append(Param)
   xmlreader.Read()
End While

' Call the Existing code and pass the Command object
EC.Example2(Cmd)

Note   See Example 2 in the BDAdotNetWebServices1.vb sample code (see top of article for download).

ADO2x Recordset Object

ADO 2x disconnected recordsets are commonly used to pass data between tiers of a multitier application. Data can be single row, sets of rows, or hierarchical rows.

Read data

In this example, existing code returns an ADO Recordset object containing hierarchical row data that is transformed to XML before being returned by the Web Service:

' Existing code returns Recordest
RS = EC.Example3()
' Instantiate a stream to receive Recordset data
Stream = New ADODB.Stream()
' Write XML representation of recordset to stream
RS.Save(Stream, ADODB.PersistFormatEnum.adPersistXML)
' Return XML as string from stream
Example3 = Stream.ReadText

Note   See Example 3 in the BDAdotNetWebServices1.vb sample code (see top of article for download).

Write data

In the following example, XML representing hierarchical row data is used to populate an ADO Recordset object, which is passed to existing code:

' Instantiate a recordset object 
RS = New ADODB.Recordset()
' Instantiate a stream object
Stream = New ADODB.Stream()
' Open the stream object
Stream.Open()
' Write XML to the stream
Stream.WriteText(RsXML)
' Position the pointer to the begining of the stream 
Stream.Position = 0
' Open the recordset from the stream XML data
RS.Open(Stream)    
' Pass recordset to existing code
EC.Example4(RS)

Note   See Example 4 in the BDAdotNetWebServices1.vb sample code (see top of article for download).

Stream Object

A stream can provide an efficient way to pass data between native tiers of an application. It is the primary means for reading XML from Microsoft SQL Server™ 2000.

Read data

In the following example, existing code returns a stream of XML representing hierarchical row data, which is read as a string to be returned by the Web Service:

Dim Stream As ADODB.Stream
Stream = EC.Example5()
Example5 = Stream.ReadText

Note   See Example 5 in the BDAdotNetWebServices1.vb sample code (see top of article for download).

XMLDOM Object

An XMLDOM object is a good way to pass data between native tiers of a multi-tier application. It provides interface extensibility, type checking, and schema validation.

Read data

In the following example, existing code returns an XML Document Object Model (XMLDOM), which is transformed to a string of XML and returned by the Web Service:

Dim Doc As MSXML2.DOMDocument
' Existing code returnins XMLDOM object
Doc = EC.Example6()
' Return XML from DOM object
Example6 = Doc.xml

Note   See Example 6 in the BDAdotNetWebServices1.vb sample code (see top of article for download).

Write data

In the following example, XML representing hierarchical row data is used to populate an XMLDOM object and passed to existing code:

Dim Doc As MSXML2.DOMDocument
' Instantiate an XMLDOMDocument object 
Doc = New MSXML2.DOMDocument()
' Load XML into DOM
Doc.loadXML(orderXML)
' Pass DOM to existing code
EC.Example7(Doc)

Note   See Example 7 in the BDAdotNetWebServices1.vb sample code (see top of article for download).

XML String

XML is a simple way to pass data between tiers. It also pushes conversion of data into XML to the "existing code" side of the COM Interop boundary, which, depending on the interface, may be more efficient than translating data into XML across the COM Interop boundary.

Read data

In the following example, existing code returns a string containing XML data, which is then passed by the Web Service to the consumer:

EC = New ExCode.ExClass()
' Pass XML string directly from existing code to consumer
Example8 = EC.Example8()

Note   See Example 8 in the BDAdotNetWebServices1.vb sample code (see top of article for download).

Write data

In the following example, an XML representation of hierarchical row data is passed as a string to existing code:

EC = New ExCode.ExClass()
' Pass XML string directly from consumer to existing code
EC.Example9(orderXML)

Note   See Example 9 in the BDAdotNetWebServices1.vb sample code (see top of article for download).

Conclusion

This article and the accompanying examples cover data transformations that enable existing code to be exposed as a Web Service with ASP .NET. Some widely used interface objects are discussed here, including XML as a string, which can cover most data provided that existing code is extended with the appropriate interface.

The performance of these solutions varies and is also affected by the size of the data being passed. Look for comparisons of these implementations in an upcoming article in this series.

Interface is only one of many things to consider when evaluating the suitability of existing code as a Web Service. Other considerations are security (including authorization, authentication, and encryption), transaction model, state model, the way errors and results are returned, and whether the code executes synchronously or asynchronously.

Show:
© 2014 Microsoft