AJAX應用服務器端:面向服務與WCF

        WCF作爲AJAX服務平臺的優勢
                WCF爲啓用AJAX的Web服務提供管道形式服務,並未服務器與客戶端之間的通信提供了統一的編程模式。WCF運行環境非常靈活,它包含了能夠運行於TCP/IP或其他LAN協議之上的服務,並且可以託管包括ASP.NET在內的許多環境中。儘管如此,我們仍然將它視爲一個純粹的Web服務平臺。以下例程,全部運行在ASP.NET託管應用下的因特務信息服務IIS中。
               依靠基於服務的架構,可以獲得重用AJAX應用的巨大潛力。在進行應用開發的時候,能夠從AJAX Web應用出現之前的那種完全基於頁面的開發模式中解脫出來。另一方面的收效在於遠程客戶端也可以使用相同的Web服務,從而可以保護在服務平臺架構上的投資。無論是想將業務發佈到遠端應用,還是使用緊耦合服務作爲AJAX應用的基礎,基於服務的AJAX架構模式都能夠通過將AJAX應用與服務平臺相分離的方式來獲得可重用性、快速開發能力以及最大的靈活性。並且,由於服務沒有捆綁到終端用戶應用上,因此同樣作爲一個產品,服務應用往往具有比終端應用更長的生命期。這種架構師的在增加新的服務或增強平臺能力時不需要重構客戶端應用,通過新型數據訪問技術,例如採用增強型的語言集成查詢LINQ或者Microsoft SQL Server,對後端平臺進行升級時也不會影響服務界面/。下圖突出體現了WCF 在AJAX應用架構中的角色。

