Virtual Earth
Getting Virtual Earth tokens using perl and SOAP::Lite

Microsoft's documentation for their web services is great if you use .NET, C# or Java. For the rest of us their documentation is sorely lacking in practical low-level information that allows us to easily integrate our toolkits of choice.

I had this problem when recently I had to talk to MS's Virtual Earth web service to get tokens for using VE maps commercially. After much beating of my head against the desk I found a way to get hold of a working SOAP call.

This is what the SOAP request needs to look like:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns3780="http://tempuri.org">
<SOAP-ENV:Body>
<GetClientToken xmlns="http://s.mappoint.net/mappoint-30/">
<specification>
<ClientIPAddress>192.168.1.1</ClientIPAddress>
<TokenValidityDurationMinutes>480</TokenValidityDurationMinutes>
</specification>
</GetClientToken>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Once I had a working SOAP call I could fiddle with SOAP::Lite until I got it to generate the right stuff to satisfy the MS SOAP server. Here's what I ended up with:

Readonly::Scalar my $VE_SOAP_ACCOUNT  => 'your account here';
Readonly::Scalar my $VE_SOAP_PASSWORD => 'your password';
Readonly::Scalar my $VE_TOKEN_SERVICE => 'https://staging.common.virtualearth.net/find-30/common.asmx';
#Readonly::Scalar my $VE_TOKEN_SERVICE => 'https://common.virtualearth.net/find-30/common.asmx';

sub get_ve_token {
    my $token_request = SOAP::Lite
      ->encoding('ISO-8859-1')
      ->uri('http://s.mappoint.net/mappoint-30/')
      ->on_action( sub { join '/', 'http://s.mappoint.net/mappoint-30', $_[1] } )
      ->proxy($VE_TOKEN_SERVICE);     

    my $token_spec = SOAP::Data->name(
        'specification' => {
            'ClientIPAddress'              => '203.10.1.1',
            'TokenValidityDurationMinutes' => 120
        }
    );   

    my $token = $token_request
        ->call(SOAP::Data->name('GetClientToken')
        ->attr( { xmlns => 'http://s.mappoint.net/mappoint-30/' } ) => $token_spec )
        ->result;     

if ( $token_request->call->fault ) {
      return "";
    }
    else {
        return $token;
    }
}

sub SOAP::Transport::HTTP::Client::get_basic_credentials {
    return $VE_SOAP_ACCOUNT => $VE_SOAP_PASSWORD;
}

 Hopefully this will help someone else out at some point!

 

 

Last Updated on Wednesday, 08 April 2009 11:39