技术门诊是51CTO社区品牌栏目,每周邀请一位客座专家,为广大技术网友解答疑问。从热门技术到前沿知识,从技术答疑到职业规划。每期一个主题,站在最新最热的技术前沿为你引航!

本期特邀资深.NET技术专家、畅销书作者蒋金楠老师,针对WCF的扩展之“道”问题给予解答,欢迎网友积极提问,与专家一起讨论!  

专家博客:http://jinnan.blog.51cto.com 

查看本期门诊精彩实录:http://doctor.51cto.com/develop-267.html

参与最新技术门诊:HTML5的Mobile Web App开发之路

精选本期网友提问与专家解答,以供网友学习参考。

 

Q: 蒋老师好:

我对WCF还是道听途说,以前接触过SharePoint里面的工作流,现在Web编程中OA的应用也很普遍。以前搞个网络通讯程序总是感觉很繁琐。请问老师,作为微软重新包装的通信技术,WCF有哪些方便开发的特点呢?

A:

你说的没错,要自行实现网络通信(比如采用Socket)是一件非常繁琐,而且不容易做好的事情。所以微软为了解决这个问题,开发了一系列的分布式/中间件技术,比如COM/DCOMEnterprise Service.NET RemotingXML Web服务、MSMQ等。

通过合理利用上面这些分布式技术完全可以创建一个完美的、能够适用不同层次需求的分布式应用。但是这些单一的技术和产品专注于某一特定的领域,并且具有完全不同的应用编程接口(API),这使得开发人员很难从容地从其中一种转移到另一种。基于这样的原因,急需一种全新的通信框架来整合以上这些技术,这就是WCF

WCF的目的在于让开发人员不需要关注底层地通信设置是消息交换层面的细节,只需要关心如何通过接口定义服务契约、实现接口编写服务操作的功能、通过代码生成机制创建服务代理,通过方法调用实现远程的服务消费。一切都如此简单、容易,对于网络编程一窍不通的开发者都可以进行WCF服务编程。

Q:

蒋老师:

    你好!

    WCF 由于集合了几乎由 .NET Framework 所提供的通信方法,因此学习曲线比较陡峭,开发人员必须要针对各个部份的内涵做深入的了解,才能够操控 WCF 来开发应用程序。请问WCF如何使用SOAPASMX进行交互?

    对于初次涉及WCF的朋友应当首先学习那些基础知识呢?

A:

如果要对WCF具有一个全面而彻底地了解,确实需要掌握太多的知识,比如.NET Framework、基本的网络知识、SOA设计思想、WS-*、消息队列、分布式事务以及MSDTC等等。

但是“学习曲线”却并不陡峭。对于一个没有接触过WCF的开发人员,他写第一个WCFHello World肯定比写一个Socket Hello World要容易得多。WCF虽然是一个基于消息的通信框架,但是它封装了所有的通信细节,对于最终的WCF编程人员甚至接触不到消息。我们接触到的更多的是反而是如何通过接口定义服务契约,如何实现接口定义相关的业务逻辑。WCF不是单纯地解决数据通信的问题,它是一个面向应用层面的分布式技术,它的目的就是让开发人员只需要关注业务逻辑的定义,所以它和Socket并没有可比性。

也就是说技术我们不了解网络通信是怎么回事,不知道消息是如何生成的,我们依然可以利用我们掌握的C#或者VB.NET进行WCF服务编程。所以WCF的入门反而是很容易地。

学习WCF是一个循序渐进的过程,初学者应该先了解WCF的基本编程方式,明白终结点的ABC三要素是什么,主要解决什么问题,服务端和客户端的配置大体具有怎样的结构等。如果想对WCF具有更加深刻的理解,我们的眼光就不应该只是关注这些编程方面的知识点了,而是应该看到在整个WCF客户端和服务端消息的生成和处理流程。

