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
 <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> 

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.

Listing 25.7. WSDL output from NameServices.cfc
 <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> 

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.

Listing 25.8. NameDump.aspx.cs

[View full width]

 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.UI.HtmlControls; 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   } } 

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).

Figure 25.9. Add Web Reference Window.


Looking over the code, you can see that the filter, the Web service reference, and the dynamically generated DataTable are created in the Page_Load method of the NameDump.aspx page. The DataTable is initially created by passing the columnList array to the MakeTable method. The returned DataTable is populated by looping over the data array associated with the QueryBean. Lastly, the DataGrid is bound to the DataTable. If you browse to NameDump.aspx, you will see the resulting output (Figure 25.10).

Figure 25.10. Output from NameDump.aspx.


NOTE

It is important to understand that when retrieving any complex type from a Web service call, ColdFusion will expose get methods to reference them in code. These methods are exposed by using <cfdump> to expose the initial result returned from the Web service. You may have to take out a magnifying glass to examine the WSDL associated with the Web service, but this can prove to be quite entertaining, especially if you are a Sherlock Holmes or James Bond zealot.


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.


You may be asking yourself what really goes on behind the scenes when a call is made to a .NET assembly through COM. First, a brief description on .NET languages and COM will help in understanding this advanced concept.

.NET languages are compiled into an intermediary language called Microsoft Intermediate Language (MSIL). Like Java, MSIL runs in the CLR. The CLR provides a hidden proxy allowing .NET assemblies to be called from COM clients; it's called the COM Callable Wrapper (CCW). Through the CCW, ColdFusion is able to indirectly interface with a .NET assembly (Figure 25.12).

Figure 25.12. ColdFusion to Proxy to .NET.




Advanced Macromedia ColdFusion MX 7 Application Development
Advanced Macromedia ColdFusion MX 7 Application Development
ISBN: 0321292693
EAN: 2147483647
Year: 2006
Pages: 240
Authors: Ben Forta, et al

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net