WCF,全称是Windows Communication Founcation,它做为微软新一代的通信技术,首先正式出如今.NET Framework 3.0中,伴随着Windows Vista的发布而名闻遐迩。在此以前,曾经做为Winfx的一部分为人所知,其代号为indigo。外语屋javascript
做为Foundation(基础模块),WCF是定位在微软.NET平台上实现统一的消息服务通信机制。它很好地吸取了以前的多种分布式开发技术的优势,而且提供了统一的编程和访问的模型,逐渐成为SOA解决方案中的主流技术,受到了普遍的关注和使用。php
从技术层面理解WCF,能够分为三个要素(俗称WCF的ABC)html
1.Address(where):地址,是指访问服务的URI(能够是一个http地址,也能够是tcp的地址)java
2.Binding(how):绑定,是指通信所使用的协议,例如http,net.tcp,msmq等等jquery
3.Contract(what):合约,是指通信的规范,例如服务的合约,数据的合约等等。android
从系统层面理解WCF,能够分为四个要素web
1.Contract:合约,定义一套合约,一般是WCF开发的起点。这也是惟一须要在宿主和客户端之间共享的信息,一般是一些接口(interface)定义。编程
2.Service:服务,基于合约实现的一个具体服务。一般是一些类型(class)定义,实现了业务逻辑。json
3.Host:宿主,既然服务是一个class,它自身是没法对客户端请求进行响应的。因此须要有一个宿主程序来提供持续的监听。WCF的宿主能够是任意的应用程序,很是灵活。浏览器
4.Client:客户端,任何客户端(例如Windows Forms,WPF, Silverlight,Console Application,甚至Javascript,或者java,php等等)均可以经过本身的方式来访问WCF.
WCF 从发布到如今的将近5年左右的时间,通过了屡次加强和改进,从最开始单纯的SOAP Service的方式,发展出来其余多种应用场景,分别是
1. SOAP Services
2. WebHttp Services
3. Data Services
4. Workflow Services
5. RIA Services
下面我将针对这些应用场景一一进行讲解
【注意】我常用WCF技术以及一些讲座中,都会感慨WCF配置的强大。宿主和客户端均可以经过配置文件的方式定义、更改WCF服务的行为。能够这么说,在WCF中,几乎什么均可以配置。这确实很酷。因此下面的讲解,不少都是用配置文件的方式来讲明问题。android中记录读取配置信息
这种场景是WCF一开始就支持的,也是最完整的一个。
为何称为SOAP Services呢?这是由于WCF服务是基于消息的通信机制,而它的消息是被封装为一个SOAP Envelope(SOAP 信封的)
【备注】SOAP的全称是Simple Object Access Protocol,咱们通常翻译为简单对象访问协议。
一个典型的SOAP Request(表明了客户端发到服务器的请求)
一个典型的SOAP Response
这 种服务是以操做(Operation)为中心的,也就是说,咱们能够彻底控制服务的全部细节,包括定义合约,实现服务,实现宿主等等。这里面有两层意思, 咱们将有足够的灵活性,由于全部一切都是能够控制的;同时,咱们也须要具有足够的专业知识,由于全部一切都须要你本身控制。
咱们来看一个典型的WCF SOAP Service的配置文件
<system.serviceModel> <services> <service name="WcfService2.Service1" behaviorConfiguration="WcfService2.Service1Behavior"> <!-- Service Endpoints --> <endpoint address="" binding="wsHttpBinding" contract="WcfService2.IService1"> <!-- Upon deployment, the following identity element should be removed or replaced to reflect the identity under which the deployed service runs. If removed, WCF will infer an appropriate identity automatically. --> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="WcfService2.Service1Behavior"> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
SOAP Services是从.NET Framework 3.0一开始就提供的,在后续版本中,也有不少改进,包括对WS-*标准更好的支持,以及提供了不少默认的配置选项,简化了配置的工做。
【备注】值得一提的是,微软研发集团上海办公室这边有一个团队,直接参与了WCF的新版本的不少功能和工具的设计和开发,包括对于配置的简化设计。感谢他们的工做。
咱们来看一个.NET Framework 4.0下面的WCF服务默认的配置文件
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior> <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel>
经过简单地比较就能够知道,在.NET Framework 4.0中,咱们并无看到端点(EndPoint)的定义,这是怎么回事呢?难道如今不须要定义端点了吗?固然不是,区别在于,.NET Framework4的ServiceHost将自动地注册几个默认的EndPoint。
【备注】若是不是为了在开发阶段调试须要而开启元数据和调试支持,上面的配置文件,甚至能够是空的,什么都不须要定义。
关于ServiceHost以及默认的端点的信息,有兴趣能够参考
http://msdn.microsoft.com/en-us/library/system.servicemodel.servicehost.aspx
总结:采用这种方式进行开发的WCF,能够根据咱们的需求,使用任意的Binding,以支持不一样的客户端,而且提供在不一样的场合下最好的速度,还能够实现诸如缓存,队列,事务协调等高级功能。
这种服务的出现,是基于一个比较热的概念:RESTFul。能够这么说,这是WCF Restful的一个具体实现。从.NET Framework 3.5开始提供。
所谓RESTFul的概念,有兴趣能够参考 http://zh.wikipedia.org/wiki/REST 以及我以前写过的一些博客文章:http://zzk.cnblogs.com/s?w=blog%3Achenxizhang%20rest
大体的意思是:
表象化状态转变(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。
目前在三种主流的Web服务实现方案中,由于REST模式的Web服务与复杂的SOAP和XML-RPC对比来说明显的更加简洁,愈来愈多的web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找;雅虎提供的Web服务也是REST风格的。
REST 从资源的角度来观察整个网络,分布在各处的资源由URI肯定,而客户端的应用经过URI来获取资源的表形。得到这些表形导致这些应用程序转变了其状态。随着不断获取资源的表形,客户端应用不断地在转变着其状态,所谓表形化的状态转变(Representational State Transfer)。
今天不是专门来探讨REST的,咱们主要看看WCF是如何实现对REST支持,以及如何使用这种风格的服务。
实现WCF Restful,关键在于一个新的Binding方式,也就是WebHttpBinding。因此这种服务,我这里将其称为WebHttp Services。
WebHttp Services是在传统的SOAP Services基础上的一个加强,它仍然是基于操做(Operation)的,只不过这些Operation能够直接经过Uri访问到,而无需客户去编写一个特殊的客户端。
同时,WebHttp Services提供了两种不一样的消息格式,第一种是XML,第二种是Json。这将更加有利于诸如Javascript这种客户端来访问服务。
要实现WebHttp,咱们首先要添加一个引用,以下
而后 ,咱们能够定义一个特殊的Operation
[OperationContract]
[WebGet]
string HelloWorld();
【注意】这里经过WebGet这个Attribute,声明该操做是能够直接在Http访问中访问的
下面是该操做的实现
using System;using System.ServiceModel.Activation;namespace WcfService1 { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together. [AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Required)] public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; } public string HelloWorld() { return "Hello,world"; } } }
【备注】该服务必须声明为AspNetCompatibility
为了使用该服务支持WebHttpBinding,咱们须要修改配置文件以下(粗体部分是咱们此次添加的)
<?xml version="1.0"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <services> <service name="WcfService1.Service1"> <endpoint address="" behaviorConfiguration="WcfService1.Service1AspNetAjaxBehavior" binding="webHttpBinding" contract="WcfService1.IService1" /> </service> </services> <behaviors> <endpointBehaviors> <behavior name="WcfService1.Service1AspNetAjaxBehavior"> <enableWebScript /> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior name=""> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> </configuration>
若是是这样的定义,那么在浏览器中咱们就能够直接访问该服务及其操做
既然是RESTful,那么就能够直接在地址栏像下面这样访问
咱们发现它的返回值是application/json格式的
具体返回的是什么内容呢?
也就是说,WebHttp Service默认是返回json格式的数据的,这就很容易在JAVASCRIPT中使用该服务。例如
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="WcfService1._default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="jquery-1.4.3.min.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> $(function () { $("#btHelloworld").click(function () { var uri = "Service1.svc/HelloWorld"; $.getJSON(uri, null, function (result) { alert(result.d); }); }); }); </script> </head> <body> <form id="form1" runat="server"> <div> <input type="button" id="btHelloworld" value="call webhttp Service"/> </div> </form> </body> </html>
在页面中测试的效果以下
值得注意的是,WebHttp Service除了支持Json格式以外,也支持XML格式,咱们能够经过修改WebGet这个Attribute的设置来达到目的
[OperationContract]
[WebGet(ResponseFormat=WebMessageFormat.Xml)]
string HelloWorld();
也能够经过配置文件的方式来设置(注意粗体部分)
<?xml version="1.0"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <services> <service name="WcfService1.Service1"> <endpoint address="" behaviorConfiguration="WcfService1.Service1AspNetAjaxBehavior" binding="webHttpBinding" contract="WcfService1.IService1" /> </service> </services> <behaviors> <endpointBehaviors> <behavior name="WcfService1.Service1AspNetAjaxBehavior"> <enableWebScript /> <webHttp defaultOutgoingResponseFormat="Xml"/> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior name=""> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> </configuration>
若是用XML格式的话,那么在浏览器测试的效果以下
总结:WebHttp Services是在SOAP Services基础上的一个改进,它不是返回SOAP Evenlope,而是根据须要返回XML或者JSON数据。这样的设计,目的是让服务更加易于使用。同时,该服务是WCF Restful的具体实现。