Listing 1: Returning a structure to .NET

<!--- employee.cfc (definition cfc) -->
<cfcomponent>
<!--- 
 Declare a property for each key in
 an employee structure
--->
<cfproperty name="employeeId" type="string" />
<cfproperty name="firstname" type="string" />
<cfproperty name="lastname" type="string" />
</cfcomponent>

<!--- employeeService.cfc (Web Service) -->
<cfcomponent>
  <cffunction name="getEmployee" 
    returntype="employee" 
    access="remote">

    <cfset var employeeStruct = "">
    <cfset var employeeCfc = "">
    <cfset var i = "" />
    <!--- ColdFusion Structure --->
    <cfset employeeStruct = structNew()>
    <cfset employeeStruct.employeeId = "2">
    <cfset employeeStruct.firstname = "Isaac">
    <cfset employeeStruct.lastname = "Newton">

    <!--- Create and populate CFC --->
    <cfset employeeCfc = 
      createObject("component", "employee")>
    <cfloop collection="#employeeStruct#" item="i">
      <cfset employeeCfc[i] = employeeStruct[i] />
    </cfloop>

    <!--- Return the CFC --->
    <cfreturn employeeCfc>
  </cffunction>
</cfcomponent>

Listing 2: Sending an array of CFCs to .NET

<!--- employeeService.cfc --->
<cfcomponent>
  <cffunction name="getEmployeeArray" 
    returntype="array" 
    access="remote">

    <cfset var result = arrayNew(1) />

    <cfset result[1] = 
      createObject("component", "employee")>
    <cfset result[1].employeeId = "1">
    <cfset result[1].firstname = "Leonardo">
    <cfset result[1].lastname = "DaVinci">
 
    <cfset result[2] = 
      createObject("component", "employee")>
    <cfset result[2].employeeId = "2">
    <cfset result[2].firstname = "Isaac">
    <cfset result[2].lastname = "Newton">

    <cfreturn result />
  </cffunction>
</cfcomponent>

VB.NET Client:

employees = employeeService.getEmployeeArray ()
For Each myEmployee In employees
    Response.Write("<br />EmployeeId: " & myEmployee.employeeId)
    Response.Write("<br />Firstname: " & myEmployee.firstname)
    Response.Write("<br />Lastname: " & myEmployee.lastname & "<br />")
Next

Listing 3: XML a .NET DataSet can understand

<books>
  <book>
    <author>Forta, Ben</author>
    <title>SQL in 10 Minutes</title>
  </book>
  <book>
    <author>Ben-Gan & Moreau</author>
    <title>Advanced Transact-SQL</title>
  </book>
</books>

Listing 4: Returning a ColdFusion query to .NET

<!--- employeeService.cfc --->
<cfcomponent>
  <cffunction name="getEmployees" 
    returnType="string" 
    access="remote">
    <cfset var getEmployees = "" />
    
    <!--- Get our Employees --->
    <cfquery datasource="Northwind" 
      name="getEmployees">
      SELECT EmployeeID, FirstName, LastName
      FROM Employees
    </cfquery>
    
    <!--- Return XML string for this query --->
    <cfreturn toString(queryToXml(getEmployees)) />
  </cffunction>

  <!--- Builds XML from a CF Query --->
  <cffunction name="queryToXml" returnType="any">
    <cfargument name="inQuery" type="query">
    <cfset var result = "">
    <cfset var i = "">
    
    <cfxml variable="result">
    <recordset>
    <cfloop query="arguments.inQuery">
      <item>
      <cfloop 
        list="#arguments.inQuery.columnList#" 
        index="i">
        <cfoutput>
          <#i#>#arguments.inQuery[i][arguments.inQuery.currentRow]#</#i#>
        </cfoutput>
      </cfloop>
      </item>
    </cfloop>
    </recordset>
    </cfxml>

    <cfreturn result>
  </cffunction>
</cfcomponent>

VB.NET Client

Dim st As String
Dim dsOut As New DataSet

'Create XML Document from Result
ReturnDoc.LoadXml(employeeService.getEmployees())

'Create stream from XML Document
st = ReturnDoc.InnerXml
Dim io As New System.IO.StringReader(st)
Dim stream As New XmlTextReader(io)

'Create dataset from stream
dsOut.ReadXml(stream)

Listing 5: Consuming a .NET DataSet from ColdFusion

<!--- Utility function that converts a .NET dataset to a structure of queries --->
<cffunction name="convertDotNetDataset"
  returnType="struct">
  <cfargument name="dataset" required="true">
  
  <!--- Local Variables --->
  <cfset var result = structNew() />
  <cfset var aDataset = dataset.get_any() />
  <cfset var xSchema  = xmlParse(aDataset[1]) />
  <cfset var xTables = xSchema["xs:schema"]
    ["xs:element"]["xs:complexType"]["xs:choice"] />
  <cfset var xData  = xmlParse(aDataset[2]) />
  <cfset var xRows = xData["diffgr:diffgram"]
    ["NewDataSet"] />
  <cfset var tableName = "" />
  <cfset var thisRow = "" />
  <cfset var i = "" />
  <cfset var j = "" />

  <!--- Create Queries --->
  <cfloop from="1" 
    to="#arrayLen(xTables.xmlChildren)#" 
    index="i">
    <cfset tableName = xTables.xmlChildren[i].
      xmlAttributes.name />
    <cfset xColumns = xTables.xmlChildren[i].
      xmlChildren[1].xmlChildren[1].xmlChildren/>
    <cfset result[tableName] = queryNew("") />
    <cfloop from="1"
      to="#arrayLen(xColumns)#"
      index="j">
      <cfset queryAddColumn(result[tableName], 
        xColumns[j].xmlAttributes.name, 
        arrayNew(1)) />
    </cfloop>
  </cfloop>
  
  <!--- Populate Queries --->
  <cfloop from="1"
    to="#arrayLen(xRows.xmlChildren)#"
    index="i">
    <cfset thisRow = xRows.xmlChildren[i] />
    <cfset tableName = thisRow.xmlName />
    <cfset queryAddRow(result[tableName], 1) />
    <cfloop from="1"
      to="#arrayLen(thisRow.xmlChildren)#"
      index="j">
      <cfset querySetCell(result[tableName], 
        thisRow.xmlChildren[j].xmlName, 
        thisRow.xmlChildren[j].xmlText, 
        result[tableName].recordCount) />
    </cfloop>
  </cfloop>
  <cfreturn result>
