在上一篇文章《Flex与.NET互操作(二):基于WebService的数据访问(上) 》中介绍了通过<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的数据访问就介绍到这里,由于个人能力有限,文中有不足之处还望大家指正。如果有什么好的建议也可以提出,大家相互讨论,学习,共同进步!!