解决方法
这个解决方法是WebORB发布的一个第三方的插件,它提供了Flex/AIR和.NET之间的无缝集成。
问题
Flash Builder 4引入了一些非常不错的插件,使得开发者可以用Flex/AIR与Java、PHP、Web Services等进行集成开发。问题是它并没有一个可以与.NET进行集成开发的插件。
详细介绍
开始
首先,为.NET下载和安装WebORB 4。WebORB的安装包括了Flash Builder插件的安装程序,这个安装程序位于安装根目录下的 /integration/flashbuilder。
如果Flash Builder正在运行,确认在安装插件程序之前把它关掉。安装完插件之后,打开Flash Builder。你可以通过打开Data菜单来确认你是否成功安装插件。Data菜单下应该有一个"Connect to WebORB for .NET..."子菜单项,如下图所示:
项目设置
新建一个Flash Builder项目,把server-type设置为ASP.NET,详细操作请浏览Introduction to Flex 4 and .NET integration (Setting up Flash Builder Project with WebORB section)。插件将会使用项目配置文件中的服务器地址。
使用Data/Services插件
在使用插件之前请先确认在Flex Package Explorer中选中了该项目。如果没有项目被选中,Flash Builder会显示这样的错误信息:"No Flex project is active. Please select a project in Flex Package Explorer"。为了使用该插件,打开Data菜单并选择"Connect to WebORB for .NET..."。Flash Builder会弹出一个对话框,如下图所示:
插件会从选中的项目的窗口获取服务器的URL。这个URL标识了服务器地址和在WebORB安装目录下的一个虚拟目录。选择"No password required"复选框并选择OK继续下一步。(这篇文章稍后将会介绍如何配置WebORB的权限,使得用户在使用插件时需要认证)。
下一步这个插件连接到WebORB服务器并且加载一个可用的远程目的地的列表。一个目的地是抽象的概念,它将一个.NET的类映射到一个逻辑名称。Flex客户通过连接目的地能够与服务器端的类进行通信。这些目的地必须在WEB-INF/flex/remoting-config.xml中声明。
插件将会显示一组目的地列表,如下图所示:
你可以在WEB-INF/flex/remoting-config.xml中添加新的目的地,但是必须重新启动ASP.NET进程或者WebORB正在运行的应用程序池。
这篇文章使用了一个.NET的类作为例子,它可以从数据库中读取数据并将数据返回给Flex。这个类的源码如下:
- using System;
- using System.Collections;
- using System.Text;
- using System.Data;
- using System.Data.OleDb;
- using System.Web;
- using System.Collections.Generic;
- namespace Weborb.Examples
- {
- public class DataBinding
- {
- private static string connectionString = "connectin string goes here";
- public DataTable getCustomers()
- {
- DataTable dataTable = new DataTable();
- OleDbConnection connection = new OleDbConnection( connectionString );
- OleDbDataAdapter adapter = new OleDbDataAdapter();
- adapter.SelectCommand = new OleDbCommand( "SELECT * FROM Customers order by CUSTOMERID", connection );
- try
- {
- adapter.Fill( dataTable );
- }
- finally
- {
- connection.Close();
- }
- return dataTable;
- }
- // This method is invoked when the user updates a record using the form
- public void updateCustomer( Hashtable updatedCustomerRecord )
- {
- // removed for sample brevity
- }
- // This method is invoked when the user updates a record directly in the datagrid
- public bool updateCustomerProperty( Hashtable originalCustomerRecord, String changedFieldName, String newValue )
- {
- // removed for sample brevity
- }
- }
- }
找到并选择DataQueryService目的地的复选框。位于在窗体下部的"Service details"组包含有两个客户端包名的字段。选择完成来为选中的目的地生成ActionScript代码(注意你可以一次选择多个目的地)。当Flash Builder完成代码创建的时候,在Data/Services面板将会显示刚才添加的服务,如下图所示:
现在服务已经添加到了项目中,你需要为函数配置好返回类型和参数类型。选择getCustomers():Object函数,右键单击并选择Configure Return Type...,如下图所示:
在"Configure Return Type"窗口中,保持默认选项(自动从样本数据中检测出返回的数据的类型)。选择下一步。Flash Builder调用getCustomers()函数。服务器端返回数据的类型是System.Data.DataTable,它里面包含了一条从数据库读取出来的记录的列表。WebORB默认会把DataTable对象序列化成一个数组,数组由没有确定类型的对象组成。当Flash Builder接收到返回值之后,它不能检测出数组中的对象的类型并且弹出一个如下图所示的窗口。输入"Customer"作为类的名称并点击完成,操作如下图所示:
Flash Builder创建Customer数据类型及其属性。你可以在Data/Services面板展开Data Types结点来查看是否创建成功:
生成服务调用
现在操作和数据类型都已经配置好了,调用服务的过程非常简单。在项目中打开一个MXML文件。在Data/Services中右键单击"getCustomers():Customer[]"并选择"Generate Service Call"。Flash Builder将代码添加到选中的MXML应用程序中。特别地,添加的代码由3个元素组成:
服务声明:
- <services:DataQueryService id="dataQueryService"
- fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
- showBusyCursor="true"/>
调用Responder--用来存放最后一次调用服务的结果:
- <s:CallResponder id="getCustomersResult"/>
调用服务的函数:
- protected function getCustomers():void
下一步是添加一个data grid组件到MXML中并且将它写到服务调用之中。将下面的语句添加到<s:Application>的闭合标签之前。
- <mx:DataGrid dataProvider="{getCustomersResult.lastResult}" left="20" right="20" top="20"/>
保存并运行程序。你将在data grid中看到一组从数据库获取的数据:
当你运行Flex程序的时候,你可能会遇到下面的错误提示:
"MessagingError message='Destination 'DataQueryService' either does not exist or the destination has no channels defined (and the application does not define any default channels.)']
不能建立连接到"DataQueryService"。
出现这个错误的原因是该项目没有在compiler properties中添加WEB-INF/flex/services-config.xml的引用。具体请查看the instructions on how to reference services-config.xml in the compiler properties。