使用WCF 爲 AJAX 應用實現服務基礎結構



              


              面向服務與基於服務的AJAX應用
                      “面向服務”是一種通過應用的服務界面來對唯一定義這個方法的架構方法,這種方法描述了架構設計的宗旨:提供鬆耦合、明確定義的、抽象概括實現細節的基於消息的應用。本節中,建立了基於服務的應用案例,用以反映以下幾點面向服務軟件的原則:
                            1)應用邊界應當清晰明確。
                            2)自主開發和部署服務
                            3)服務公開明確定義的信息。
                       對於一個AJAX應用,遵照上述幾條原則,就意味着服務不能與JavaScript客戶端或本地Web應用中的服務緊耦合。對於任何遠程應用和本地AJAX應用,服務都是透明的。
                      面向服務的原則使基於服務的AJAX應用成爲可能,它使AJAX開發和能夠交付多種基於公共服務和數據模型(data schemas)的組件,面向服務和基於模式的編程方式簡化了控件和客戶端展現的開發工作,因此開發者能夠爲標準數據模式創建公共的控件和展現技術。例如,在爲展現邏輯編寫XSLT時,把它建立在模式的基礎上就能夠在多種上下文中重用XSLT。
                     基於服務的AJAX應用位於面向服務應用架構的頂層。由於AJAX服務集成是通過運行環境行爲鬆散耦合實現的,因此不必在服務代碼中編寫太多的AJAX支持。AJAX應用在服務界面之上進行開發,通過配置的方式可以填入AJAX-enablling。依照這種策略,能夠將遠程客戶端應用添加到同一個服務中,並在多個AJAX組件中重用服務節點。理想情況是開發者編寫的是基於服務的AJAX應用,不是基於AJAX的服務應用。


        WCF基礎
                 WCF師的開發者能夠在Windows平臺上採用標準統一的編程模型來建立面向服務的應用——開發外向型Web服務應用、內網Web服務、peer-to-peer內網應用或者server-to-server分佈式應用都可以使用同樣的WCF面向服務的編程模型來完成。由於具有基於通道、綁定、協定、終結點和行爲的服務封層方式,因此WCF的編程模型非常靈活。通過服務分層方式,行爲通過配置就可以添加到終結點,具備替代行爲與綁定的多個終結點可在託管應用中創建。恆定不變的是編程模型——不必理會綁定和行爲,服務編程模型是統一的。
                 下圖表示了WCF編程的層次劃分方式。

                WCF 對服務編程進行的層次劃分

                        可以通過應用協定屬性到接口的方式來創建服務協定。接口通過定義了具體行爲的類來執行。服務類並沒有什麼特別之處,它並未集成ASMX Web Service類這樣那個的基礎類,而只是實現了由WCF屬性標記的服務界面。
                       終結點通過類似 http://knowledgebace/dataservice.svc 這樣的URI來發布服務協定,在ASP.NET中基於部署到Web應用的SVC文件。應用綁定到終結點,並指定使用的協議:簡單Web綁定、使用SOAP的Web Service 綁定或者是用戶自定義的綁定。宿主應用使用綁定來創建具有邊界協議的服務通道。在說明通信使用的傳輸機制和協議時,綁定將服務與傳輸機制分隔開。在ASP.NET Web應用中,使用的綁定通常包括wsHttpBinding 和webHttpBinding,前者是SOAP Web服務提供的HTTP綁定,後者是爲無SOAP的簡單Web服務提供的HTTP綁定。AJAX客戶端通常使用webHttpBinding,遠程客戶端通常使用wsHttpBinding。
                     Silverlight 2.0 和其他一些兼容ASMX的客戶端使用基本綁定basicHttpBinding。在後面的小節中,將詳述協定、終結點、綁定和行爲的更多細節。下面首先來看看使用HelloWorld實現的簡單例子。

             WCF協定
                      協定是面向服務的應用基礎。協定爲遠程終端的服務和界面定義了數據模式和操作規約。遠程應用所能接觸到的只有協定——它無法獲知服務內部信息和執行細節。基於SOAP的Web服務通過Web Service Description Language(WSDL)發佈協定。對於 .NET Web服務(包括 ASMX和WCF服務),WSDL由服務運行庫生成,並未SV或svcutil.exe用來爲遠程客戶端生成代理類。WSDL最值得注意的部分是你不必真正閱讀它,儘管它是面向服務架構中非常重要的角色,但它只是我們開發工具創建或使用的中介物。
                       在代碼中,服務協定是通過服務界面中使用的屬性來定義的。儘管能夠應用服務界面屬性的實體類,但是爲了提供具有自豪可維護性的代碼,服務界面總是作爲interface類型來定義的。使用接口師的代碼相對於遠程終端爆出了代碼上的穩定性,因爲界面比較容易在編譯時捕獲破壞性的更改。例如,下面的代碼爲具備Hello這樣一個單一方法的HelloWorld服務定義了簡單界面。
 

public interface IHelloWorld
{
    string Hello();
}
                      要想WCF服務一樣使用界面,需要添加ServiceContract和OperationContract屬性。ServiceContract屬性應用於界面或者類,將它作爲WCF服務激活。OperationContract應用於服務方法中。下面的例子激活了IHelloWorld界面,將它作爲WCF服務協定來使用:
[ServiceContract]
public interface IHelloWorld
{
    [OperationContract]
    string Hello();
}

                       ServiceContract屬性也同樣具有參數名(Name)和命名空間(Namespace),它們常用於幫助住識別協定。OperationContract具備Name屬性。Name和Namespace參數指定了服務的XML名稱和命名空間以及WSDL協定中的操作。XML命名空間是概念性的URI,用於表示服務和XML模式。這些URL與.NET命名空間類似,但是XML應用他們來消除數據模式的歧義。它們不必是真實的URL,通常是基於開發者公開的URL。例如,Miicrosoft在URL http://microsoft.com/schemas/rss/core/2005 爲 Simple List Extensions 定義了XML命名空間。這個URL並不是真實的,在這個位置並不存在頁面,替代的是一個identitier。對知識偶然使用服務的開發者,這些命名空間也不併不重要,但是它們在面向服務框架中去世關鍵性的。如果不定義XML命名空間,命名可能更加http://tempuri.org將被指派。最佳的通常管理是在協定上定義XML名稱和命名空間,就下面這個應用到IHelloWorld上的例子一樣:
[ServiceContract(Name = "HelloWorld",
            Namespace = "http://example.com/exampleServices")]
public interface IHelloWorld
{
    [OperationContract(Name = "Hello")]
    string Hello();
}

                         在定義服務界面的過程中,定義用於生成WSDL以及通過WCF服務服務類的公共服務協定。協定與實現無關,它只是指定的操作和數據模型。通過實現一個接口,能夠保證不會“打斷”任何服務客戶端(即發生讓已有的客戶端不可用的更改)。公共API中公佈的界面是“啞”的,但是可以增添新的界面。爲了完成HelloWorld,除了先前公佈的Hello方法之外,還要添加了Goodbye方法。添加第二個方法不會對客戶端應用造成引起中斷的改變。另外,WebGet屬性被應用到這些方法中。隨後關於WebServiceHostFactory的小節中崙蘇WebGet屬性。
IHelloWorld協定定義了服務及其操作
using System;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace ExampleServices
{
    [ServiceContract(Name="HelloWorld", 
            Namespace="http://example.com/exampleServices")]
    public interface IHelloWorld
    {
        [WebGet]
        [OperationContract(Name="Hello")]
        string Hello();

        [WebGet]
        [OperationContract(Name = "Goodbye")]
        string Goodbye();
    }
}

                             如同前面所提到的,在界面應用ServiceContract屬性可以使界面像服務協定一樣使用。每個發佈到服務的方法都必須標誌上 OperationContract屬性。下面定義了執行IHelloWrold協定的HelloWorld服務。在隨後會使用這個服務來演示終結點、綁定以及行爲。由於在界面中,服務管道是受控的,因此服務類不需要額外的服務標記就能夠控制實現。
using System.ServiceModel;
using System.ServiceModel.Activation;

