Following my last piece on Flex and .NET web services I will show how to use datasets and Flex. Some folks have reported issues when working with datasets and Flex. Macromedia's Mike Downey reports that Flash has no support for datasets but you must instead use object arrays.
In keeping with the previous article lets translate Mikes C# code into VB.NET
Imports System
Imports System.Web.Services
Public Class Employee
Public name As String
Public department As Integer
End Class
<WebServiceAttribute(Namespace:="http://services.r.us/", Description:="Access the Employee database")> _
Public Class Employees
<WebMethodAttribute(Description:="Get a list of employees")> _
Public Function getEmployees() As Employee()
Dim employees As Employee() = New Employee(1){}
employees(0) = New Employee()
employees(0).name = "Bob"
employees(0).department = 123
employees(1) = New Employee()
employees(1).name = "Mary"
employees(1).department = 456
Return employees
End Function
End Class
If we run this code we get
Note that the serialized object array structure is a much simpler model than a serialized dataset (this means less issues with aggregating our SOAP packet). However note that they have been some reports of multi dimension arrays not serializing correctly, this could lead to data loss or corruption in your SOAP packets. Lets try our own example, here we will query the SQL Server pubs database and convert the dataset to an object array.
Public Class TitleInfo
Public strTitleName As String
End Class
<WebMethod()> _
Public Function GetTitleData() As TitleInfo()
Try
'create dataset
Dim dsTitleData As New DataSet
'create connection
Dim objCon As SqlConnection = New SqlConnection("server=localhost;uid=sa;pwd=;database=pubs")
'create data adapter
Dim cmdSQL As SqlDataAdapter = New SqlDataAdapter("select top 5 title from titles", objCon)
'fill dataset using data adapter
cmdSQL.Fill(dsTitleData, "titles")
'create object array, using row count as upper dim
Dim objTitles As TitleInfo() = New TitleInfo(dsTitleData.Tables(0).Rows.Count - 1) {}
'loop through dataset to add data to object array
Dim intRsCount As Int16
For intRsCount = 0 To dsTitleData.Tables(0).Rows.Count - 1
objTitles(intRsCount) = New TitleInfo
objTitles(intRsCount).strTitleName = dsTitleData.Tables(0).Rows(intRsCount)("title")
Next
'return object array
Return objTitles
Catch exp As Exception
Throw
End Try
End Function
This function does a simlar job to the code Mike showed, it connects to the database, obtains the data and creates the dataset. We then loop through the dataset to populate the object array and return the object array. I have not included any error checking (other than the Try-Catch) to keep the code simple, you would normally want to add error checking (for example our array depends on a row count to get its size). The resulting SOAP packet is as follows.
To get at this data in Flex we can now get at the data using a standard web service call
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" width="600" height="450">
<mx:WebService id="TestApp" wsdl="http://localhost/test/test.asmx?WSDL" showBusyCursor="true" fault="alert(event.fault.faultstring)">
<mx:operation name="GetTitleData">
</mx:operation>
</mx:WebService>
<mx:VBox>
<mx:Button click="TestApp.GetTitleData.send()"></mx:Button>
<mx:DataGrid dataProvider="{TestApp.GetTitleData.result}" widthFlex="1">
<mx:columns>
<mx:Array>
<mx:DataGridColumn columnName="strTitleName" headerText="Title Name"/>
</mx:Array>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
Here we populate a datagrid from the strTitleName field in our object array when the button event fires. Nore that the datagrid provider points to our web service function (GetTitleData) and the columnname points to the strTitleName field (if you have more fields in your object array you could add more fields in your datagrid etc).