Casting from JSON to Dictionary to CDT, array entries are null

I have a REST service that returns JSON which is converted to Dictionary by the integration.  I have CDTs I have imported from the service WSDL (so the property names exactly match the JSON names).  The problem is that array properties are left null instead of being populated.

I'm trying to convert it this way.... with a single call to cast of the top-level node.

  /*local!rawData: rule!SH_GetLibraryIntegration(libraryName: ri!libraryName) */
  local!rawData: a!fromJson(
    "{""GetLibraryResult"":{""Name"":""Uptown Public Library"",""HeadLibrarian"":""Kathlyn Walton"",""Books"":[{""Author"":""Fyodor Dostoevsky"",""Title"":""Crime and Punishment"",""IsCheckedOut"":false,""DueDate"":null},{""Author"":""Charles Dickens"",""Title"":""A Tale of Two Cities"",""IsCheckedOut"":true,""DueDate"":""01-10-2021""}]}}"
  ),
  fn!cast(
    'type!{http://schemas.datacontract.org/2004/07/TestService}Library',
    local!rawData.GetLibraryResult
  )

However, The "books" (in my example) are null and did not make it into the CDT.

I found a way to do this by converting the dictionary to individual maps, property by property, and then to a CDT.  However, this is really ugly and tedious.  

  /*local!rawData: rule!SH_GetLibraryIntegration(libraryName: ri!libraryName) */
  local!rawData: a!fromJson(
    "{""GetLibraryResult"":{""Name"":""Uptown Public Library"",""HeadLibrarian"":""Kathlyn Walton"",""Books"":[{""Author"":""Fyodor Dostoevsky"",""Title"":""Crime and Punishment"",""IsCheckedOut"":false,""DueDate"":null},{""Author"":""Charles Dickens"",""Title"":""A Tale of Two Cities"",""IsCheckedOut"":true,""DueDate"":""01-10-2021""}]}}"
  ),
  fn!cast(
    'type!{http://schemas.datacontract.org/2004/07/TestService}Library',
    a!map(
      Books: fn!cast(
        'type!{http://schemas.datacontract.org/2004/07/TestService}ArrayOfBook',
        a!map(
          Book: a!forEach(
            items: local!rawData.GetLibraryResult.Books,
            expression: fn!cast(
              'type!{http://schemas.datacontract.org/2004/07/TestService}Book',
              fv!item
            )
          )
        ) 
      ),
      Name: local!rawData.GetLibraryResult.Name,
      HeadLibrarian: local!rawData.GetLibraryResult.HeadLibrarian,
    )
  )

My real service has a very large JSON object (300+ classes in the web service) and many, many array-based properties.  This will be exceedingly tedious and error prone to convert to a CDT through map-cast method above.

Is there a better way to do this conversion?

  Discussion posts and replies are publicly visible

Parents
  • 0
    Certified Lead Developer

    Can you post a screenshot of the CDT configuration?

  • Here are the CDTs.  These were imported from a DotNet web service's WSDL.

    Here is a fragment from the WSDL that defines these.

    		<xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/TestService" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/TestService">
    			<xs:complexType name="Library">
    				<xs:sequence>
    					<xs:element minOccurs="0" name="Books" nillable="true" type="tns:ArrayOfBook"/>
    					<xs:element minOccurs="0" name="HeadLibrarian" nillable="true" type="xs:string"/>
    					<xs:element minOccurs="0" name="Name" nillable="true" type="xs:string"/>
    				</xs:sequence>
    			</xs:complexType>
    			<xs:element name="Library" nillable="true" type="tns:Library"/>
    			<xs:complexType name="ArrayOfBook">
    				<xs:sequence>
    					<xs:element minOccurs="0" maxOccurs="unbounded" name="Book" nillable="true" type="tns:Book"/>
    				</xs:sequence>
    			</xs:complexType>
    			<xs:element name="ArrayOfBook" nillable="true" type="tns:ArrayOfBook"/>
    			<xs:complexType name="Book">
    				<xs:sequence>
    					<xs:element minOccurs="0" name="Author" nillable="true" type="xs:string"/>
    					<xs:element minOccurs="0" name="DueDate" nillable="true" type="xs:dateTime"/>
    					<xs:element minOccurs="0" name="IsCheckedOut" type="xs:boolean"/>
    					<xs:element minOccurs="0" name="Title" nillable="true" type="xs:string"/>
    				</xs:sequence>
    			</xs:complexType>
    			<xs:element name="Book" nillable="true" type="tns:Book"/>
    		</xs:schema>
    

  • +1
    Certified Lead Developer
    in reply to stevenh6272

    Hm ... this seems a bit weird. Why is there a books field which is of a type that has only one field "book" which is a list of books.

    I understand that the provided JSON does not cast to this structure.

    To understand what is going on, create a data structure using the CDT types and turn that into JSON to spot the difference.

Reply Children