I have a very interesting issue when I call a SOAP method with my client, I must pass a parameter which is of type Array_Of_Int(Array_Of_Int = array of Integer), the problem
Since no one cares to post their answer or have no other idea on how to fix this issue, I'll just post my fix until others can come out with a more elegant solution than editing the request.
Make sure the next line of code is added in the initialization section of the *.pas file generated when you imported the WSDL file(big thanks to Bruneau for pointing this out)
InvRegistry.RegisterInvokeOptions(TypeInfo(<ServerInterfaceNameHere>), ioDocument);
However that imposes another issue, the namespace, as a quick and pretty elegant fix, I've added the following code in the THTTPRio's OnBeforeExecute method
procedure TMyDataModule.MyRioBeforeExecute(const MethodName: string; SOAPRequest: TStream);
procedure FixNamespaces;
var
LStrings: TStringList;
begin
LStrings := TStringList.Create;
try
SOAPRequest.Position := 0;
LStrings.LoadFromStream(SOAPRequest);
SOAPRequest.Position := 0;
SOAPRequest.Size := 0;
LStrings.Text := StringReplace(LStrings.Text, MethodName, 'NS1:' + MethodName, [rfReplaceAll]);
LStrings.Text := StringReplace(LStrings.Text, MethodName + ' xmlns', MethodName + ' xmlns:NS1', []);
LStrings.SaveToStream(SOAPRequest);
SOAPRequest.Position := 0;
finally
FreeAndNil(LStrings);
end; // tryf
end; // procedure FixNamespaces;
begin
FixNamespaces;
// other possible issue to be fixed -- if any
end;
The two serialization options you described are both valid and needed. The issue is that from a language/native point of view, Delphi represents both of them with a dynamic array (Array_Of_Int = array of Integer). So, the runtime must be told whether to serialize for a "Pure Collection" (the first kind with elements and the outer ArrayParam) or "unbounded elements" ("ArrayParam" elements).
In earlier versions, including 2010, you could instruct the runtime to serialize as unbounded elements with the following registration:
RemClassRegistry.RegisterSerializeOptions(TypeInfo(Array_Of_Int), [xoInlineArrays]);
If the type is used in a property, you could also simply tag the property itself as unbounded, as in:
property propName: Array_Of_Int Index (IS_UNBD) read FName write FName;
The drawback of the registration approach is that it does not allow one to (re)use the type for both serializations. In Delphi XE this was remedied and now the type is never registered for a particular scheme. Instead each Dynamic Array property or parameter specifies whether it's a "Pure Collection" vs. "Unbounded Element", eliminating the need to have distinct Dynamic Array of Integers for each serialization.
Cheers,
Bruneau