tags:

views:

219

answers:

4

I'm having an issue trying to access a web service through Delphi. I've consumed a java WSDL with the 2007 version of the WSDLimp tool and it looks like it's created all of the objects correctly. When I make a tester program however that calls the service every object is empty. If I dump the SOAPResponse object in the HTTPRIOAfterExecute method I can see that I've gotten back a properly formatted XML Soap packet that contains all the data I would expect, but I can't access it through the objects. So is there something I'm missing?

A: 

You could try the solution discussed at http://www.borlandtalk.com/1-vt102378.html?start=0

Scott
+1  A: 

Delphi dropped the ball on web service support after Delphi 7 and didn't get their act together again until Delphi 2007 (though 2006 was an improvement).

If it works for you in Delphi 2007, you can probably get this working in Delphi 2005 by using the updated SOAP runtime.

http://cc.embarcadero.com/Item/24535

Bruce McGee
I unfortunately don't have access to D2007. I did use the WSDLimp that is referenced in your link. I definitely noticed that the D2005 created incredibly wrong code. I think my issue is happening where the SOAPResponse gets translated into the objects. Any idea where that occurs? I've tried stepping through the code but I haven't seen where that even tries to happen.
mcmar
Are you using the updated units from the same link? They are what Delphi 2007 uses and will be able to deal with the unit generated by the new WSDLImp and the web service SOAP packets.
Bruce McGee
I will admit that I wasn't using the updated source until yesterday when I realized there was source along with the newer WSDL. But I get the exact same results either way.
mcmar
Interesting. Is the URL public, and do you have an example of calling a method? I can try it in Delphi 2007 and 2009. I'd be interested to see what's up.
Bruce McGee
No the URL is internal to my company unfortunately. I downloaded the trial of D2009 yesterday and I get the exact same behavior as I did in 2005. I know that someone else I'm working with was able to consume the WSDL and get correct results through Java. So I think the service works in some regard..
mcmar
I think the service is fine. It's just Delphi's handling of the SOAP that seems to be an issue. Refer to the suggestion in my second answer and let me know if it helps.
Bruce McGee
A: 

I re-read the question and the fact that it's a Java web service made me remember something.

Making sure you use the latest WSDLImp and SOAP units. Look in the imported unit for the call to RegisterInvokeOptions. The second parameter should be ioDocument. What happens if you change this to ioDefault.

I remember a post somewhere that suggested this for Java NetBeans (maybe?) web services, but haven't tried it.

Bruce McGee
+1  A: 

The web service response contains aliased namespaces for each attribute. These aliases are not defined in the WSDL. For example, the WSDL contains a namespace of "http://www.example.com/SomeService" and the request aliases that on-the-fly as xmlns:ns3="http://www.example.com/SomeService" in the top level node. So attributes in the response look like ns3:somePropertyName="[value]".

In the OPToSOAPDomConv unit, in the TSOAPDomConv.InitObjectFromSOAP, it's attempting to look up an attribute name without the namespace prefix. This is causing the look up to fail and the object property to be left blank. This is happening even with the 2007 source files.

The best fix I can see is to modify the InitObjectFromSOAP routine.

Around line 4181, add:

  RemTypeRegistry.InfoToURI(PropList[i].PropType^, NS, PropName, IsScalar);

and change the AttrNode.HasAttribute to pass the NS variable as a second parameter so it looks like:

  if AttrNode.HasAttribute(ExternalPropName, NS) then

Also, a few lines down is a SetObjectPropFromText call. The last parameter is the attribute value, and you'll need to change Attr.Attributes[ExternalPropName] to

SetObjectPropFromText(Instance, PropList[I], AttrNode.GetAttributeNS(ExternalPropName, NS))

And of course declare the NS, PropName and IsScalar vars.

Scott