ColdFusion Web Service (Returning a Complex Type)
Next we will return a ColdFusion query via a Web service, to a calling ASP.NET function. First let's create our CFC, which will contain the remote function (Listing 25.6).
Listing 25.6. NameService.cfc
The query executes the same query as our .NET Web service did. Remember, a data source must be created in the ColdFusion Administrator to connect to the Access database. It will return a complex type of QueryBean. A QueryBean is an object that contains a one-dimensional array of column names, and a two-dimensional array containing the associated data. This can be seen in the WSDL output associated with the GetNames function (Listing 25.7). Go to http://localhost/WebServices1/NameService.cfc?wsdl in the browser and analyze the resulting xml output.
<cfcomponent>
<cffunction access="remote"
name="GetNames"
output="false"
returntype="query"
displayname="GetNames"
hint="This function accepts a string filter and returns a query.">
<cfargument name="sFilter" type="string" required="true" />
<cfquery name="result" datasource="names">
SELECT *
FROM [names]
WHERE name LIKE '#sFilter#%'
</cfquery>
<cfreturn result>
</cffunction>
</cfcomponent>
Listing 25.7. WSDL output from NameServices.cfc
Now that the CFC has been created, we'll access it in ASP.NET and bind the resulting object to a DataGrid for display purposes. In Listing 25.8, the code to retrieve the QueryBean object and data can be seen at the beginning of the Page_Load method.
<complexType name="ArrayOf_xsd_string">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]" />
</restriction>
</complexContent>
</complexType>
<complexType name="ArrayOfArrayOf_xsd_anyType">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:anyType[][]" />
</restriction>
</complexContent>
</complexType>
<complexType name="QueryBean">
<sequence>
<element name="columnList" nillable="true" type="impl:ArrayOf_xsd_string" />
<element name="data" nillable="true" type="impl:ArrayOfArrayOf_xsd_anyType" />
</sequence>
</complexType>
Listing 25.8. NameDump.aspx.cs
[View full width]
Before we can create the initial objects containing the QueryBean data, a Web Reference must be created. This is done by clicking the Project tab in the VS.NET window and then clicking Add Web Reference in the drop-down list. The Add Web Reference interface is then displayed; it has a text box for you to supply the URL to the CFC (http://localhost/WebServices1/NameService.CFC?wsdl). Click the Go button; when the connection is successful, the service's methods are displayed. Enter a Reference name to use in code, click Add Reference, and you're ready to include the call to the Web service in your code (Figure 25.9).
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.U222Controls;
namespace WebServices1
{
public class NameDump : Page
{
protected DataGrid DataGrid1;
private void Page_Load(object sender, EventArgs e)
{
//Create the string filter to pass to the web service
string sFilter = "je";
//Reference the ColdFusion web service
GetNamesCFC.NameServiceService cfWs = new GetNamesCFC.NameServiceService();![]()
//Reference the QueryBean that ColdFusion returns from the web service
GetNamesCFC.QueryBean qBean = cfWs.GetNames(sFilter);
DataTable dTable = MakeTable(qBean.columnList);
object oData = new object();
DataRow row = null;
int iCount = 0;
//Add QueryBean data to the DataTable
for (int i=0;i<=qBean.data.Length-1;i++)
{
oData = qBean.data[i];
row = dTable.NewRow();
foreach(object oLoopData in ((Array)(oData)))
{
row[iCount] = oLoopData;
iCount = iCount + 1;
}
iCount = 0;
dTable.Rows.Add(row);
}
DataGrid1.DataSource = dTable;
DataBind();
}
private DataTable MakeTable(string[] sColumns)
{
//Make a table with all of the names from the array sColumns column
//list contained in the QueryBean
DataTable dTable = new DataTable("dTable");
DataColumn dColumn;
foreach(string columnName in sColumns)
{
dColumn = new DataColumn(columnName, Type.GetType("System.String"));
dTable.Columns.Add(dColumn);
}
return dTable;
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}
Figure 25.9. Add Web Reference Window.

Figure 25.10. Output from NameDump.aspx.

Interoperability through COM Callable Wrapper
ColdFusion continues to support a Component Object Model (COM) interface in ColdFusion 7, with its COM bridge capabilities provided by Intrinsyc's J-Integra interoperability software. J-Integra is instantiated through the <cfobject> tag or with <cfscript> utilizing the function createObject. In this next example, we'll expose our .NET assembly to ColdFusion via Microsoft's COM Callable Wrapper methodology. Figure 25.11 illustrates how ColdFusion and J-Integra hook into various automation components.
Figure 25.11. CF MX to J-Integra to COM hooks.

Figure 25.12. ColdFusion to Proxy to .NET.
[View full size image]
