DELPHI: RIO OnBeforeExecute
У меня есть сервис SOAP, который я сгенерировал из внешнего источника, который дает мне некоторые ошибки. Я хотел бы захватить XML, отправляемый в службу SOAP, прежде чем он будет фактически отправлен, и нашел пару упоминаний о выполнении OnBeforeExecute на RIO, но не уверен, как это реализовать. Я обычно не использую Delphi, просто поддерживаю эту унаследованную программу, поэтому чем больше деталей, тем лучше!
Вот сгенерированный код API/SOAP (RIO_OnBeforeExecute - это то, что я пытался вставить, но он жалуется на несовместимые типы: указатель на метод и обычная процедура):
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;
Вот код, который вызывает метод HealthCheck (элементы cEPS_* являются константами, определенными ранее в коде):
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 ответ
Я смог заставить это работать и выкладываю ответ на тот случай, если кто-то еще найдет этот вопрос.
Для начала мне нужно было добавить компонент THTTPRIO (с именем HTTPRIO1) в мою форму, а затем настроить событие OnBeforeExecute для этого компонента (с именем HTTPRIO1BeforeExecute). Закончив, я передал объект HTTPRIO1 в метод GetExpressSOAP, связанный с методом OnBeforeExecute:
FEPS_SoapService := c_ExpressPSAPI.GetExpressSoap(System.False, '', HTTPRIO1);
Затем я мог бы использовать OnBeforeExecute следующим образом:
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;