views:

1135

answers:

2

Has anyone gotten Bing Map Web Services (formerly Virtual Earth Web Services) working with Delphi?

Based on my experiences so far (both using Delphi and Visual Studio C#), I'm about ready to give up on it and go with the MapPoint Web Service until a future version of Bing Maps Web Services comes out. However, I thought I'd post a question here as a last resort...

I imported the Token Service and Geocode Services WSDL documents.

I was successfully able to get a token from the token service, but have been unable to get the Geocode service to work at all. It always returns the following error message: The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).

I noticed Delphi wasn't specifying a value for the SOAPAction header, so I tried specifying "http://staging.dev.virtualearth.net/webservices/v1/geocode/contracts/IGeocodeService/Geocode" and got the following error message instead:

The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.

Below is my Delphi code and the raw XML being sent, then the raw XML being sent by a similar call from Microsoft's sample C# code. There are several differences in the XML, but I'm not sure what difference(s) is the key.

var
  Service: IGeocodeService;
  Request: Geocode;
  Response: GeocodeResponse3;
  ResponseIndex: Integer;
  Token: WideString;
  Filters: ArrayOfFilterBase;
begin
  Token := GetToken;

  Service := GetIGeocodeService;

  Request := Geocode.Create;
  try
    Request.request := GeocodeRequest.Create;

    Request.request.Credentials := GeocodeService.Credentials.Create; // Freed by GeocodeRequest class
    Request.request.Credentials.Token := Token;

    Request.request.Query := AddressEdit.Text;

    Request.request.Options := GeocodeOptions.Create;

    SetLength( Filters, 1 );
    Filters[ 0 ] := ConfidenceFilter.Create;
    ConfidenceFilter( Filters[ 0 ] ).MinimumConfidence := GeocodeService.High_;

    Request.request.Options.Filters := Filters;

    Response := Service.Geocode( Request );
    try
      for ResponseIndex := Low( Response.GeocodeResult.Results ) to High( Response.GeocodeResult.Results ) do
      begin
        OutputMemo.Lines.Add( Response.GeocodeResult.Results[ ResponseIndex ].DisplayName );
      end;
    finally
      Response.Free;
    end;
  finally
    Request.Free;
  end;
end;


<?xml version="1.0"?>
<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/"&gt;
    <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS2="http://dev.virtualearth.net/webservices/v1/geocode/contracts" xmlns:NS3="http://dev.virtualearth.net/webservices/v1/geocode" xmlns:NS4="http://dev.virtualearth.net/webservices/v1/common"&gt;
        <NS1:Geocode xmlns:NS1="http://dev.virtualearth.net/webservices/v1/geocode/contracts"&gt;
            <parameters href="#1"/>
        </NS1:Geocode>
        <NS2:Geocode id="1" xsi:type="NS2:Geocode">
            <request href="#2"/>
        </NS2:Geocode>
        <NS3:request id="2" xsi:type="NS3:GeocodeRequest">
            <Credentials href="#3"/>
            <Options href="#4"/>
            <Query xsi:type="xsd:string">Some Address</Query>
        </NS3:request>
        <NS4:Credentials id="3" xsi:type="NS4:Credentials">
            <Token xsi:type="xsd:string">cbYkKgNlrsGnZbn3HRP7Xp5LJMv3RR_5qECwgB792COfY3EPmviaDpZ4mmD3fDP1Osc6fWUkTptog7bfgM73bA2</Token>
        </NS4:Credentials>
        <NS3:Options id="4" xsi:type="NS3:GeocodeOptions">
            <Filters xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:FilterBase[1]">
                <item href="#5"/>
            </Filters>
        </NS3:Options>
        <NS3:ConfidenceFilter id="5" xsi:type="NS3:ConfidenceFilter">
            <MinimumConfidence xsi:type="NS4:Confidence">High</MinimumConfidence>
        </NS3:ConfidenceFilter>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"&gt;
    <s:Body>
        <Geocode xmlns="http://dev.virtualearth.net/webservices/v1/geocode/contracts"&gt;
            <request xmlns:a="http://dev.virtualearth.net/webservices/v1/geocode" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"&gt;
                <Credentials xmlns="http://dev.virtualearth.net/webservices/v1/common"&gt;
                    <ApplicationId i:nil="true"/>
                    <Token>pezCDpJoxdCG63NQdJUGkTrYYalnuSQDwuIC9FvheFAd9MIPO75qX9n7il0dx3eTEHlN2877PzN1_6YbQDL5tg2</Token>
                </Credentials>
                <Culture i:nil="true" xmlns="http://dev.virtualearth.net/webservices/v1/common"/&gt;
                <ExecutionOptions i:nil="true" xmlns="http://dev.virtualearth.net/webservices/v1/common"/&gt;
                <UserProfile i:nil="true" xmlns="http://dev.virtualearth.net/webservices/v1/common"/&gt;
                <a:Address i:nil="true" xmlns:b="http://dev.virtualearth.net/webservices/v1/common"/&gt;
                <a:Options>
                    <a:Count i:nil="true"/>
                    <a:Filters>
                        <a:FilterBase i:type="a:ConfidenceFilter">
                            <a:MinimumConfidence>High</a:MinimumConfidence>
                        </a:FilterBase>
                    </a:Filters>
                </a:Options>
                <a:Query>1 Microsoft Way, Redmond, WA</a:Query>
            </request>
        </Geocode>
    </s:Body>
</s:Envelope>
+1  A: 

My best guess is that Delphi seems to be producing too many Geocode elements - there doesn't appear to be any thing that corresponds to NS2:Geocode in the C# produced XML. If you can intercept the XML and change it so that it looks like this, who knows - it might work:

    ...
    <NS1:Geocode xmlns:NS1="http://dev.virtualearth.net/webservices/v1/geocode/contracts"&gt;
        <parameters href="#2"/>
    </NS1:Geocode>
    <NS3:request id="2" xsi:type="NS3:GeocodeRequest">
    ...

The other problem could be that the Bing service doesn't support the way Delphi organizes the SOAP request.

It that doesn't work, perhaps you can find another SOAP library you can use with Delphi - perhaps resorting to wrapping a library with a C or COM interface.

garethm
Thanks, I had tried something similar before, but I just tried it again with no luck.
Nathan Sutcliffe
A: 

I have exatctly the same problem. I run Delphi 2006, used WSDLImp.exe in command mode; needed version 11.0 of 2006 to get the import work. What do you use? We have the intention to try RemObjects, version 6. Any guess if that would work better?

Cheers, Lars

I'm using Delphi 2007.I'd be very interested to hear if you have any luck with RemObjects. I haven't worked on this project for a couple weeks, but I expect we'll use the the old MapPoint API instead until the Bing Map API matures.
Nathan Sutcliffe