I have an SOAP service that I generated from an outside source that is giving me some errors. I would like to capture the XML being sent to the SOAP service before it is actually sent and have found a couple mentions of doing an OnBeforeExecute on the RIO but am not sure how to implement this. I do not normally use Delphi, just maintaining this legacy program so the more detail the better!
Here is the generated API/SOAP code (the RIO_OnBeforeExecute is what I tried to put in but it complains about incompatible types: method pointer and regular procedure):
ExpressSoap = interface(IInvokable)
['{83D77575-DBDE-3A05-D048-60B2F6BCDFE6}']
function HealthCheck(const credentials: Credentials; const application: Application): Response; stdcall;
end;
function GetExpressSoap(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): ExpressSoap;
procedure RIO_BeforeExecute(const MethodName: string; var SOAPRequest: WideString);
implementation
function GetExpressSoap(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): ExpressSoap;
const
defWSDL = 'https://certtransaction.elementexpress.com/express.asmx?wsdl';
defURL = 'https://certtransaction.elementexpress.com/express.asmx';
defSvc = 'Express';
defPrt = 'ExpressSoap';
var
RIO: THTTPRIO;
begin
RIO.OnBeforeExecute := RIO_BeforeExecute;
Result := nil;
if (Addr = '') then
begin
if UseWSDL then
Addr := defWSDL
else
Addr := defURL;
end;
if HTTPRIO = nil then
RIO := THTTPRIO.Create(nil)
else
RIO := HTTPRIO;
try
Result := (RIO as ExpressSoap);
if UseWSDL then
begin
RIO.WSDLLocation := Addr;
RIO.Service := defSvc;
RIO.Port := defPrt;
end else
RIO.URL := Addr;
finally
if (Result = nil) and (HTTPRIO = nil) then
RIO.Free;
end;
end;
procedure RIO_BeforeExecute(const MethodName: string; var SOAPRequest: WideString);
begin
MessageDlg('Hello', mtConfirmation, [mbOK] ,0);
end;
Here is the code that is calling the HealthCheck method (the cEPS_* items are constants defined earlier in the code):
procedure TForm1.Button1Click(Sender: TObject);
var
Headers : ISOAPHeaders;
aResult: c_ExpressPSAPI.Response;
begin
try
FEPS_SoapService := c_ExpressPSAPI.GetExpressSoap();
FEPS_Headers := (FEPS_SoapService as ISOAPHeaders);
FEPS_Application := c_ExpressPSAPI.Application.Create();
FEPS_Application.ApplicationID := cEPS_ApplicationID;
FEPS_Application.ApplicationName := cEPS_ApplicationName;
FEPS_Credentials := c_ExpressPSAPI.Credentials.Create();
FEPS_Credentials.AccountID := cEPS_AccountID;
FEPS_Credentials.AccountToken := cEPS_AccountToken;
FEPS_Credentials.AcceptorID := cEPS_AcceptorID;
FEPS_Credentials.NewAccountToken := '';
aResult := c_ExpressPSAPI.Response.Create;
aResult := FEPS_SoapService.HealthCheck(FEPS_Credentials, FEPS_Application);
except
on E : ERemotableException do
ShowMessage(E.ClassName + ' error raised, with message : ' + E.FaultDetail + ' :: '
+ E.Message);
end;
end;
I was able to get this working and am posting the answer in case someone else finds this question.
To begin with I had to add a THTTPRIO (named HTTPRIO1) component to my form and then setup the OnBeforeExecute event on that component (named HTTPRIO1BeforeExecute). Once done I passed the HTTPRIO1 object to the GetExpressSOAP method which tied in the OnBeforeExecute method:
I could then use the OnBeforeExecute like such: