1
votes

I was using the WSDL importer to create a class (Delphi 10.3). But got an error when calling a web service method. After examining the call with Fiddler, I've noticed that an attribute was missing.

In WSDL we have:

  <s:complexType name="ArrayOfAnyType">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="unbounded" name="anyType" nillable="true" type="s:string" />
    </s:sequence>
  </s:complexType>

The working SOAP envelope looks like this:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <FidelioSPMSWSXML xmlns="http://fideliocruise.de/">
      <psFunction>Login</psFunction>
      <poParam>
        <anyType xsi:type="xsd:string">sasa</anyType>
        <anyType xsi:type="xsd:string">F45731E3D39A1B2330BBF93E9B3DE59E</anyType>
      </poParam>
    </FidelioSPMSWSXML>
  </s:Body>
</s:Envelope>

Delphi creates envelope like this:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Body>
    <FidelioSPMSWSXML xmlns="http://fideliocruise.de/">
      <psFunction>Login</psFunction>
      <psSessionID/>
      <poParam>
        <anyType>username</anyType>
        <anyType>password</anyType>
      </poParam>
    </FidelioSPMSWSXML>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

And only thing why Delphi calls are not working is because of missing xsi:type="xsd:string" from anyType element. How to force Delphi to add that attribute?

1
Looks like a bug in the importer. Can't you fix the generated code?Olivier
no, I am trying to change the SOAP envelope in htpr1BeforeExecuteDejan Dozet

1 Answers

1
votes

Well, I found that the easiest way for me is to add THTTPRIO component on the form and to use it's onBeforeExecute event to change SOAPRequest like this:

procedure TForm2.htpr1BeforeExecute(const MethodName: string;
  SOAPRequest: TStream);
var
  sl: TStringList;
begin
  sl:=TStringList.Create;
  try
    SOAPRequest.Position := 0;
    sl.LoadFromStream(SOAPRequest);
    sl.Text := StringReplace(sl.Text,'<anyType>','<anyType xsi:type="xsd:string">',[RfReplaceAll]);
    sl.SaveToFile('SOAPRequest.txt'); //for debug
    SOAPRequest.Position := 0;
    sl.SaveToStream(SOAPRequest);
  finally
    sl.Free;
  end;
end;