namespace ExampleServices
{
    // The following attribute enables execution in the ASP.NET pipeline:
    [AspNetCompatibilityRequirements(
        RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class HelloWorld : IHelloWorld
    {
        public string Hello()
        {
            return "Hello, world!";
        }

        public string Goodbye()
        {
            return "Goodbye, cruel world!";
        }
    }
}

                                     由於爲業務實現了一個界面、業務實現相分離的界面,因此在應用的整個生命期具備了更易維護的代碼。在編譯時,HelloWorld類中的代碼修改不會中斷服務協定。WCF服務終結點可以通過設定配置來訪問服務界面和類。




 


           WCF終結點
                  終結點定義了提供可用服務的地址或URI。終結點通過一臺創建了服務通道和綁定的服務主機激活。服務主機用來運行服務、配置它的終結點以及應用安全設置。主機可以通過控制檯應用程序、服務應用、Windows進程激活服務(WAS ,Windows Process Activation Service)、IIS或者ASP.NEt創建。這裏將詳述ASP.NET託管服務。
                  在ASP.NET中,服務部署定義文件讓ASP.NET創建並運行WCF服務主機。服務部署定義文件僅僅定義服務運行狀態的終結點,它大致與ASP.NET 2.0的ASMX Web Service文件相當。ASP.NET中的服務部署定義文件使用 .svc 擴展名,並且部署在ASP.NET文件系統中。
                  ASP.NET服務宿主文件用於激活服務並向WCF運行庫傳遞調用。服務宿主文件定義的是服務實現類而不是界面,其界面、綁定、行爲等擴展配置在web.config中。下面的服務宿主文件定義了服務ExampleServices.HelloWorld,這個服務使用ServiceHostFactory和通用的ServiceHost類來託管。
<%@ ServiceHost Service="ExampleServices.HelloWorld"  %>

   注意: 一般來說,ServiceHost 和ServiceHostFacotry類是由ASP.NET運行庫控制的,可以通過web.config和 .svc文件來定義,而不必在具備WCF的ASP.NET中創建和實例化這些類

                如果沒有特別的額外說明,服務主機將使用通用的ServiceHost,可採用ServiceHostFactory來創建這個類。如後面的章節所述,ServiceHost和ServiceHostFactory類需要在web.config中進行配置。在ASP.NET中可以指定使用WebServiceHostFactory或者WebScritpServiceFactory來生成宿主,這種方式不需要進行額外的配置,但是靈活性較差。下面的SVC文件使用WebServiceHostFactory創建WebServiceHost,這樣就不必在web.config中進行配置了。
<%@ ServiceHost Service="ExampleServices.HelloWorld" 
    Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>

                 WebServiceHostFactory創建了一個在ASP.NET應用中運行的宿主,並將webHttpBinding和webHttpBehavior應用到終結點。WebGet屬性應當添加到任何一個支持GET方法的終結點,以便利用webHttpBehavior來發布通過HTTP GET請求的Web Service。同樣地,WebScriptServiceFactory類也可以創建在ASP.NET應用中運行的宿主並將webHttpBinding和enableWebScriptBehavior應用到終結點。下面的SVC文件使用WebScriptServiceHostFactory創建了WebScriptServiceHost,而並未修改web.config
<%@ ServiceHost Service="ExampleServices.HelloWorld" 
    Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"%>

                  重要:儘管WebServiceHostFactory類和WebScriptServiceFactory類不需要配置web.config中的條目,但對於定義終結點來說卻缺乏靈活性。

               如果使用以便的ServiceHost宿主(如果未使用前面所提到的ServiceHostFactory類),將使用這個缺省類型,則必須在web.config中定義服務。SVC文件的作用是一個激活的,而配置文件用於指定終結點的相對地址、界面、綁定以及行爲。綁定與行爲我們稍後討論。現在要說的是,wsHttpBinding指定終結點使用SOAP協議,這與webHttpBinding不同,後者使用的是簡單的URL協議。
              下面從web.config中抽取的服務配置的含義爲:當從URL“HelloWrold.svc/soap”訪問HelloWorld類型時,該類型通過wsHttpBinding發佈IHelloWorld界面。請注意終結點地址定義與SVC文件的關係。
  
      <service name="ExampleServices.HelloWorld" behaviorConfiguration="ExampleServicesBehavior">
        <endpoint address="soap" binding="wsHttpBinding"
                  contract="ExampleServices.IHelloWorld" />
      </service>



  
        WCF綁定
                 綁定定義了服務的傳送機制/。這種機制將服務綁定到SOAP或者Web請求協議。AJAX服務可使用webHttpBinding進行綁定,這激活了一個簡單的HTTP接入。webHttpBinding綁定也激活了WebScriptEnablingBehavior,它將爲WCF服務自動建立JavaScript代理。如果前文所述,具有代表性情況的是使用wsHttpBinding通過SOAP想遠程客戶端發佈服務,想JavaScript客戶端發佈服務通常使用webHttpBinding。另外。webHttpBinding中使用basicHttpBinding,主要是爲了保持與ASMX Web Service客戶端的兼容性。
                下面的終結點定義中,對前面的例子進行了補充添加了一個定義在URL“HelloWorld.svc/ajax”中使用webHttpBinding的終結點。
      <service name="ExampleServices.HelloWorld" behaviorConfiguration="ExampleServicesBehavior">
        <endpoint address="soap" binding="wsHttpBinding"
                  contract="ExampleServices.IHelloWorld" />
        <endpoint address="ajax" binding="webHttpBinding" behaviorConfiguration="JsonBehavior"
                  contract="ExampleServices.IHelloWorld" />
      </service>





      WCF行爲
              WCF中的行爲使服務得以擴展。行爲可以作用於服務、終結點、協定或者操作。WCF行爲是用戶自定義的代碼,通過修改運行環境操作應用到服務調用上。例如,WebScriptEnablingBehavior運行WCF方法接受來自JavaScript客戶端的調用,並在通過 /js 或 /jsdebug 終結點訪問時生成 JavaScript 代理,簡化了從AJAX代碼中調用WCF的操作。
              行爲在web.config文件中的 configuration/system.serviceModel/behaviors 節點內進行定義。可以定義很多行爲,包括開發者自己編寫的行爲。但是目前我們最爲關心的行爲是支持服務發現的行爲以及終結點的AJAX集成。


       更多信息:如果程序要創建自己的WC行爲,要了解更多關於自定製WCF行爲的信息,可以參見 http://msdn.microsoft.com/en-us/magazine/cc163302.aspx 中Aaron Skonnard的文章


           在服務級上,serviceMetaData行爲生成WSDL和Metadata Exchange(MEX),讓客戶端能夠使用服務,這個行爲定義在serviceBehaviors總,所示如下:
<serviceMetadata httpGetEnabled="true" />

             serviceDebug元素幫助開發者調試服務,它可以顯示SOAP故障中的錯誤消息,這樣AJAX客戶端就能夠捕捉到異常錯誤。serviceDebug元素的定義方式如下:
  <serviceDebug includeExceptionDetailInFaults="true"/>

               serviceDebug 元素激活服務的幫助頁面,它具有兩個可供選擇的屬性 httpHelpPageEnabled 和 httpHelp-PageUrl 。
              下面的配置中創建了一個名爲ExampleServicesBehavior的服務行爲。該行爲應用在服務上,用於啓動服務的元數據和服務調試信息。
<serviceBehaviors>
        <behavior name="ExampleServicesBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"  />
        </behavior>
      </serviceBehaviors>

                  在服務行爲的配置定義完成後,就可以應用於多個服務。羨慕的實例代碼將行爲配置應用到ExampleService.HelloWorld服務中。
      <service name="ExampleServices.HelloWorld" behaviorConfiguration="ExampleServicesBehavior">
        <endpoint address="soap" binding="wsHttpBinding"
                  contract="ExampleServices.IHelloWorld" />
        <endpoint address="ajax" binding="webHttpBinding" behaviorConfiguration="JsonBehavior"
                  contract="ExampleServices.IHelloWorld" />
      </service>

                  另一個對於AJAX開發非常重要的行爲是終結點行爲enableWebScript,在System.ServiceModle類型中定義。Description.WebScriptEnablingBehavior、動態生成的JavaScript服務代理以及JavaScript集成爲服務終結點提供支持。下面的配置文件定義了ExampleAjaxBehavior的配置,其彙總包括enableWebScript行爲。ExampleAjaxBehavior是一個隨意命名,分配給終結點配置中的終結點使用。
    <behaviors>
      <endpointBehaviors>
        <behavior name="ExampleAjaxBehavior">
          <enableWebScript/>
        </behavior>  
      </endpointBehaviors>
     </behaviors> 

                 如同接下來的例子中所示,要將ExampleAjaxBehavior配置應用到服務終結點,需要在終結點增加behavioConfigutation屬性。enableWebScript屬性只能應用到webHttpBinding上,如果應用到其他綁定,當業務激活時將導致運行錯誤。下面的配置將 ExampleAjaxBehavior添加到名爲ajax的終結點,這個終結點使用的是webHttpBinding綁定。
      <service name="ExampleServices.HelloWorld" behaviorConfiguration="ExampleServicesBehavior">
        <endpoint address="soap" binding="wsHttpBinding"
                  contract="ExampleServices.IHelloWorld" />
        <endpoint address="ajax" binding="webHttpBinding" behaviorConfiguration="ExampleAjaxBehavori"
                  contract="ExampleServices.IHelloWorld" />
      </service>

                 重要:爲了使用enableWebScript行爲將服務發佈到ASP.NEt AJAX運行庫,webHttpBinding綁定是必須的。enbaleWebScript行爲應用於wsHttpBinding綁定屬性的服務,將會導致服務激活失敗。


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章