Overview of SOAP Client in Windows XP

 

Roger Wolter
Microsoft Corporation

May 2001

Summary: This article covers the basics of using the SOAP Client software included with Microsoft Windows XP Professional to access Web Services using SOAP. It begins with a brief introduction to SOAP and WSDL standards and then discusses how to implement a client that can communicate with a SOAP-enabled Web service. (16 printed pages)

Contents

Introduction What Is SOAP? What Is WSDL? Building A Simple Client Application Next Steps The SOAPClient Object           Mssoapinit Method           ClientProperty Property           ConnectorProperty Property           Detail Property           HeaderHandler (SOAPClient)           Faultactor Property (SOAPClient)           Faultcode Property (SOAPClient)           Faultstring Property (SOAPClient)

Introduction

Microsoft® Windows® XP Professional includes the client portion of the Microsoft SOAP Toolkit 2.0, making it possible to build SOAP client applications or to distribute them to Windows XP Professional clients without distributing the client portions of the SOAP Toolkit 2.0. This paper covers the basics of using the SOAP client software included with Windows XP to access Web services using SOAP. It begins with a brief introduction to SOAP and Web Services Description Language (WSDL) standards, and then discusses how to implement a client that can communicate with a SOAP-enabled Web service.

What Is SOAP?

SOAP, which stands for Simple Object Access Protocol, is defined by the SOAP standard available at https://www.w3.org/TR/SOAP. The SOAP protocol defines the format of standard XML messages that are used to communicate among systems. Because the message format is standardized and based on the XML standard, SOAP can be used to communicate among multiple computer architectures, languages, and operating systems. SOAP enables a new class of applications called Web services, which expose services in a standard way so that application developers can create new applications by putting together services from many different sources on the Web.

There are four main areas covered by the SOAP specification: a required SOAP Envelope format that defines what the envelope that surrounds the XML content of a SOAP message must look like; an optional set of encoding rules that defines how language types are mapped to XML in a SOAP message (since this is defined in section 5 of the specification, it is referred to as "section 5 encoding"); an optional RPC format that defines how function calls are expressed in SOAP messages; and an HTTP binding that defines how SOAP messages may be exchanged through HTTP. HTTP is the only communications protocol binding defined by the standard; thus almost all SOAP implementations include an HTTP binding. Note that SOAP doesn't impose limitations on what other communications protocols can be used to transport SOAP messages.

Here's a simple SOAP message:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope 
SOAP-ENV:encodingStyle="https://schemas.xmlsoap.org/soap/encoding/" 
  xmlns:SOAP-ENV="https://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    <SOAPSDK1:Add xmlns:SOAPSDK1="https://tempuri.org/message/">
    <a>333</a>
    <b>888</b>
    </SOAPSDK1:Add>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Let's go through this in detail to understand the format of a SOAP message. The first line is the XML declaration that defines the character set used in the SOAP document. The Envelope element is a required element that is always the root of a SOAP message, and is always in the "https://schemas.xmlsoap.org/soap/envelope/" namespace.

The SOAP-ENV:encodingStyle="https://schemas.xmlsoap.org/soap/encoding/" attribute defines the encoding style used in the message. In this case, standard section 5 encoding is used. The Body sub element of the Envelope element contains the SOAP Message. As defined in section 7 of the SOAP specification, the Add element represents a call on an operation named Add. The sub elements of Add are the parameters of the Add method call.

The response to this message would look like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope 
SOAP-ENV:encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"
 xmlns:SOAP-ENV="https://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    <SOAPSDK1:AddResponse
    xmlns:SOAPSDK1="https://tempuri.org/message/">
    <Result>1221</Result>
    </SOAPSDK1:AddResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

What Is WSDL?

WSDL stands for Web Service Description Language. In order to successfully call a Web service you will need to know how to get to the service, what operations the service supports, what parameters the service expects, and what the service returns. WSDL provides all of this information in an XML document that can be read or machine-processed.

To understand the format of a WSDL file, let's examine the following WSDL file:

<?xml version="1.0" encoding="UTF-8" ?> 
<definitions name="net.xmethods.services.currencyexchange.CurrencyExchange"
targetNamespace="https://www.themindelectric.com/wsdl/
net.xmethods.services.currencyexchange.CurrencyExchange/" 
xmlns:tns="https://www.themindelectric.com/wsdl/
net.xmethods.services.currencyexchange.CurrencyExchange/"
xmlns:electric="https://www.themindelectric.com/" 
xmlns:soap="https://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:xsd="https://www.w3.org/2001/XMLSchema" 
xmlns:soapenc="https://schemas.xmlsoap.org/soap/encoding/" 
xmlns:wsdl="https://schemas.xmlsoap.org/wsdl/" 
xmlns="https://schemas.xmlsoap.org/wsdl/">

<message name="getRateRequest1">
  <part name="country1" type="xsd:string" /> 
  <part name="country2" type="xsd:string" /> 
</message>
<message name="getRateResponse1">
  <part name="Result" type="xsd:float" /> 
</message>
<portType name="net.xmethods.services.
currencyexchange.CurrencyExchangePortType">
  <operation name="getRate" parameterOrder="country1 country2">
    <input message="tns:getRateRequest1" /> 
    <output message="tns:getRateResponse1" /> 
  </operation>
</portType>
<binding name="net.xmethods.services.currencyexchange.CurrencyExchangeBinding" 
type="tns:net.xmethods.services.currencyexchange.CurrencyExchangePortType">
<soap:binding style="rpc"
transport="https://schemas.xmlsoap.org/soap/http" />
  <operation name="getRate">
  <soap:operation soapAction="urn:xmethods-CurrencyExchange#getRate" /> 
    <input>
      <soap:body use="encoded" namespace="urn:xmethods-CurrencyExchange"
      encodingStyle="https://schemas.xmlsoap.org/soap/encoding/" /> 
    </input>
    <output>
      <soap:body use="encoded" namespace="urn:xmethods-CurrencyExchange"
      encodingStyle="https://schemas.xmlsoap.org/soap/encoding/" /> 
    </output>
  </operation>
</binding>
<service name="net.xmethods.services.currencyexchange.CurrencyExchangeService">
  <documentation>
  net.xmethods.services.currencyexchange.CurrencyExchange web service
  </documentation> 
  <port name="net.xmethods.services.currencyexchange.CurrencyExchangePort"
  binding="tns:net.xmethods.services.currencyexchange.
  CurrencyExchangeBinding">
    <soap:address location="https://206.135.115.109:9090/soap" /> 
  </port>
</service>
</definitions>

This is the WSDL file for an exchange rate service implemented in Glue from The Mind Electric. Therefore, the format is not identical to a Microsoft SOAP Toolkit WSDL file, but it is compatible. The first element of the WSDL file is the definitions element, which is the root element of the file and normally contains several namespace declarations:

<definitions 
name="net.xmethods.services.currencyexchange.CurrencyExchange"
targetNamespace="https://www.themindelectric.com/wsdl/
  net.xmethods.services.currencyexchange.CurrencyExchange/"
xmlns:tns="https://www.themindelectric.com/wsdl/
  net.xmethods.services.currencyexchange.CurrencyExchange/"
xmlns:electric="https://www.themindelectric.com/" 
xmlns:soap="https://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:xsd="https://www.w3.org/2001/XMLSchema" 
xmlns:soapenc="https://schemas.xmlsoap.org/soap/encoding/" 
xmlns:wsdl="https://schemas.xmlsoap.org/wsdl/" 
xmlns="https://schemas.xmlsoap.org/wsdl/">

</definitions>

Note that the xsd namespace is the 2001 version. The SOAP Toolkit defaults to the 2001 Recommendation version of the XSD Schema namespace but it can understand WSDL files written with older namespace versions.

If the WSDL used any complex types, the XSD Schema definition for these types would be contained in a <types></types> element. Since this WSDL file doesn't use any complex types, that element is missing.

The next section defines the messages used by the service defined in this WSDL:

<message name="getRateRequest1">
  <part name="country1" type="xsd:string" /> 
  <part name="country2" type="xsd:string" /> 
</message>
<message name="getRateResponse1">
  <part name="Result" type="xsd:float" /> 
</message>

The names and datatypes of the method parameters are defined here.

The portType element defines a mapping between the messages defined in the previous section and the operations that use them:

<portType name="net.xmethods.services.currencyexchange.CurrencyExchangePortType">
  <operation name="getRate" parameterOrder="country1 country2">
    <input message="tns:getRateRequest1" /> 
    <output message="tns:getRateResponse1" /> 
  </operation>
</portType>

