Using the SOAP Toolkit to Format SOAP Headers for MapPoint Web Service

 

IMPORTANT: MapPoint Web Service was retired on November 18, 2011. Please see Bing Maps for a list of current Bing Maps APIs.

Justin Southall
Microsoft Corporation

March 2005

Update  SOAP Toolkit 2.0 is no longer supported. Information in this article may apply to SOAP Toolkit 3.0, which has been deprecated by the Microsoft .NET Framework. See the SOAP Toolkit page on the MSDN Web Services Developer Center for information on available support for SOAP Toolkit 3.0.

Applies to:
Microsoft SOAP Toolkit 3.0
Microsoft MapPoint Web Service 3.5 and later

Summary: Learn how to modify the SOAP headers produced by the SOAP Toolkit so that they work with MapPoint Web Service. (7 printed pages)

Contents

Introduction MapPoint Web Service SOAP Headers Using the SOAP Toolkit Implementing IHeaderHandler Conclusion

Introduction

The Microsoft .NET Framework is a perfect fit for any Web-based or desktop application that accesses Web services. But before the .NET Framework was released, the only Microsoft product offering a way to access Web services was the SOAP Toolkit. Although the SOAP Toolkit is an older technology, many applications still rely on it to make SOAP-based calls. If you have a Web site that uses ASP as its main programming language or an application that uses Microsoft Visual Basic 6.0 or Microsoft Visual C++, you must use the SOAP Toolkit to incorporate the functionality that MapPoint Web Service offers.

MapPoint Web Service uses values in SOAP headers to set parameters such as locale, distance unit (miles or kilometers), custom reporting values, and so on. However, the SOAP Toolkit does not create SOAP headers in a format that MapPoint Web Service recognizes, and that can be a problem. If the values in the SOAP header are not set properly, MapPoint Web Service sets the parameters to their default values.

This article shows you how to modify the output of the SOAP Toolkit to create headers that work with MapPoint Web Service. This article assumes that you are familiar with the MapPoint Web Service SOAP API. For more information, see Developing with MapPoint Web Service in the MapPoint Web Service SDK.

MapPoint Web Service SOAP Headers

MapPoint Web Service has two main SOAP headers: UserInfo and CustomerInfo. Each MapPoint Web Service service has slightly different names for its headers, as listed in the following table.

ServiceHeaders
CommonCustomerInfoHeader
 UserInfoHeader
RenderCustomerInfoRenderHeader
 UserInfoRenderHeader
FindCustomerInfoFindHeader
 UserInfoFindHeader
RouteCustomerInfoRouteHeader
 UserInfoRouteHeader

Figure 1 shows the hierarchy of each of the headers.

ms980699.mwsheaders01(en-us,MSDN.10).gif

Figure 1. MapPoint Web Service headers

According to this diagram, you would expect the XML in the SOAP header for the find service to be formatted as follows:

<SOAP:Header>
<CustomerInfoFindHeader>
<CustomLogEntry/>
</CustomerInfoFindHeader>
<UserInfoFindHeader>
<DefaultDistanceUnit/>
<Context>
<EntityID/>
<Iso2/>
</Context>
<Culture>
<Name/>
<Lcid/>
</Culture>
</UserInfoFindHeader>
</SOAP:Header>

And this is, indeed, the format in which MapPoint Web Service expects to receive the SOAP XML.

Using the SOAP Toolkit

The SoapClient30 object of the SOAP Toolkit has a HeaderHandler property that accepts any implementation of the IHeaderHandler interface as its argument. This HeaderHandler object defines how the SOAP headers are read and written. This section illustrates how to implement the IHeaderHandler_WriteHeaders method so that it returns a SOAP header in a format that MapPoint Web Service can recognize.

The following code example uses the MapPoint Web Service route service to demonstrate how to create an instance of the SoapClient30 object for the route service.

[Visual Basic 6.0]
Dim myRouteService As New SoapClient30
myRouteService.MSSoapInit2 "[path to wsdl file]", _
"[path to wsml file]", "RouteService", "RouteServiceSoap", _
"http://s.mappoint.net/mappoint-30/"

'Set the user ID and password.
myRouteService.ConnectorProperty("AuthUser") = "[UserName]"
myRouteService.ConnectorProperty("AuthPassword") = "[Password]"
myRouteService.ConnectorProperty("WinHTTPAuthScheme") = 24 
    
Set myRouteService.HeaderHandler = IHeaderHandlerClass

Suppose you want to retrieve driving directions from MapPoint Web Service, but you want the distance units to be in miles instead of kilometers (the default). To retrieve the distance in miles, you must use an implementation of the IHeaderHandler_WriteHeaders method to set the value of the DefaultDistanceUnit header. The following code example shows a commonly-used implementation of IHeaderHandler_WriteHeaders.

[Visual Basic 6.0]
Private Sub IHeaderHandler_WriteHeaders( _
    ByVal pSerializer As MSSOAPLib30.ISoapSerializer, _
    ByVal pObject As Object)
    
'Call the Serializer methods to create UserInfoRouteHeader.
    pSerializer.StartHeaderElement "UserInfoRouteHeader", 
"http://s.mappoint.net/mappoint-30/"
    pSerializer.StartElement "DefaultDistanceUnit"
    pSerializer.WriteString "Mile"
    pSerializer.EndElement
    pSerializer.EndHeaderElement
End Sub

You might expect that this implementation generates XML in the following format:

<UserInfoRouteHeader namespace="http://s.mappoint.net/mappoint-30">
<DefaultDistanceUnit>Mile</DefaultDistanceUnit>
</UserInfoRouteHeader>

But instead, the SOAP Toolkit generates the following XML structure:

<SOAPSDK4:UserInfoFindHeader 
xmlns:SOAPSDK4="http://s.mappoint.net/mappoint-30/">
<DefaultDistanceUnit>Mile</DefaultDistanceUnit>
</SOAPSDK4:UserInfoFindHeader>

The element prefix SOAPSDK4 causes the DefaultDistanceUnit parameter to be unrecognized by MapPoint Web Service and, therefore, MapPoint Web Service returns driving directions with distances specified in kilometers instead of miles.

But because you already know how the XML should look, you don't need to call the serializer methods such as StartHeaderElement and StartElement. Instead, you can build the XML yourself as a string, as shown in the following implementation of IHeaderHandler_WriteHeaders. That way, you can control the format of the XML.

[Visual Basic 6.0]
Private Sub IHeaderHandler_WriteHeaders( _
    ByVal pSerializer As MSSOAPLib30.ISoapSerializer, _
    ByVal pObject As Object)
    
    Dim doc As New MSXML2.DOMDocument40
    Dim NameSpace As String
    NameSpace = "http://s.mappoint.net/mappoint-30/"
    Dim myDistanceUnit As String
    myDistanceUnit = "Mile"

    'Create the string for UserInfoRouteHeader.
    Dim userDoc As String
    userDoc = "<UserInfoRouteHeader xmlns=""" & NameSpace & """>"
    userDoc = userDoc & "<DefaultDistanceUnit>" & myDistanceUnit & _
"</DefaultDistanceUnit>"
    userDoc = userDoc & "</UserInfoRouteHeader>"
    
    pSerializer.WriteXml userDoc
End Sub

This code example correctly formats the XML in the SOAP header to retrieve driving directions with distances in miles instead of kilometers, as intended.

Implementing IHeaderHandler

This section contains a full implementation of the RouteHeaderHelper class, which demonstrates how to format a SOAP header for MapPoint Web Service. You can copy this code into Microsoft Visual Studio and compile it.

[Visual Basic 6.0]
Option Explicit
Implements IHeaderHandler

Private Const NameSpace As String = "http://s.mappoint.net/mappoint-30/"
Private myDistanceUnit As String

Public Property Let DistanceUnit(ByVal newUnit As String)
    myDistanceUnit = newUnit
End Property

Public Property Get DistanceUnit() As String
    DistanceUnit = myDistanceUnit
End Property

Private Function IHeaderHandler_ReadHeader( _
    ByVal pReader As SoapReader30, _
    ByVal pHeaderNode As MSXML2.IXMLDOMNode, _
    ByVal pObject As Object) _
    As Boolean
    
    IHeaderHandler_ReadHeader = False
End Function

Private Function IHeaderHandler_WillWriteHeaders() As Boolean
    IHeaderHandler_WillWriteHeaders = True
End Function

Private Sub IHeaderHandler_WriteHeaders( _
    ByVal pSerializer As MSSOAPLib30.ISoapSerializer, _
    ByVal pObject As Object)
    
    Dim doc As New MSXML2.DOMDocument40
    
    'Create the string for UserInfoRouteHeader.
    Dim userDoc As String
    userDoc = "<UserInfoRouteHeader xmlns=""" & NameSpace & """>"
    
    If myDistanceUnit <> "" Then
        userDoc = userDoc & "<DefaultDistanceUnit>" & myDistanceUnit & 
"</DefaultDistanceUnit>"
    End If
    
    userDoc = userDoc & "</UserInfoRouteHeader>"
    
    pSerializer.WriteXml userDoc
End Sub

The following code illustrates how you can use the RouteHeaderHelper class defined earlier in this section. In this example, the DistanceUnit property of the RouteHeaderHandler class is set to Mile, so that MapPoint Web Service calculates driving directions by using miles instead of the kilometers.

For more information about how to implement IHeaderHandler classes, see the SOAP Toolkit documentation.

[Visual Basic 6.0]
'Initialize MapPoint Web Service.
  Dim routeService As New SoapClient30
  With routeService
    .MSSoapInit2 "[path to wsdl]", _
                 "[path to wsml]", _
                 "RouteService", _
                 "RouteServiceSoap", _
                 "http://s.mappoint.net/mappoint-30/"
                 
    .ConnectorProperty("AuthUser") = "[UserName]"
    .ConnectorProperty("AuthPassword") = "[Password]"
    .ConnectorProperty("WinHTTPAuthScheme") = 24 
    
    Set .HeaderHandler = New RouteHeaderHelper
    .HeaderHandler.DistanceUnit = "Mile"
  End With

Conclusion

When using the SOAP Toolkit with MapPoint Web Service, you must generate properly formatted SOAP headers. To format the headers, you simply remove the leading element prefixes generated by the SOAP Toolkit, and the SOAP packets will once again work with MapPoint Web Service. Formatting the XML as a string in the code is a fast and easy way to make sure that your SOAP headers are in the format that MapPoint Web Service can recognize.

Justin Southall is a Web Development Engineer in the Microsoft MapPoint Business Unit, and is a member of the Professional Services team.

Show: