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的具體實現。