Author: 冯峰
Date: 2008年2月20日
在前一篇文章《.Net Compact Framework 3.5对 Linq的支持》中,主要介绍了对 Linq的一些使用,这篇文章将介绍另一大 .Net CF3.5的新特性 --对 WCF的支持。
随着微软 WCF的逐步推广,越来越多的系统都将会采用 WCF作为数据交互,如果在移动设备上还单纯的保留原先的对 Web Service的支持,将使得企业不得不面临保留原先 Web Service接口,再开发基于 WCF的接口,保留 2套,多费事。现在都采用 WCF之后,企业只需要将原先基于 Web Service升级到 WCF即可。省事 ~~。
废话不多说了,开始介绍如何在 .Net CF3.5中使用 WCF吧。
开发环境: VS2008+Windows Mobile 5.0 PPC
首先创建一个空的 Web Site,然后添加一个 WCF Service文件, VS2008会自动创建一个 IService.cs和 Service.cs,修改这 2个文件,来定义 OperationContract及 DataContract。具体如何开发 WCF,文章最后会有推荐文章。
在 WCF中,将实现 2个功能,一个测试功能(传入 2个 int数,返回 2数相加),另一个返回一个 List泛型数组,存放数据。最初写该 Demo时,我返回的是 DataTable类型,但 DataTable类型并不是 WCF所建议使用的。稍后会有说明。
WCF写完后,就需要对 web.config进行设置。我用的是 WCF Configuration工具,在 web.config文件右键, Open With中可以添加该工具。通过该工具可以很方便的配置完一个 WCF。
启动后效果如下:
接着开发客户端,创建一个 WM5.0的一个工程,选择 .Net CF3.5。在界面上放置一个 DataGrid,将 WCF传来的数组绑定到该 DataGrid中。客户端比较简单,关键在调用 WCF的地方。
在调用 WCF之前,通过使用 SvcUtil.exe来生成出所需要的 Client端调用代码。该程序在 Program File\Microsoft.Net\SDK\Compact Framework\v3.5\bin下。
通过键入: netcfSvcUtil.exe /language:cs https://localhost:3721/WCFSite/Service.svc 来解析生成客户端的调用文件。会生成 2个文件,一个叫 CFClientBase.cs,另一个是你 Service的 cs文件。
将这 2个文件添加到工程中,然后在调用 WCF的地方,创建 ChannelBinding、 Endpoint和 ServiceClient对象,然后调用 WCF方法即可。
代码如下:
Code
1 System.ServiceModel.Channels.Binding binding = ServiceClient.CreateDefaultBinding();
2 string remoteAddress = ServiceClient.EndpointAddress.Uri.ToString();
3
4 // Server IP Address
5 remoteAddress = remoteAddress.Replace( "localhost" , "10.16.172.204" );
6 EndpointAddress endpoint = new EndpointAddress(remoteAddress);
7 ServiceClient client = new ServiceClient(binding, endpoint);
8 try
9 {
10 //MessageBox.Show(client.Add(10, 20).ToString());
11 this .dataGrid1.DataSource = client.GetUserInfo();
12 }
13 catch (Exception ex)
14 {
15 MessageBox.Show(ex.Message);
16 }
因为我的 WCF在本地,所以需要将其中 remoteAddress需要替换成 WCF所在的 Service地址。
代码完成后开始进行测试,点击 Get Data,返回数据,效果如下:
发现数据排列不是我想要的,这时候就需要改变 DataMember中的 Attribute,设置其 Order顺序。效果如下:
工程如下:
Tips:
- 在实际测试中,因为公司网络设置代理服务器,所以,需要将模拟设备中的代理去除,并不允许连接到 Internet,才能进行访问 WCF,否则会需要用户验证。
- WCF不返回 DataSet和 DataTable的理由:
DataSet和 DataTable类型是可序列化的,因而我们可以在服务契约中接收或返回数据表或数据集。
如果服务契约使用了 DataSet和 DataTable类型,生成的代理文件不会直接使用 DataSet和 DataTable类型,而是包含 DataTable数据契约的定义(只包含 DataTable的样式,而不包含任何代码)。但我们可以手工修改这些定义。
注意, DataRow类型是不能序列化的。
在 WCF中,还可以使用 DataTable和 DataSet的类型安全的子类。书中也给出了相应的例子。然而, WCF的最佳实践则是避免使用 DataTable和 DataSet,以及使用 DataTable和 DataSet的类型安全的子类。在《 Programming WCF Services》书中阐释了原因:
“对于 WCF的客户端与服务而言,虽然可以通过 ADO.NET和 Visual Studio工具使用 DataSet、 DataTable以及它们的类型安全的派生对象,但这种方式过于繁琐。而且,这些数据访问类型都是特定的 .NET类型。在序列化时,它们生成的数据契约样式过于复杂,很难与其它平台进行交互。在服务契约中使用数据表或者数据集还存在一个缺陷,那就是它可能暴露内部的数据结构。同时,将来对数据库样式的修改会影响到客户端。虽然在应用程序内部可以传递数据表,但如果是跨越应用程序或公有的服务边界发送数据表,却并非一个好的主意。通常情况下,更好的做法是暴露数据的操作而非数据本身。 ” - WCF可以不创建 Web Site方式,可以创建 Host方式来打开关闭 WCF。这里不做说明。
参考文章:
WCF:张逸: Programming WCF Services
《 An Introduction to WCF for Device Developers》
Demo下载:SmartDeviceWCFDemo.rar