The binding element defines a binding between the abstract operations defined in the portType element and how they are implemented in SOAP. This is done is a separate element because WSDL is intended to define other non-SOAP protocols. A few thing to note here: the style="rpc" means that this message uses the rpc rules defined in section 7 of the SOAP standard. If style="document" was specified, the contents of the SOAP message would be an XML document. The transport attribute indicates that the SOAP messages will be sent in SOAP HTTP messages, the soapAction attribute defines the contents of the soapAction header in the HTTP packet, and the use="encoded" attribute indicates that SOAP section 5 encoding is used for parameter values.

<binding name=
"net.xmethods.services.currencyexchange.CurrencyExchangeBinding"
type="tns:net.xmethods.services.currencyexchange.CurrencyExchangePortType">
<soap:binding style=
"rpc" transport="https://schemas.xmlsoap.org/soap/http" />
  <operation name="getRate">
  <soap:operation soapAction="urn:xmethods-CurrencyExchange#getRate" /> 
    <input>
    <soap:body use="encoded" namespace="urn:xmethods-CurrencyExchange"
    encodingStyle="https://schemas.xmlsoap.org/soap/encoding/" /> 
    </input>
    <output>
    <soap:body use="encoded" namespace="urn:xmethods-CurrencyExchange"
    encodingStyle="https://schemas.xmlsoap.org/soap/encoding/" /> 
    </output>
  </operation>
</binding>

The service element ties a SOAP binding to a physical implementation of the service. This is where the URL of the service is defined. Notice that this service is found at port 9090—SOAP doesn't just work through port 80. (There is also a copy of the service running on port 80 if your firewall requires you to use port 80.)

<service
  name="net.xmethods.services.currencyexchange.CurrencyExchangeService">
  <documentation>
  net.xmethods.services.currencyexchange.CurrencyExchange web service
  </documentation> 
  <port name="net.xmethods.services.currencyexchange.CurrencyExchangePort"
  binding="tns:net.xmethods.services.
  currencyexchange.CurrencyExchangeBinding">
  <soap:address location="https://206.135.115.109:9090/soap" /> 
  </port>
</service>

Building a Simple Client Application

This section walks through the process of building a simple SOAP application using the SOAP Client included in Windows XP. The Web Service used in our example is the currency exchange rate service located at the XMethods site, an online listing of available SOAP services. 

This service accepts two countries as parameters and returns the exchange rate between them. The WSDL file that describes this service is available at: https://www.xmethods.net/sd/CurrencyExchangeService.wsdl.

The steps necessary to call this SOAP method using the high-level SOAP API are: create a SOAPClient object, initialize the SOAPClient object with the WSDL file, and call the method.

Here's the simple VBScript code that accomplishes this:

dim SOAPClient
set SOAPClient = createobject("MSSOAP.SOAPClient")
on error resume next
SOAPClient.mssoapinit("https://www.xmethods.net/sd/
CurrencyExchangeService.wsdl") 
  if err then
    wscript.echo SOAPClient.faultString
    wscript.echo SOAPClient.detail
  end if
wscript.echo SOAPClient.getRate("England","Japan")
  if err then
    wscript.echo SOAPClient.faultString
    wscript.echo SOAPClient.detail
  end if

The three bold lines correspond to the three steps mentioned previously. The parameter to mssoapinit is a WSDL file specification, which can be either an URL if the WSDL file is located on a remote system or a file path if the WSDL file is present on the local machine. A local WSDL file is more efficient because no network round-trips are necessary to retrieve the file. Still, it is easier to administer a single WSDL file that gets loaded to all the clients as it is used.

To run this SOAP method, type the code into a file called "currency.vbs" and then execute it with "cscript currency.vbs". The results should look something like this:

C:\SOAPDemo>cscript currency.vbs
Microsoft (R) Windows Script Host Version 5.1 for Windows
Copyright (C) Microsoft Corporation 1996-1999. All rights reserved.

173.9434

You should easily be able to apply this to VB, C++, or any other COM-enabled language. Here's the same service implemented in VB:

Private Sub Form_Load()
  Dim SOAPClient As SOAPClient
  Set SOAPClient = New SOAPClient
  On Error GoTo SOAPError
  SOAPClient.mssoapinit _
  ("https://services.xmethods.net/soap/urn:xmethods-CurrencyExchange.wsdl")
  MsgBox Str(SOAPClient.getRate("England", "Japan")), _
  vbOKOnly, "Exchange Rate"
Exit Sub
SOAPError:
  MsgBox SOAPClient.faultstring + vbCrLf + SOAPClient.detail, vbOKOnly,_
  "SOAP Error"
End Sub

Note:

   

The version of the SOAPClient that is included in Windows XP is not suitable for running in an ASP application. To do that, you must download the full release of the SOAP Toolkit 2.0.

Next Steps

Now that you know how to build a Web Services client application using SOAP in Windows XP, you might want to expand your SOAP knowledge and build Web Services of your own. Two good sources of information are https://msdn.microsoft.com/soap/ and https://msdn.microsoft.com/webservices/. These sites have links to SOAP information, white papers, other SOAP sites, and the download page where you can download the complete SOAP Toolkit 2.0 to start building your own Web Service applications. Please note that when you install the full release you will get some warnings about the inability to overwrite the current files because of system file protection. It is safe to ignore these errors. You can also go to XMethods and try some more of the services there—just keep in mind that in order for the SOAP Toolkit to work, the service must supply a WSDL file.

The SOAP Client Object

This section reviews the object model exposed by the SOAPClient object. Each method and property exposed by the SOAPClient is described. For more information, see https://msdn.microsoft.com/soap/.

Mssoapinit Method

The mssoapinit method initializes the SOAPClient object using the Web Services Description Language (WSDL) file as input. All of the operations in the identified service are bound to the SOAPClient object during initialization. Thus, you can call the operations defined in the service using the SOAPClient object.

Method definition

HRESULT mssoapinit(
 [in] BSTR bstrWSDLFile,
 [in, optional, defaultvalue("")] BSTR bstrServiceName,
 [in, optional, defaultvalue("")] BSTR bstrPort,
 [in, optional, defaultvalue("")] BSTR bstrWSMLFile);

Parameters

bstrWSDLFile

bstrWSDLFile is the URL of the WSDL file that describes the services offered by the server.

bstrServiceName

bstrServiceName is the optional service in the WSDL file that contains the operation specified in the Simple Object Access Protocol (SOAP) request. If this parameter is missing, null, or an empty string, the mssoapinit method uses the first service in the specified WSDL file when initializing the SOAPClient object.

bstrPort

bstrPort, also optional, is the name of the port in the WSDL file that contains the operation specified in the SOAP request. If this parameter is missing, null, or an empty string, the mssoapinit method uses the first port in the specified service when initializing the SOAPClient object.

bstrWSMLFile, also optional, is the URL of the Web Services Meta Language (WSML) file. This is a required parameter only when using custom type mappers.

Visual Basic syntax

Sub mssoapinit(bstrWSDLFile As String,_ 
   [bstrServiceName As String],_ 
   [bstrPort  As String],_ 
   [bstrWSMLFile As String])

Visual Basic example

set soapclient = CreateObject("MSSOAP.SOAPClient") 
call soapclient.mssoapinit("DocSample1.wsdl", "", "", "")
wscript.echo soapclient.AddNumbers(2,3)
wscript.echo soapclient.SubtractNumbers(3,2)

Remarks

The mssoapinit method is part of the high-level API on the client side. To use this method, you must first create a SOAPClient object on the client. Then, call the mssoapinit method using the WSDL file name, service name, and port name as parameters. Now the client can call any operations defined in the WSDL file for the requested service or port.

ClientProperty Property

The ClientProperty property sets and retrieves properties specific to the SOAPClient object.

Method definition

[propget] HRESULT ClientProperty(
  [in]  BSTR  PropertyName,
  [out, retval] VARIANT* pPropertyValue);

[propput] HRESULT ClientProperty(
  [in] BSTR PropertyName,
  [in] VARIANT pPropertyValue);

Parameters

PropertyName PropertyName is the name of the property to set or retrieve. See the following Remarks section for a list of properties. The following properties are supported (the property names are case sensitive):

Property Name Description
ServerHTTPRequest A True/False value indicating whether to use the "server-safe" XML components to load the Web Services Description Language (WSDL) and Web Services Meta Language (WSML) files. Set to True when an Active Server Pages (ASP) application or an ISAPI DLL uses the SOAPClient object.

When ServerHTTPRequest is set to true, the WinHTTP Proxy Configuration Utility must be used to configure WinHTTP. This is necessary even if a proxy server is not being used. Download utility and follow the usage instructions provided in the ReadMe.txt file provided in the download.

ConnectorProgID Specifies the ProgID of a class that implements the ISOAPConnector interface. Will create and use objects of this class when sending requests to the service. When set to an empty string, the default value, SOAPClient uses a SOAPConnectorFactory object to create a connector for the transport protocol specified the WSDL.

pPropertyValue

pPropertyValue is the property's value.

Visual Basic syntax

Property ClientProperty(PropertyName As String) As Variant

Visual Basic example

Dim Client As New SOAPClient
Client.ClientProperty("ServerHTTPRequest") = True

ConnectorProperty Property

Sets and retrieves properties specific to the transport protocol connector used by a SOAPClient object.

Method definition

[propget] HRESULT ConnectorProperty (
  [in]  BSTR  PropertyName,
  [out, retval] VARIANT* pPropertyValue);

[propput] HRESULT ConnectorProperty (
  [in] BSTR PropertyName,
  [in] VARIANT pPropertyValue);

Parameters

PropertyName

PropertyName is the name of the property to set or retrieve. Which properties are supported depends on the connector being used. The protocol specified by the <soap:binding> transport attribute in the Web Services Description Language (WSDL) file determines the connector to use.

pPropertyValue

pPropertyValue is the value of the property.

Visual Basic syntax

Property ConnectorProperty(PropertyName As String)

Visual Basic example

Dim Client As New SOAPClient
Client.mssoapinit WSDLFile, Service, Port
Client.ConnectorProperty("ProxyUser") = User
Client.ConnectorProperty("ProxyPassword") = Password

Connector properties

Property Description
AuthPassword The password used for end point authentication.
AuthUser The user name used for end point authentication.
EndPointURL The end point URL.
ProxyPassword The password used for proxy authentication.
ProxyPort The port of the proxy server to use.
ProxyServer The IP address or host name of the proxy server.
ProxyUser The user name used for proxy authentication.
SOAPAction The value used in the SOAPAction HTTP header.
SSLClientCertificateName A string identifying the client certificate to use for the Secure Sockets Layer (SSL) protocol, if any. The syntax is:
[CURRENT_USER | LOCAL_MACHINE\[store-name\]]cert-name

with the defaults being CURRENT_USER\MY (the same store that Microsoft Internet Explorer uses).

Timeout The timeout for HttpConnector. This timeout is in milliseconds.
UseSSL A Boolean value (true or false) that specifies the use of SSL.

Detail Property

The detail property is read-only. It provides the value of the <detail> element of the <Fault> element in the Simple Object Access Protocol (SOAP) message.

Method definition

[propget] HRESULT detail(
  [out, retval] BSTR* bstrDetail);

Parametersd

bstrDetail

bstrDetail is the detail of the fault.

Visual Basic syntax

Property detail As String

HeaderHandler (SOAPClient)

Sets the header handler for the next call against this client instance.

Method definition

HRESULT HeaderHandler([in] IDispatch* rhs);

Parameters

rhs

rhs is the reference to the COM class interface that implements the IHeaderHandler.

Visual Basic syntax

Property HeaderHandler As Object

Visual Basic example

Set sc = WScript.CreateObject("MSSOAP.SOAPClient")
sc.mssoapinit "https://localhost/DocSample7/DocSample7.wsdl"
sc.HeaderHandler = 
  WScript.CreateObject("SessionInfoClient.clientHeaderHandler")
Sc.SomeMethod "param1", "param2"

Faultactor Property (SOAPClient)

The faultactor property is read-only, and provides the Universal Resource Identifier (URI) that generated the fault.

Method definition

[propget] HRESULT faultactor(
  [out, retval] BSTR* bstrActor);

Parameters

bstrActor

The bstrActor is the URI that generated the fault.

Visual Basic syntax

Property faultactor As String

Visual Basic example

wscript.echo soapclient.faultactor

Faultcode Property (SOAPClient)

The faultcode property is read-only. It provides the value of the <faultcode> element of the <Fault> element in the Simple Object Access Protocol (SOAP) message.

Method definition

[propget] HRESULT faultcode(
  [out, retval] BSTR* bstrFaultcode);

Parameters

bstrFaultcode

bstrFaultcode is the value of the <faultcode> element.

Visual Basic syntax

Property faultcode As String

Visual Basic example

wscript.echo soapclient.faultcode

Faultstring Property (SOAPClient)

This faultstring property is read-only. It provides the value of the <faultstring> element of the <Fault> element in the Simple Object Access Protocol (SOAP) message.

Method definition

[propget] HRESULT faultstring(
  [out, retval] BSTR* bstrFaultstring);

Parameters

bstrFaultstring

bstrFaultstring is the value of the <faultstring> element.

Visual Basic syntax

Property faultstring As String

Visual Basic example

wscript.echo soapclient.faultstring