在上一篇文章《 》中介绍了通过<mx:WebService>标签来访问Webservice。实际上我们也可以通过编程的方式动态的访问WebService,Flex SDK为我们提供了WebService类。
使用WebService类来访问WebService其实也就是将<mx:WebService>标签的属性通过类对象的属性形式来表示,相比之下使用WebService类比使用<mx:WebService>标签要灵活。下面我们来看看编程方式怎么连接和调用远程方法:
1 internal function onClick(): void
2 {
3 var service:WebService = new WebService();
4 service.loadWSDL( " http://localhost:1146/FlashFlexService.asmx?wsdl " );
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来访问就可以了,下面是使用<mx:WebServive>标签访问(这里需要注意,<mx:operation>标签的name必须与服务端的WebService方法同名):
1 < mx:WebService id = " myService "
2 wsdl = " http://localhost:1146/DataWebService.asmx?wsdl " 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的相关代码如下:
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 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 < Book > BookList()
3 {
4 return new List < Book >
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>返回的两个Book对象,而lastResult的类型是:mx.collections.ArrayCollection,这不真是ActionScript中的数组集合吗?好的,既然这样,在Flex客户端便可以直接通过lastResult得到WebService返回的泛型集合数据了。如下代码块:
1 internal function onTable(): void
2 {
3 myService.addEventListener(ResultEvent.RESULT,onSuccess);
4 myService.addEventListener(FaultEvent.FAULT,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 >
关于WebService的数据访问就介绍到这里,由于个人能力有限,文中有不足之处还望大家指正。如果有什么好的建议也可以提出,大家相互讨论,学习,共同进步!!
版权说明
本文属原创文章,欢迎转载,其版权归作者和博客园共有。
作 者:Beniao
文章出处: