BizTalk Utilities CV ,   Jobs ,   Code library  
 
 
Page 5 of 9

 

Previous Page Table Of Contents Next Page

XIR: Use XML To Call COM Components over the Internet, cont.

The Client Side

The XIR client is implemented as an ActiveX control to be included on a web page with the <OBJECT> tag. When designing this control, I wanted the ability to queue up several server calls and send them as part of one HTTP request. This meant there had to be three methods on the control: One to queue up a server call, another to send all queued up calls and a third to retrieve results.

Figure 3 XIR Client Interface Design

As you can see from figure 3, the control's interface is straightforward. CallService accepts a unique service name and all input parameters(i.e. ByVal parameters) and returns a call sequence number used later to retrieve call results. Send tells the control to send an HTTP POST request containing all queued service calls and retrieve the response. Finally, GetOutput accepts the call sequence number and returns whatever the service call returned, if anything.

Due to the simplicity of its interface, the client control is easy to use. For example, assume you had a server-side component with the following method: GetOrderInfo(lOrderId As Long) As Recordset. The code to call this using the XIR control would be as in figure 4.

Figure 4 Sample script code showing how to use the XIR client

<OBJECT ID=objXIRControl …></OBJECT>

<SCRIPT Language=VBScript>

Sub GetOrderInformation()

Dim callid

Dim orderid

Dim rsOrderInfo

orderid=7

callid=objXIRControl.CallService("GetOrder",orderid)

objXIRControl.Send

Set rsOrderInfo=objXIRControl.GetOutput(callid)

.

.

End Sub

</SCRIPT>

That's all there is to it. The client's CallService method shown in figure 5 is responsible for converting input parameters to XML and creating a new servicecall node in the Request XML document.         First, it creates a new Request document if needed. Then it creates a new servicecall node using createElement and sets the node's attributes. It then creates a param node for each input parameter and converts the parameter's value to XML using Vnt2XML. This handy function accepts a variant and returns an XML representation of the variant's contents. Although very useful, the code for this function is fairly straightforward. How you convert a variant to XML depends of course on the variant type. For all simple data types (e.g. string, long, date etc.), it is a simple conversion to string. As I mentioned earlier, objects can be converted to XML provided they implement IXIRPersistXML. ADO Recordsets are different because you must use the ADO Stream object to save the recordset as XML then read that XML out of the stream as shown in figure 6. This requires ADO 2.5, which, at the time of this writing, is still in beta. I am using late binding whenever I reference a Recordset, that way if you do not need to pass ADO Recordsets around, you can use XIR without ADO 2.5.

Figure 5 Implementation of CallService

Public Function CallService(ByVal sServiceId As String, ParamArray vntParams()) As Long

            Dim oCall As IXMLDOMElement

            Dim oParam As IXMLDOMElement

            Dim i As Integer

            On Error GoTo eh

            If moRequestDoc Is Nothing Then

                        Set moRequestDoc = New DOMDocument

                        moRequestDoc.loadXML "<XIRRequest></XIRRequest>"

            End If

            '1. create and append new element for the service call

            Set oCall = moRequestDoc.createElement("servicecall")

            'set attributes

            oCall.setAttribute "serviceid", sServiceId

            oCall.setAttribute "callid", CStr(mlNextCallID)

            'increment next call id

            CallService = mlNextCallID

            mlNextCallID = mlNextCallID + 1

            'append node to request document

            moRequestDoc.documentElement.appendChild oCall

            '2. For each parameter passed in, create a new parameter node and

            'convert parameter value to XML

            For i = LBound(vntParams) To UBound(vntParams)

                        'Add child node for parameter

                        Set oParam = moRequestDoc.createElement("param")

                        'convert to xml

                        If Not IsEmpty(vntParams(i)) Then

                                    oParam.Text = Vnt2XML(vntParams(i))

                        End If

                        'add the cloned node to the command in the request doc

                        oCall.appendChild oParam

            Next

            Exit Function

