本文以.NET平台下C#语言开发的WebService作为远程数据源,详细介绍Flex与.NET的 WebService的数据通信知识点;包括连接WebService,远程调用WebService方法,给WebService方法传递参数等相关知 识点。三个标签的使用方法基本上是一样,这里就以标签为例进行介绍。
Flex提供了、和标签来直接访问远程数据,这用于与各种不同语言环境开发提供的远程服务端数据源(如WebService)进行数据交互通信显得更加容易.
本文以.NET平台下C#语言开发的WebService作为远程数据源,详细介绍Flex与.NET的WebService的数据通信知识 点;包括连接WebService,远程调用WebService方法,给WebService方法传递参数等相关知识点。三个标签的使用方法基本上是一 样,这里就以标签为例进行介绍。
首先看看如下代码块:
?
1?????internal?function?onClick():void 2?????{ 3?????????var?service:WebService?=?new?WebService(); 4?????????service.loadWSDL("[url]http://localhost:1146/FlashFlexService.asmx?wsdl[/url]"); 5?????????service.addEventListener(ResultEvent.RESULT,onResult); 6?????????service.addEventListener(FaultEvent.FAULT,onFault); 7?????????service.GetBook(); 8?????}
|
?wsdl属性指定到要访问的WebService的wsdl地址既可,其中定义了两个操作标签(),分别对应于WebService中定义的WebMethod方法。result属性标记访问WebService方法成功后的处理函数;fault则相反,指定于访问失败的处理函数。以上两个对应于WebService的WebMethod方法如下:
?
1?????///?<summary> ?2?????///?返回字符串 ?3?????///?</summary> ?4?????///?<returns></returns> ?5?????[WebMethod] ?6?????public?string?HelloWorld() ?7?????{ ?8?????????return?"Hello?World"; ?9?????} 10? 11?????///?<summary> 12?????///?返回一个简单对象 13?????///?</summary> 14?????///?<returns></returns> 15?????[WebMethod] 16?????public?Book?GetBook() 17?????{ 18?????????return?new?Book 19?????????{ 20?????????????Id?=?1, 21?????????????Name?=?"三国演义", 22?????????????Author?=?"罗贯中", 23?????????????Price?=?100 24?????????}; 25?????}
如上便是WebService方法定义和在Flex的客户端(mxml)通过标签来访问WebService的完整流程,下面我们来看看在Flex的客户端怎么去调用WebService所定义的方法:
?
?
1?<mx:.>
2?<![CDATA[
3?import?mx.controls.Alert; 4?import?mx.rpc.events.FaultEvent; 5?import?mx.rpc.events.ResultEvent; 6 7? 10?internal?function?onRequest():void 11?{ 12?dataService.HelloWorld(); 13?} 14 15? 18?internal?function?onSuccess(evt:ResultEvent):void 19?{ 20?Alert.show(evt.result.toString()); 21?} 22 23 24? 27?internal?function?onFault(evt:FaultEvent):void 28?{ 29?Alert.show("访问WebService失败!"); 30?} 31?]]> 32?</mx:.>
通过上面的调用,就可以完成一个Flex和.NET WebService的交互。当然我们在Flash/Flex的客户端调用WebService也是可以传递参数的,如下WebService的WebMethod定义:
?
1?///?///?<summary>
2?///?将传递进来的参数转化为大写字符返回 3?///?///?</summary>
4?///?///?<param?name="value"></param>
5?///?///?<returns></returns>
6?[WebMethod] 7?public?string?ConvertToUpper(string?value) 8?{ 9?return?value.ToUpper(); 10?}
通过在标签下配置执行该方法就可以访问了,如下:
?
??????1? 4?internal?function?onRequest():void 5?{ 6?//dataService.HelloWorld(); 7?dataService.ConvertToUpper("abcdefg"); 8?}
另外,我们还可以通过来传递参数,这里只需要知道里的参数配置与WebService提供的WebMethod方法参数同名就OK。
回到前面看看WebService的方法定义,其中一个方法GetBook是返回的一个Book对象,如果是返回的对象我们在Flex的客户端怎么来获取这个对象的值呢?详细见如下代码示例:
?
?????1?internal?function?onObject():void 2?{ 3?dataService.GetBook(); 4?} 5 6?internal?function?onObjectSuccess(evt:ResultEvent):void 7?{ 8?//直接通过事件的result属性得到返回值,然后直接访问属性便OK 9?Alert.show(evt.result.Name); 10?} 11 12? 15?internal?function?onFault(evt:FaultEvent):void 16?{ 17?Alert.show("访问WebService失败!"); 18?}
如上便完成了服务端的WebService返回对象到客户端的调用。
在上一篇文章《Flex与.NET互操作(二):基于WebService的数据访问(上) 》中介绍了通过标签来访问Webservice。实际上我们也可以通过编程的方式动态的访问WebService,Flex SDK为我们提供了WebService类。
在上一篇文章《Flex与.NET互操作(二):基于WebService的数据访问(上) 》中介绍了通过标签来访问Webservice。实际上我们也可以通过编程的方式动态的访问WebService,Flex SDK为我们提供了WebService类。
使用WebService类来访问WebService其实也就是将标签的属性通过类对象的属性形式来表示,相比之下使用WebService类比使用标签要灵活。下面我们来看看编程方式怎么连接和调用远程方法:
?
1?internal?function?onClick():void 2?{ 3?var?service:WebService?=?new?WebService(); 4?service.loadWSDL("[url]http://localhost:1146/FlashFlexService.asmx?wsdl[/url]"); 5?service.addEventListener(ResultEvent.RESULT,onResult); 6?service.addEventListener(FaultEvent.FAULT,onFault); 7?service.GetBook(); 8?}
直接通过类对象的loadWSDL()方法调用远程WebService,动态为类对象指定相关的处理函数,然后和标签一样调用远程WebService方法既可。
1?internal?function?onResult(evt:ResultEvent):void 2?{ 3?Alert.show(evt.result.Id); 4?} 5 6?internal?function?onFault(evt:FaultEvent):void 7?{ 8?Alert.show(evt.fault.faultDetail.toString()); 9?}
|
如上便完成了使用WebService类通过编程的方式访问远程WebService方法的调用。
下面来看看WebService返回DataTable等负责类型,在Flex客户端该怎么解析。首先定义WebService方法如下:
1?[WebMethod(Description="该方法将返回DataTable类型的数据")]
2?public?DataTable?GetDataTable()
3?{
4?DataTable?dt?=?new?DataTable("Books");
5?dt.Columns.Add("Id",?typeof(int));
6?dt.Columns.Add("Name",?typeof(string));
7?dt.Columns.Add("Author",?typeof(string));
8?dt.Columns.Add("Price",?typeof(double));
9
10?DataRow?dr?=?dt.NewRow();
11?dr["Id"]?=?1;
12?dr["Name"]?=?"《Flex游戏开发》";
13?dr["Author"]?=?"张三";
14?dr["Price"]?=?54.85;
15?dt.Rows.Add(dr);
16
17?dr?=?dt.NewRow();
18?dr["Id"]?=?2;
19?dr["Name"]?=?"《Flash游戏开发》";
20?dr["Author"]?=?"李四";
21?dr["Price"]?=?65.50;
22?dt.Rows.Add(dr);
23
24?return?dt;
25?}
同样在Flex客户端通过WebService来访问就可以了,下面是使用标签访问(这里需要注意,标签的name必须与服务端的WebService方法同名):
1?????<mx:WebService?id="myService"?
2?????????wsdl="[url]http://localhost:1146/DataWebService.asmx?wsdl[/url]"?useProxy="false">
3?????????<mx:operation?name="GetDataTable">
4?????????</mx:operation>
5?????</mx:WebService>
?????提供好了WebService,客户端也连接上了WebService,现在只差调用WebService提供的远程方法了。如下:
1?internal?function?onTable():void
2?{
3?myService.addEventListener(ResultEvent.RESULT,onSuccess);
4?myService.addEventListener(FaultEvent.FAULT,onFault);
5?myService.GetDataTable.send();
6?}
7
8?internal?function?onSuccess(evt:ResultEvent):void
9?{
10?//bookGrid.dataProvider=this.myService.GetDataTable.lastResult.Tables.Books.Rows;
11?}
12
13?internal?function?onFault(evt:FaultEvent):void
14?{
15?Alert.show("调用WebService方法失败,详细:"?+?evt.fault.faultDetail.toString());
16
17?}
将WebService的返回值绑定在Flex的DataGrid组件,mxml的相关代码如下:
<mx:Panel?x="41"?y="123"?width="480"?height="279"?layout="absolute"?fontSize="12">
?2?????<mx:DataGrid?x="10"?y="10"?width="436"?id="bookGrid"?
?3?????????dataProvider="{this.myService.GetDataTable.lastResult.Tables.Books.Rows}">
?4?????????<mx:columns>
?5?????????????<mx:DataGridColumn?headerText="编号"?dataField="Id"/>
?6?????????????<mx:DataGridColumn?headerText="书名"?dataField="Name"/>
?7?????????????<mx:DataGridColumn?headerText="作者"?dataField="Author"/>
?8?????????????<mx:DataGridColumn?headerText="价格"?dataField="Price"/>
?9?????????</mx:columns>
10?????</mx:DataGrid>
11?????<mx:ControlBar>
12?????????<mx:Button?label="DataTable"?click="onTable()"/>
13?????</mx:ControlBar>
14?</mx:Panel>
通过DataGrid的dataProvider属性绑定 DataGrid组件的数据源,除了直接通过"{}"绑定表达式帮定外我们也可以在调用远程方法成功的处理函数里给DataGrid指定数据源,见上面代 码中注释的代码部分。{this.myService.GetDataTable.lastResult.Tables.Books.Rows}表示将远 程WebService方法GetDataTable()的返回结果(DataTable)的所有行作为数据源与DataGrid组件进绑定,其中 Books为数据源DataTable的name,详细见前面WebService方法的定义出。程序运行结果如下图:
DataSet,DataTable相比泛型集合来说,性能上有很大的差距,复杂的序列化和反序列化过程也很负责,自从.net 2.0推出泛型到现在,我一直就比较喜欢用泛型来传递大数据。OK,下面我将介绍下在Flex中怎么去处理WebService方法返回的泛型集合数据。 我们有如下WebService方法定义:
1?[WebMethod(Description="该方法返回泛型集合")]
2?public?List?BookList()
3?{
4?return?new?List
5?{
6?new?Book
7?{
8?Id?=?1,
9?Name?=?"《Flex游戏开发》",
10?Author?=?"张三",
11?Price?=?54.85
12?},
13?new?Book
14?{
15?Id?=?1,
16?Name?=?"《Flash游戏开发》",
17?Author?=?"李四",
18?Price?=?65.50
19?}
20?};
21?}
相比DataSet,DataTable类型,使用List<>返回数据我个人认为更方面容易处理。我们直接在WebService的调试环境下测试返回List<>的WebService方法可以看到如下结果:
这就是以泛型结合(List<>)的形式返回的数据形式,相比DataTable的返回结果更为简洁,明了。话说到此,我们在 Flex下该怎么去获取这个返回值和处理这个值呢?其实这里已经很清楚的展现了我们可以通过什么方式去处理,仔细看上图会发 现"ArrayOfBook"????这是什么东西?莫非是在客户端可以通过数组的形式得到这个返回值。为了进一步搞清楚这里面的的点点滴滴,我们需要深 入到内部去了解下返回值的具体构造,通过Flex Builder的调试环境可以得到如下信息:
看清楚了吗?BookList方法的lastResult结构集下有两个对象,点开节点可知正是我们通过List返回的两个 Book对象,而lastResult的类型是:mx.collections.ArrayCollection,这不真是ActionScript中的 数组集合吗?好的,既然这样,在Flex客户端便可以直接通过lastResult得到WebService返回的泛型集合数据了。如下代码块:
1?internal?function?onTable():void
2?{
3?myService.addEventListener(ResultEvent.RESULT,onFault);
5?myService.BookList.send();
6?}
7
8?internal?function?onSuccess(evt:ResultEvent):void
9?{
10?var?arrC:ArrayCollection?=?this.myService.BookList.lastResult?as?ArrayCollection;
11?bookGrid.dataProvider=arrC;
12?}
13
14?internal?function?onFault(evt:FaultEvent):void
15?{
16?Alert.show("调用WebService方法失败,详细:"?+?evt.fault.faultDetail.toString());
17
18?}
对应的mxml代码如下(运行结果和上面返回DataTable类型一样):
?1???mx:Panel?x="41"?y="123"?width="480"?height="279"?layout="absolute"?fontSize="12"> ?2?????<mx:DataGrid?x="10"?y="10"?width="436"?id="bookGrid"> ?3?????????<mx:columns> ?4?????????????<mx:DataGridColumn?headerText="编号"?dataField="Id"/> ?5?????????????<mx:DataGridColumn?headerText="书名"?dataField="Name"/> ?6?????????????<mx:DataGridColumn?headerText="作者"?dataField="Author"/> ?7?????????????<mx:DataGridColumn?headerText="价格"?dataField="Price"/> ?8?????????</mx:columns> ?9?????</mx:DataGrid> 10?????<mx:ControlBar> 11?????????<mx:Button?label="DataTable"?click="onTable()"/> 12?????</mx:ControlBar> 13?</mx:Panel>