DELPHI: RIO OnBeforeExecute

4.6k Views Asked by At

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;
1

There are 1 best solutions below

0
On

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:

  FEPS_SoapService := c_ExpressPSAPI.GetExpressSoap(System.False, '', HTTPRIO1);

I could then use the OnBeforeExecute like such:

procedure TForm1.HTTPRIO1BeforeExecute(const MethodName: string;
  var SOAPRequest: WideString);
var
  tmpString: TStringList;
begin
  try
    Memo1.Lines.Append(SOAPRequest);
  except
    on ER : ERemotableException do
      ShowMessage(ER.ClassName + ' error raised, with message : ' + ER.FaultDetail);

    on E : Exception do
      ShowMessage(E.ClassName + ' error raised, with message : ' + E.Message);
  end;
end;