AppleSeeker's Tech Blog
Welcome to AppleSeeker's space
posts - 67,  comments - 696,  trackbacks - 6
在前一篇文章《.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 http://localhost:3721/WCFSite/Service.svc 来解析生成客户端的调用文件。会生成2个文件,一个叫CFClientBase.cs,另一个是你Service的cs文件。

将这2个文件添加到工程中,然后在调用WCF的地方,创建ChannelBinding、Endpoint和ServiceClient对象,然后调用WCF方法即可。
代码如下:
Code
因为我的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

Tag标签: Windows Mobile,WCF
posted on 2008-02-20 11:43 AppleSeeker 阅读(2949) 评论(9)  编辑 收藏 网摘 所属分类: .NetMobile

FeedBack:
2008-02-20 11:46 | jillzhang      
这个是不错的消息
收藏,以后可能用得到

  回复  引用  查看    
#2楼[楼主]
2008-02-20 11:49 | appleseeker      
@jillzhang
大哥,你回复的也太快了吧,刚把Demo上传完

  回复  引用  查看    
2008-02-20 14:18 | jillzhang      
@appleseeker
我还没看呢,现在忙,先收藏了,一会看

  回复  引用  查看    
2008-02-21 09:18 | zzz[未注册用户]
谢谢楼主的文章。有个问题请教一下:本人刚学习WCF,写了个WCF例子,客户端调用服务时,如果要求返回少量的List<string>,程序正常,如果要求返回大量的List<string>时则出错:“读取管道时出错: 管道已结束。 (109、0x6d)。” 主要代码如下:
1)ServiceContract及其实现的代码:

[ServiceContract]
public interface IService //接口
{
[OperationContract]
List<string> GetStringList(int numToGet); //返回的是List<string> , 泛型
}

public class Service : IService //实现
{
public List<string> GetStringList(int numToGet)
{
List<string> list = new List<string>();
for (int i = 0; i < numToGet; i++)
{
list.Add(string.Format("这是第{0}个字符串\r\n", i));
}
return list;
}
}

internal class MyServiceHost
{
internal static ServiceHost serviceHost = null;

internal static void StartService()
{
Uri baseAddress = new Uri("net.pipe://localhost/WCFService/Service");
NetNamedPipeBinding binding = new NetNamedPipeBinding();
binding.MaxReceivedMessageSize = 65536 * 1000;
serviceHost = new ServiceHost(typeof(Service), baseAddress);
serviceHost.AddServiceEndpoint(typeof(WCFService.IService), binding, "");
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri("http://localhost:8001/");
serviceHost.Description.Behaviors.Add(behavior);
serviceHost.Open();
}

internal static void StopService()
{
if (serviceHost.State != CommunicationState.Closed)
serviceHost.Close();
}
public static void Main() //控制台Main
{
StartService();
Console.WriteLine("Service Start.....");
Console.ReadLine();
StopService();
}
}


2)客户端主要代码:
try
{
NetNamedPipeBinding binding = new NetNamedPipeBinding();
binding.MaxReceivedMessageSize = 65536*1000;
ServiceClient proxy = new ServiceClient(binding,
new EndpointAddress("net.pipe://localhost/WCFService/Service"));
List<string> list = proxy.GetStringList(100000); //已通过VS将集合类型映射为List<T>
//StringBuilder sb = new StringBuilder();
//foreach (string s in list)
//{
// sb.Append(s);
//}

//textBox1.Text = sb.ToString();
}
catch (CommunicationException ex)
{
textBox1.Text = "错误::" + ex.Message;
}

问题出在这一行:List<string> list = proxy.GetStringList(100000);
如果这一行中的GetStringList()的参数值改小一点,如10000,则程序正常运行,如果大一点则出错(初步判断跟返回List<T>和MaxReceivedMessageSize大小没有关系),请问应该怎么修改才能解决?先谢了!

  回复  引用    
#5楼[楼主]
2008-02-21 10:04 | appleseeker      
@zzz
你好,我的判断是传输内容太长,超过限制。你可以在服务器端测试下,将list序列化后的长度,看有多长。

如果可以的话,发代码给我,我帮你看下~

  回复  引用  查看    
2008-02-26 15:32 | 史云飞[未注册用户]
楼主,你好,按照你的方法我做了一遍,我写完wcf服务后在ie里面能正常显示,可是在PPC(移动程序中)却始终显示以下错误:
There was no endpoint listening at http://shiyunfei/Demo03/Service.svc
that could accept the message.This is often caused by an incorrect address or SOAP action.See InnerException, if present, for more details

我把你写的程序放在我机器上也是这种问题.

  回复  引用    
#7楼[楼主]
2008-02-26 16:37 | appleseeker      
@史云飞
你是用模拟设备还是实际程序?模拟设备有没有与ActiveSync连接?

如果你是模拟设备,首先,连接ActiveSync,然后测试下能否访问Internet,如果可以,再试试访问WCF.

程序本身没有问题,是设备配置问题.

  回复  引用  查看    
2009-01-21 11:03 | 伯乐族人      
好文章,你的文章已经被伯乐族收藏。你也可以通过伯乐族提交你的文章,这样有更多人能关注到你的文章。

伯乐族 www.*** --程序员的时间很精彩!
--关注你需要的最新.NET技术文章、招聘职位、最新装备...
--订阅伯乐族族人推荐给你的最新程序员的世界发生的精彩信息

  回复  引用  查看    
2009-05-15 08:46 | BruceZhou      
偶刚开始写一个wm6.0 调用WCF操作数据库的程式,收藏
  回复  引用  查看    



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1074741




相关文章:

相关链接:
Free Hit Counter

MSN:appleseeker@hotmail.com
Mail:appleseeker@gmail.com MVP

ITProCity相聚同城,追逐梦想——上海站,第九届线下活动


<2008年2月>
272829303112
3456789
10111213141516
17181920212223
2425262728291
2345678

与我联系

搜索

 

常用链接

留言簿

我参与的团队

我的标签

随笔分类(106)

随笔档案(67)

Mobile Blog

最新随笔

积分与排名

  • 积分 - 176759
  • 排名 - 281

最新评论

阅读排行榜

评论排行榜