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绑定属性的服务,将会导致服务激活失败。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值