.Net Compact Framework 3.5对WCF的支持

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:

  1. 在实际测试中,因为公司网络设置代理服务器,所以,需要将模拟设备中的代理去除,并不允许连接到 Internet,才能进行访问 WCF,否则会需要用户验证。
  2. 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类型。在序列化时,它们生成的数据契约样式过于复杂,很难与其它平台进行交互。在服务契约中使用数据表或者数据集还存在一个缺陷,那就是它可能暴露内部的数据结构。同时,将来对数据库样式的修改会影响到客户端。虽然在应用程序内部可以传递数据表,但如果是跨越应用程序或公有的服务边界发送数据表,却并非一个好的主意。通常情况下,更好的做法是暴露数据的操作而非数据本身。 ”
  3. WCF可以不创建 Web Site方式,可以创建 Host方式来打开关闭 WCF。这里不做说明。

参考文章:
WCF:张逸: Programming WCF Services
《 An Introduction to WCF for Device Developers》

Demo下载:SmartDeviceWCFDemo.rar

 

 

下一篇:(冯峰)[Podcast推荐]--ASP.NET and .NET