Array_Of_Int in SOAP client

后端 未结 2 1218
你的背包
你的背包 2021-01-15 00:26

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

相关标签:
2条回答
  • 2021-01-15 00:57

    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;
    
    0 讨论(0)
  • 2021-01-15 00:59

    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

    0 讨论(0)
提交回复
热议问题