至于你提到的WCFASMX交互问题,我们应该这样来考虑:WCF是一个消息处理框架,WCF与其它平台的Web Service(泛指)进行集成主要体现在:

1WCF客户端能够调用其它平台Web Service

2、其他平台客户端能够调用WCF Service

客户端和服务能够正常交互的唯一前提是交换的消息能够被彼此识别。由于WCF采用标准的SOAP,并且对WS-*提供支持,意味着它进行处理的消息的格式和消息处理方式都是“标准”的,其他平台的Web Service如果也支持同一套标准,它们交互就不是问题。


Q: 蒋老师你好,我想问你一个问题。因为在实际项目中还没有具体的使用过这个技术,目前WCF给我的感觉就是,WCF是微软对于各种通信技术的一个封装,能够很容易的通过一些配置来达到不同的通信效果。那么WCF这个技术我感觉只是在多系统集成、数据交互的时候才会用到,一般的应用不会用到这个,跟以前的web service很类似。你认为我的这些观点正确吗?

A:

你的理解是对的,WCF就是广义的Web Service,系统之间的集成确实一个WCF主要解决的一个问题。不过这里的集成体现在以下两个方面:

与既有系统的集成:现有的系统包含一些可重永的功能,为了节约成本,可以通过WCF对它进行封装并被新的系统使用。

对未来系统的集成:对于一个企业来说,一个完整的解决方案往往需要多个系统协作完成,我们在开发新的系统的使用,应该考虑目前的功能的潜在的重用性。对于这些具有重用性潜力的功能,在设计的时候就应该采用SOA的原则进行设计。

 

除了集成,有些应用采用WCF就是当成一种单纯的分布式技术在使用,他们更多地还是考虑“部属”方面的问题:如果将业务逻辑进行集中部属(比较典型的部属方式是,Web Server部属的逻辑仅仅涉及简单的UI处理,而所有的业务逻辑则定义成WCF服务部属在Application Server中),可以单独地实施安全策略和负载均衡等。

 
Q:

蒋老师您好 我现在有个WCF RESTFUL 服务中IEmployees 契约中 我想加入一个方法使 传入一个List<Employees>的集合 用来执行批量新增人员应该如何处理?

例如: void CreateMore(List<Employees> employees);
应该如何定义? 如何调用? 如果是其他平台调用例如iphone,有没有可以通用的调用方法?

A:
WCF REST和针对SOAPWCF定义服务契约的时候除了需要使用WebGet或者WebInvoke指定一个Uri模板和HTTP Method之外,并没有什么不同。至于实现服务契约接口的服务类型来说,就更加没有区别了。

如果采用自我寄宿的方式,应该采用WebServiceHost,而不是ServiceHost(其实使用它也可以,只是需要作其他相关的设置)。使用的绑定类型为WebHttpBinding。如果使用IIS寄宿,不要忘了添加WebBehavior行为。

既然叫作WCF REST,意味着它是完全基于Web的,其服务调用方式就是一次单纯的HTTP请求/响应的过程,和我们普通访问某个Web页面没有本质的区别。所以说不论采用什么客户端技术,处于什么平台,你只需要向服务终结点地址发送HTTP方法和数据格式相匹配的HTTP请求,服务端就能够正确处理请求和执行相应的服务操作,并最终将处理结果作为响应返回给客户端。

WCF REST能够职能地根据请求的媒体类型决定采用的消息格式化方式。以你提出的这个例子来说,如果请求的媒体类型被设置为“application/xml”,你可以采用XML的方式来封装添加的Employee列表。如果采用“application/json”,Employee列表可以通过Json格式来表示。响应消息格式化也可以根据请求职能地完成。

关于WCF REST,在我的Blog上也有一系列文章:

