Question
· May 12, 2023

Serializing Collections in SOAP request of SOAP EnsLib Service

Has anyone had success with passing in a collections  property within a SOAP request to a Soap Service in Ensemble? Please reply with how you set up that collections property. I am able to successfully send a SOAP request correctly containing the elements of the collection property to Cache, as seen in a custom soap log file which I am using to troubleshoot. But the collection property in the  Ensemble request is not getting serialized, meaning MyContainers has nothing.

My.Request consists of a property, MyContainers, which can have 0 or more Containers (My.Container)

When MyContainers  is of My.ContainerList (ArrayOfObjects) datatype , I get an object script error : LIST>%GetSerial+1^%Library.ArrayOfObjects. Please see the class definition below.

When MyContainers is a  list of My.Container, the MyContaieners in the Ensemble message shows up empty.(This is not shown in the code snippets below)

 

See class definitions below

Service  class 

// Sample.MyService
Class Sample.MyService Extends EnsLib.SOAP.Service
{

/// Name of the WebService.
Parameter SERVICENAME = "MyService";
/// TODO: change this to actual SOAP namespace.
/// SOAP Namespace for the WebService
Parameter NAMESPACE = "http://tempuri.org";
Property Target as Ens.DataType.ConfigName

Method SendToTarget(pRqst As My.Request) As My.Response[SoapAction="http://tempuri.org/Sample.MyService.SendToTarget", webmethod]
{
    Set tSC= ..SendRequestSync(..Target, pRqst, .tResponse)
    return tResponse
}
/// 
Class My.Request Extends (HS.Util.EnsRequest, %XML.Adaptor)
{

    Property MyContainers As My.ContainerList;
}
/// 
Class My.ContainerList Extends (%ArrayOfObjects, %XML.Adaptor)
{
    Parameter ELEMENTTYPE="My.Container";
}
///
Class My.Container Extends (%RegisteredObject, %XML.Adaptor)
{
    Property PropertyA As %String;
    Property PropertyB As %String;
}
Product version: IRIS 2021.2
Discussion (1)1
Log in or sign up to continue

Hi Stella,

Thinking could this use the "List Of" syntax to achieve a collection for XML projection.

Service:

Class TEST.SOAPCOL.MyService Extends EnsLib.SOAP.Service
{ 
/// Name of the WebService.
Parameter SERVICENAME = "MyService"; /// TODO: change this to actual SOAP namespace.
/// SOAP Namespace for the WebService
Parameter NAMESPACE = "http://tempuri.org"; Property Target As Ens.DataType.ConfigName; Parameter SETTINGS = "Target:Basic";
Method SendToTarget(pRqst As TEST.SOAPCOL.Request) As TEST.SOAPCOL.Response [ SoapAction = "http://tempuri.org/Sample.MyService.SendToTarget", WebMethod ]
{
    set tResponse=##class(TEST.SOAPCOL.Response).%New()
    Set tSC= ..SendRequestAsync(..Target, pRqst)
    return tResponse
}
}

Request (Note "List Of" )

Class TEST.SOAPCOL.Request Extends Ens.Request
{
  Property MyContainer As list Of TEST.SOAPCOL.ListItem;
} 

Inner Items

Class TEST.SOAPCOL.ListItem Extends (%Persistent, %XML.Adaptor)
{
Property PropertyA As %String;
Property PropertyB As %String; 
}

Response:

Class TEST.SOAPCOL.Response Extends Ens.Response
{
}  

Projection seen in Message Trace:

<?xml version="1.0" ?>
<!-- type: TEST.SOAPCOL.Request  id: 1 -->
<Request>
  <MyContainer>
    <ListItem>
      <PropertyA>AAA
      </PropertyA>
      <PropertyB>BBB
      </PropertyB>
    </ListItem>
  </MyContainer>
</Request>

Trying out client code in terminal:

set o=##class(MyService.MyServiceSoap).%New()
set o.Location="http://localhost:1980/TEST.SOAPCOL.MyService.CLS"
set pRqst=##class(MyService.Request).%New()
set item=##class(MyService.ListItem).%New()
set item.PropertyA="AAA"
set item.PropertyB="BBB"
do pRqst.MyCOntainer.Insert(item)
set response=o.SendToTarget(pRqst)