eh:

            CallService = 0

            MsgBox "An error occurred in CallService: " & _

                                    vbCrLf & Err.Description, vbExclamation + vbOKOnly, _

                                    "Error in CallService"   

End Function

 

Figure 6 Converting an ADO 2.5 Recordset to an XML string

'convert recordset to XML for passing out

 'create stream

 Dim oStream As Object

 Set oStream = CreateObject("ADODB.Stream")

 'set type to text

 oStream.Type = 2

 'Save RS to stream

 vntParamVal.save oStream, 1

 'append the new XML to the Param XML

 'start from the first child node

 Set oTempDoc = New DOMDocument

 oTempDoc.loadXML oStream.ReadText

 Vnt2XML = oTempDoc.childNodes(0).xml

It is important to note that I am deliberately building the request document using nodes and attributes instead of just building one long XML string with simple string concatenation. This allows me to explicitly set each parameter value as the parameter text without caring whether this text actually contains XML. If I had used string concatenation to build the request document, I would have had to encode each parameter value using entity references such as &lt; and &gt;. CallService ensures that for each method call the client makes, the XML request document contains the called service's unique id and parameter values passed in by the client.

Before moving on to the server side, take a look at Send() in figure 7. This method uses a couple of interesting techniques to send the request document using HTTP along with any cookies. First it uses the XMLHTTP component I discussed earlier to send the HTTP POST request. It also uses UserControl.Parent to gain access to the hosting HTML document. This is a powerful, yet not very well known technique to manipulate an HTML page from within your ActiveX control. The returned IHTMLDocument2 interface has a Cookie property that returns a list of all cookies specific to the current page. These cookies are then all sent to the server in the HTTP request headers. Finally, the function posts the request and saves the returned XML response in moResponseDoc for use by GetResults.

Figure 7 Using XMLHTTP component to send XML over HTTP

Public Sub Send()

            On Error GoTo eh

            Dim oXMLHTTP As MSXML.XMLHTTPRequest

            Dim objDoc As IHTMLDocument2

            Set oXMLHTTP = New MSXML.XMLHTTPRequest

            oXMLHTTP.open "POST", mServerURL, False

            'send any document cookies

            Set objDoc = UserControl.Parent

            If Len(objDoc.cookie) > 0 Then

                        oXMLHTTP.setRequestHeader "Cookie", objDoc.cookie

            End If

            'send request

            oXMLHTTP.Send moRequestDoc

            Set moRequestDoc = Nothing 'reinit

            If oXMLHTTP.responseXML.xml = "" Then

                        MsgBox "No valid reponse returned. " & _

                                                vbCrLf & "Response text is: " & _

                                    oXMLHTTP.responseText, vbCritical, "XIR Client"

            Else

                        'retrieve response

                        Set moResponseDoc = oXMLHTTP.responseXML

            End If

            Exit Sub

eh:

            MsgBox "Error sending request: " & vbCrLf & Err.Description

End Sub

 

Page 5 of 9

 

Previous Page Table Of Contents Next Page
 

Recent Jobs

An immediate job opportunity as a B
Software Developers Needed in Charl
Sr. Software Engineer - Analytics
Immediate Mainframe openings for Ch
Immediate TANDEM-TAL openings for C

View all Jobs (Add yours)
View all CV (Add yours)



answering service
online fax
swimming pool contractor
conference calling services
water softener
Teleconference
Host Department NOLIMIT Web Hosting
MSN
sunglasses


    Email TopXML  

Front Page Daily Stuff TopXML Forum XML blogs XML Newsgroups BizTalk Biztalk Utilities Biztalk Utilities Tutorial B2B SAP XML Microsoft .NET Dotnet System XML Soapformatter SQLXML XMLserializer XQuery PHP PHP SimpleXML PHP XML Dom PHP XML RPC PHP XSLT Java Java Java XML Xalan Microsoft ASP ASP Schemas XML SQL Server XML XMLDom XSL XSL Tutorial XSLT Stylesheets General Javascript CSS XHTML WAP