[01] 一个简单的REST服务实例 
[02] 
WebHttpBinding与消息编码 
[03] 
Web消息主体风格(Message Body Style 
[04] 
帮助页面与自动消息格式(JSON/XML)选择 
[05] 
WebServiceHost有何特别之处? 
[06] 
UriTemplateUriTemplateTableWebHttpDispatchOperationSelector 
[07] 
通过ASP.NET Output Caching实现声明式缓存 
[08] 
提高性能的一个有效的手段:条件资源获取(Conditional Retrieval 
[09] 
解决资源并发修改的一个有效的手段:条件更新(Conditional Update

 

最后再说一点,由于WCF在设计之初主要是为了SOAP而设计的,而WCF REST是通过WCF的扩展实现的。我个人喜欢将SOAPREST称为“重量级”和“轻量级”消息通信,在重量级通信框架WCF下实现轻量级的REST,我觉得有点“牛刀杀鸡”的感觉。所以我们不太赞成大家使用WCF RESTASP Web API反而是更好的选择。

 
Q:

蒋老师您好,您的答案中“ 如果请求的媒体类型被设置为“application/xml”,你可以采用XML的方式来封装添加的Employee列表。”

您的意思是我将  void CreateMore(List<Employees> employees);替换为  void CreateMore(string employeesXML);

然后根据调用传递的XML 解析成List<Employees>在操作吗?

如果是基于WCF SOAP去提供一个服务给IPAD调用需要注意什么吗?
A:

我们无须为消息的格式改变操作的定义(参数的类型)。也就是说,不论是XML格式,还是JSON格式,CreateMore的参数都可以定义成IEnumerable<Employees>WCF REST会根据请求消息的媒体类型动态地选择不同的消息格式化器进行序列化和反序列化。

另一个关于iPad应用如何调用基于SOAPWCF Service,我个人没有从事IOSObject-C相关的经验,所以回答不了这个问题。不过从原则上讲,不论什么客户端,对于WCF Serivice的调用最终都体现为根据发布出来的元数据(主要体现为WSDL)生成相应的SOAP消息。

Q:

最近使用wcf是在SL3.0版本下,wcf可以理解为和webService类似的东东,在别的软件平台上我看到也有用服务这个概念的,例如WebGIS中使用soapwsdl(才疏学浅,表达不准确,测试接口的时候用的是这个服务地址),而处理的返回结果可能是几十万个数据(如电话号码,坐标点之类的)的字符串表达,前端使用GIS提供的这样服务,获取数据然后表达出来,速度确实很快!

弱弱的问问:1、如果使用wcf进行上述类似的数据处理,返回大数据量的结果,如果保存为对象列表(List结构之类的)几十万个对象保存在List中,前端进行接收,会不会造成性能的降低呢?

2wcf能不能像您说的,提供可扩展的功能来实现呢?或者说便于高性能的传输和转换?小人总是觉得使用wcf传输几十万个对象,好像有点过分,这个没有试验过,只是觉得可能存在这么个问题。 谢谢您,浪费您的时间看我的如此几个笨笨的问题了。

A:
1. 由于WCF涉及到网络转输、序列化、编码,甚至签名和加密等,大数据量的处理肯定有性能问题,这是所有技术都会遇到的问题,因为所有这些环节是避免不了的。实际上对于OLTP,来说这种大数据量的处理是很少的,即使出现了我们觉得也应该采用“分批”获取的策略。对于OLAP来说,它们对性能的要求不是那么高,甚至不具有实时性的要求。

2WCF的可扩展性意味着我们可以通过自定义相应的组件来定制某个环节的消息处理,比如我们定义更加高效的序列化器、消息编码器、传输信道,甚至可以对消息进行压缩传输,根据性能和安全的要求采用适合的安全策略(安全和性能是互相制约的,我们往往需要根据具体需求对两者进行权衡)。总之,整个消息处理的管道都是可以定制的,如果我们具有比微软更好的实现方式,完全可以替换掉现有的组件,就像是我们组装电脑一样,可用选用任意厂商的CPU、内存、主版、硬盘等