Delphi 2007 generates invalid SOAP messages

I am writing an application in Delphi 2007 that uses a web service. I used the WSDL importer to generate the necessary code to communicate with this service, but when I try to use this service, I get "unexpected subelement (elementname)" errors.

Using Fiddler 2, I found that the problem is that xmlns is being added to the array of values ​​sent in the SOAP message:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="..." xmlns:xsd="..." xmlns:xsi="..."> <SOAP-ENV:Body> <Request xmlns="http://service.com/theService/"> <UserName xmlns="">user</UserName> <Password xmlns="">pass</Password> <List xmlns=""> <Item xmlns="http://service.com/theService/">123456</Item> <Item xmlns="http://service.com/theService/">84547</Item> </List> </Request> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

If I resend a message created by Delphi to Fiddler, changing xmlns for Item elements to an empty string, I no longer receive an error message, and the service responds correctly. i.e:

 <List xmlns=""> <Item xmlns="">123456</Item> <Item xmlns="">84547</Item> </List> 

Now I can get rid of the xmlns attribute for list items by changing the initialization part of my service class with

 InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioDocument); InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioLiteral); RemClassRegistry.RegisterSerializeOptions(RequestType, [xoLiteralParam]); 

in

 InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioDocument); RemClassRegistry.RegisterSerializeOptions(RequestType, [xoHolderClass, xoLiteralParam]); 

However, this will change the name of the request element to the default SOAP action name (for example, GetInformation), which will again cause an error. I struggled with this for too long, any ideas would be appreciated.

In addition, I created a C # test application that uses this service, and it has no problems communicating with the service.

+6
soap web-services delphi delphi-2007
source share
1 answer

I spoke with other people who had problems with serialization in Delphi, and it seems that there is no clear way to fix this problem.

Instead, the solution I came across is to bind an event handler to the OnBeforeExecute event of a THTTPRIO object that sends a SOAP message, giving you access to the serialized soap message as a string. From there, I just parsed the attribute that caused the problem, and now everything works.

A bit of an ugly solution, but it works.

+6
source share

All Articles