Export (0) Print
Expand All
Expand Minimize

Exposing Existing Code as a Web Service Using the SOAP Toolkit 2.0

 

Steve Kirk and Priya Dhawan
Microsoft Developer Network

Summary: This article covers data transformations made to expose existing Microsoft Visual Basic 6.0 code as a Web Service using the Microsoft SOAP Toolkit version 2.0. (7 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
Conclusion

Introduction

The Microsoft® SOAP Toolkit version 2.0 simplifies the task of exposing and consuming existing code as a Web Service, as documented in the SOAP Toolkit 2.0 documentation. Some of the primary functions performed on the server side are transformations made between data as passed in various data types by the existing code and the XML messages used between the Web Service client and server. Transformation of simple data types is handled automatically while more complex data types require the developer to supply transformation code.

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. An alternative to transformation by SOAP Toolkit code would be to extend existing code with XML interfaces. Transformation techniques for the following data types are covered:

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

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. Code in a Custom Type Mapper uses the SoapSerializer object to transform the Command object before it is passed to the web service consumer:

With SoapSerializer    
    ' Transform the CommandType
    .startElement "CommandType"
    .writeString Cmd.CommandType
    .endElement
    ' Transform CommandText
    .startElement "CommandText"
    cmdText = Cmd.CommandText
    cmdText = Left(Cmd.CommandText, Len(cmdText) - 8)
    cmdText = Right(cmdText, Len(cmdText) - 7)    
    .writeString cmdText
    .endElement
    ' Transform the Parameters collection
    .startElement "Parameters"
    For i = 0 To oCmd.Parameters.Count - 1
        .startElement Right(oCmd.Parameters(i).Name, _
            Len(oCmd.Parameters(i).Name) - 1)
            .startElement "Direction"
            .writeString oCmd.Parameters(i).Direction
            .endElement
            .startElement "Type"
            .writeString oCmd.Parameters(i).Type
            .endElement
            .startElement "Size"
            .writeString oCmd.Parameters(i).Size
            .endElement
            .startElement "Value"
            .writeString oCmd.Parameters(i).Value
            .endElement
        .endElement
    Next
    .endElement
End With

Note   See Example 1 in the BDAdotNetWebServices2.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.

In the following example, XML data submitted to a Web Service by the consumer is transformed to parameters on an ADO Command object that will be passed to existing code:

Dim Cmd As ADODB.Command
Dim Param As ADODB.Parameter
' pNode is MSXML2.IXMLDOMNode containing XML submitted by consumer
' Instantiate an ADO Command object
Set Cmd = New ADODB.Command
With Cmd
    ' Apply CommandType and CommandText
    .CommandType = _
        CInt(pNode.selectSingleNode("CommandType").nodeTypedValue)
    .CommandText = pNode.selectSingleNode("CommandText").nodeTypedValue
    ' Populate the Parameters collection
    Set nodeParent = pNode.selectSingleNode("Parameters")
    For i = 0 To nodeParent.childNodes.length - 1
        Set nodeParameter = nodeParent.childNodes(i)
        Set Param = New ADODB.Parameter
        With Param
            .Name = "@" + nodeParameter.nodeName
            .Direction = _
                nodeParameter.selectSingleNode("Direction").nodeTypedValue
            .Type = nodeParameter.selectSingleNode("Type").nodeTypedValue
            .Size = nodeParameter.selectSingleNode("Size").nodeTypedValue
            .Value = factory.getMapper(enXSDstring, _
                Nothing).Read(nodeParameter.selectSingleNode("Value"), _
                    bstrEncoding, encodingMode, lFlags)
        End With
    .Parameters.Append oParam
    Next
End With

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

ADO 2x Recordset Object

ADO 2x disconnected recordsets are commonly used to pass data between tiers of a multi-tier 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 to the consumer:

Dim RS As ADODB.Recordset
Dim DataStream As ADODB.Stream   
Set RS = pvar
Set DataStream = New ADODB.Stream
' Save the recordset object as XML into the stream
RS.Save DataStream, adPersistXML
' Read and pass the XML string from the Stream to the 
' SoapSerialized object
pSoapSerializer.writeXML DataStream.ReadText

Note   See Example 3 in the BDAdotNetWebServices2.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 to be passed to existing code:

Dim RS As ADODB.Recordset
Dim DataStream As ADODB.Stream
Set RS = New ADODB.Recordset
Set DataStream = New ADODB.Stream
' Read XML into the Stream
DataStream.Open
DataStream.WriteText pNode.xml
DataStream.Position = 0
' Open the Recordset object from the Stream
RS.Open DataStream
Set ISoapTypeMapper_read = RS
Set DataStream = Nothing

Note   See Example 4 in the BDAdotNetWebServices2.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 transformed before being returned to the consumer:

Dim inStream As ADODB.Stream
' pvar contains stream object returned by existing code    
Set inStream = pvar
' Pass XML data from stream to SOAP Serializer
SoapSerializer.writeString inStream.ReadText

Note   See Example 5 in the BDAdotNetWebServices2.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 XMLDOMDocument object, which is transformed for return to the consumer:

' pvar contains XMLDOMDocument
pSoapSerializer.writeXML pvar.xml

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

Write data

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

Dim Doc As MSXML2.DOMDocument
Set Doc = New MSXML2.DOMDocument
' Load XML into the DOM Document
Doc.loadXML pNode.selectSingleNode("NewDataSet").xml
Set ISoapTypeMapper_read = Doc

Note   See Example 7 in the BDAdotNetWebServices2.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 the SOAP Toolkit 2.0. Some widely used interface objects are covered here.

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