Delphi SOAP Server: hexBinary type

Hello,

I’m building a SOAP server in Delphi. I have switched from Delphi’s native SOAP tools to the Remoting SDK because it’s a requirement to have a document/literal server.

My server requires some complex objects (which with Delphi’s implementation I did by classes inheriting from TRemotable). With Remoting SDK I found that I can do the same with TROComplexType.

However, in my Delphi implementation I use the

I have defined some custom types using TROComplexType as a base class. However, some properties of those custom types require the use of the hexBinary type.

In Delphi’s native SOAP tools I used the TXSDateTime and TXSHexBinary types from Delphi’s Soap.XSBuiltIns unit. For the TXSDateTime type there appears to be an equivalent with the XsDateTime type. But for the hexBinary type I’m at a loss.

In what way can I make it so that in my WSDL type=“xs:hexBinary” will appear as type? I have searched far and wide for a possible solution, but I can’t find anything that might get me underway. It goes without saying that I’m new to RemObjects :wink:

I hope somebody can help me along.

Thanks!

Hi,

Remoting SDK passes soap binary as xsd:base64Binary.

declare property with Binary type.

Hi Evgeny,

Thanks for your reply. I had already found TROBinaryMemoryStream, but when using it I end up with type=“base64Binary” in the wsdl. I already found out that SOAP provides in two binary types, base64Binary and hexBinary.

I am creating a webservice that has to adhere to a standard (www.stosag.nl), that explicitly requires me to use hexBinary.

Is there any way to tell TROBinaryMemoryStream to use base64 or base16 (hex)?

Hi,
Remoting SDK supports only base64Binary.

but you can convert it manually in the TROSOAPMessage.OnEnvelopeComplete event.

Note: you can use in this event these properties of TROSOAPMessage:

    property EnvelopeNode : IXMLNode;
    property BodyNode: IXMLNode;
    property MessageNode: IXMLNode;
    property FaultNode : IXMLNode;
    property HeaderNode : IXMLNode;

Hi,

It’s in the incoming message that the encoded value is, but your reply gave me the idea to use the TROSOAPMessage.OnBeforeProcessIncomingEnvelopes event. I simply modify the inbound stream before it gets processed where I then convert as nescescarry.

This only leaves the issue of the WSDL file. This wil still be published with type=“xs:base64binary”. For this I used the TROServer.OnWriteToStream event, I replace base64binary with hexBinary and voila… my webservice now supports hexBinary.

One question though: it would be better if could do the string replace only when the WSDL is served. Is there any way that I can see the targetURI of the http request when te OnWriteToStream event fires?

My original idea was to use the OnCommandGet of the internal Indy server, but… if I link my own eventhandler the entire thing stops working, which leeds me to believe that TROIndyHTTPServer links it’s own event handler that get’s overwritten by mine.

Next I tried the TROServer.OnCustomResponseEvent, where I CAN see the URI, but this only seems to fire when an acutal SOAP request has been made and not when a mere GET for the wsdl file is done.

base64binary is hardcoded so it can’t be changed easily

I can suggest to use OnCustomResponseEvent. this link contains some example that will be useful for you.

Note: this event only works for unhandled (i.e. unknown) requests.

you can process here link like http://localhost:8099/mywsdl
this event should catch this request, change path and pass modified data to MainProcessMessage.
later you can grab aRequestStream and modify data as you like.

the same can be done with usual method calls (http://localhost:8099/mysoap) - you can modify aRequestStream and change hexBinary data with base64binary

Thanks, logged as bugs://83171

Thank you Evgeny,

This indeed works, but for now I’ll keep using the TROServer.OnWriteStream (I check if it’s a WSDL document that is returned by analyzing the contents).

Too bad there isn’t one place where you can intercept all incoming HTTP requests and responses as you can with Indy’s HTTP server (or any http server for that matter).

But still, I got everyting I need to work, well working.

Regards,

Stijn

We use these events:

  fIndyServer.OnCommandGet := InternalServerCommandGet;
  fIndyServer.OnCommandOther := InternalServerCommandOther;
  fIndyServer.OnConnect := InternalServerConnect;

you can assign your own events here, but you should store our methods before assigning your ones.
also you should call our methods inside your events …

:man_facepalming:

I could have thought of that :smile:

That’s indeed a good way. Thanx!

bugs://83171 got closed with status fixed.