</cffunction>

<!--- Invoke our Web Service --->
<cfinvoke 
  webservice="http://localhost/employee.asmx?WSDL"
  method="getEmployees"
  returnvariable ="result">

<!--- Convert result to CF queries --->
<cfset result = convertDotNetDataset(result) />

<!--- Display --->
<cfdump var="#result#" />

Listing 6:  XML a .NET DataSet can understand

<books>
  <book>
    <author>Forta, Ben</author>
    <title>SQL in 10 Minutes</title>
  </book>
  <book>
    <author>Ben-Gan & Moreau</author>
    <title>Advanced Transact-SQL</title>
  </book>
</books>

Listing 7:  Returning a ColdFusion query to .NET

<!--- employeeService.cfc --->
<cfcomponent>
  <cffunction name="getEmployees" 
    returnType="string" 
    access="remote">
    <cfset var getEmployees = "" />
    
    <!--- Get our Employees --->
    <cfquery datasource="Northwind" 
      name="getEmployees">
      SELECT EmployeeID, FirstName, LastName
      FROM Employees
    </cfquery>
    
    <!--- Return XML string for this query --->
    <cfreturn toString(queryToXml(getEmployees)) />
  </cffunction>

  <!--- Builds XML from a CF Query --->
  <cffunction name="queryToXml" returnType="any">
    <cfargument name="inQuery" type="query">
    <cfset var result = "">
    <cfset var i = "">
    
    <cfxml variable="result">
    <recordset>
    <cfloop query="arguments.inQuery">
      <item>
      <cfloop 
        list="#arguments.inQuery.columnList#" 
        index="i">
        <cfoutput>
          <#i#>#arguments.inQuery[i][arguments.inQuery.currentRow]#</#i#>
        </cfoutput>
      </cfloop>
      </item>
    </cfloop>
    </recordset>
    </cfxml>

    <cfreturn result>
  </cffunction>
</cfcomponent>

VB.NET Client

Dim st As String
Dim dsOut As New DataSet

'Create XML Document from Result
ReturnDoc.LoadXml(employeeService.getEmployees())

'Create stream from XML Document
st = ReturnDoc.InnerXml
Dim io As New System.IO.StringReader(st)
Dim stream As New XmlTextReader(io)

'Create dataset from stream
dsOut.ReadXml(stream)

Listing 8:  Consuming a .NET DataSet from ColdFusion

<!--- Utility function that converts a .NET dataset to a structure of queries --->
<cffunction name="convertDotNetDataset"
  returnType="struct">
  <cfargument name="dataset" required="true">
  
  <!--- Local Variables --->
  <cfset var result = structNew() />
  <cfset var aDataset = dataset.get_any() />
  <cfset var xSchema  = xmlParse(aDataset[1]) />
  <cfset var xTables = xSchema["xs:schema"]
    ["xs:element"]["xs:complexType"]["xs:choice"] />
  <cfset var xData  = xmlParse(aDataset[2]) />
  <cfset var xRows = xData["diffgr:diffgram"]
    ["NewDataSet"] />
  <cfset var tableName = "" />
  <cfset var thisRow = "" />
  <cfset var i = "" />
  <cfset var j = "" />

  <!--- Create Queries --->
  <cfloop from="1" 
    to="#arrayLen(xTables.xmlChildren)#" 
    index="i">
    <cfset tableName = xTables.xmlChildren[i].
      xmlAttributes.name />
    <cfset xColumns = xTables.xmlChildren[i].
      xmlChildren[1].xmlChildren[1].xmlChildren/>
    <cfset result[tableName] = queryNew("") />
    <cfloop from="1"
      to="#arrayLen(xColumns)#"
      index="j">
      <cfset queryAddColumn(result[tableName], 
        xColumns[j].xmlAttributes.name, 
        arrayNew(1)) />
    </cfloop>
  </cfloop>
  
  <!--- Populate Queries --->
  <cfloop from="1"
    to="#arrayLen(xRows.xmlChildren)#"
    index="i">
    <cfset thisRow = xRows.xmlChildren[i] />
    <cfset tableName = thisRow.xmlName />
    <cfset queryAddRow(result[tableName], 1) />
    <cfloop from="1"
      to="#arrayLen(thisRow.xmlChildren)#"
      index="j">
      <cfset querySetCell(result[tableName], 
        thisRow.xmlChildren[j].xmlName, 
        thisRow.xmlChildren[j].xmlText, 
        result[tableName].recordCount) />
    </cfloop>
  </cfloop>
  <cfreturn result>
</cffunction>

<!--- Invoke our Web Service --->
<cfinvoke 
  webservice="http://localhost/employee.asmx?WSDL"
  method="getEmployees"
  returnvariable ="result">

<!--- Convert result to CF queries --->
<cfset result = convertDotNetDataset(result) />

<!--- Display --->
<cfdump var="#result#" />