一、绑定行为概述

为了支持服务端的其它本地特性,WCF定义了行为的概念。行为就是服务的本地特性,不会影响服务的通信模式。客户端并不知道服务端行为,所以行为不会出现在服务的绑定和发布的元数据中。说下WCF下“契约(Contract)”和“行为(Behavior)”的区别:契约是涉及双边的描述(契约是服务的提供者和服务消费者进行交互的手段),那么行为就是基于单边的描述。客户端行为体现的是WCF如何进行服务调用的方式,而服务端行为则体现了WCF的请求分发方式。所以服务契约会通过元数据对外发布,而WCF服务行为则对于客户端是透明的。

通过将行为应用于系统的各个不同部分,可以控制WCF的会话管理、并发性、限流(Throttling)和事务等活动,其中一些活动只能应用在某个级别上,如服务级别,终结点级别、操作级别和契约级别。

针对不同的级别,可以用不同的方法设置行为。大多数行为可以通过配置或配置中的特性进行设置。尽管大多数行为都可以通过配置参数来进行设置,但有些行为必须在代码中进行设置。

二、服务行为

通过[ServiceBehavior]特性,可以在服务级别上应用规则和行为。在设计时,可以利用以下属性来控制行为的并发性、实例化、限流、事务、会话和线程等:

  • AddressFilterMode:允许修改消息过滤器。AddressFilterMode属性有三个值:Any(WCF会关闭基于地址的消息筛选机制,它允许路由服务处理携带的目标地址(WS-Addressing的<To>报头,适用于消息路由)与本终结点不一致的请求消息)、Exact(指示对传入消息的地址执行精确匹配的筛选器)、Prefix(指示对传入消息的地址执行最长前缀匹配的筛选器),默认值为Exact。
  • AutomaticSessionShutdown:AutomaticSessionShutdown默认为true,当客户端关闭代理时,会话会被终止。将其设置为false,则会话会继续直到服务显式地关闭其发送通道,这样就可以控制会话的生命周期了。
  • ConcurrencyMode:用此参数可以设置服务是以单线程还是多线程运行。默认值是Single。将它设置为Multiple,则意味着在服务中必须实现线程安全。
  • IgnoreExtensionDataObject:此参数是一个布尔值,默认为false。将它设置为true,则意味着消息中不带任何未知的序列化数据。
  • IncludeExceptionDetailInFaults:如果需要把未处理的异常作为SOAP消息发送给客户端,就需要把此消息参数设置为true。在开发环境中,需要将此参数设置为true;在生产环境,需要将它设为false。
  • InstanceContextMode:用此属性可以设置服务实例的生命周期。它的值可以取PerCall(新的 System.ServiceModel.InstanceContext 对象在每次调用前创建,在调用后回收)、PerSession(为每个会话创建一个新的 System.ServiceModel.InstanceContext 对象)、Single(只有一个 System.ServiceModel.InstanceContext 对象用于所有传入呼叫,并且在调用后不回收。如果服务对象不存在,则创建一个),默认为PerSession。关于实力管理的详细信息,在后续会讲到。
  • MaxItemsInObjectGraph:此属性用来设置允许在序列化和反序列化的对象图中出现的最大项数。
  • ReleaseServiceInstanceOnTransactionComplete:如果把此参数设置为true,则表示当前活动事务结束后释放服务对象。
  • TransactionAutoCompleteOnSessionClose:如果希望在会话被客户端正常关闭时,把当前活动事务标志为结束,就需要将此参数设置为true。
  • TransactionIsolationLevel:当事务出于活动状态时,指定当前对象的隔离级别。Chaos(无法覆盖隔离级别更高的事务中的挂起的更改)、ReadCommitted(可以在事务期间读取可变数据,但是不可以修改它)、ReadUncommitted(可以在事务期间读取和修改可变数据)、RepeatableRead(可以在事务期间读取可变数据,但是不可以修改。可以在事务期间添加新数据)、Serializable(可以在事务期间读取可变数据,但是不可以修改,也不可以添加任何新数据)、Snapshot(可以读取可变数据。在事务修改数据之前,它验证在它最初读取数据之后另一个事务是否更改过这些数据。 如果数据已被更新,则会引发错误。 这样使事务可获取先前提交的数据值)、Unspecified(正在使用与指定隔离级别不同的隔离级别,但是无法确定该级别。 如果设置了此值,则会引发异常)。
  • TransactionTimeout:设置事务的超时时间,超过此时间之后,此事务即被认为已经中止,回滚过程被激活。
  • UseSynchronizationContext:该值指定是否使用当前同步上下文来选择执行的线程
  • ValidateMustUnderstand:此属性用来关闭对标志为MustUnderstand的SOAP头的验证。默认为true。

三、操作行为

利用OperationBehavior特性控制类的方法,利用类的方法可以进一步控制服务的某些方面。在操作级别可以控制的行为有事务行为、访问者身份识别行为和对象回收行为。

  • AutoDisposeParameters:此属性允许操作自动释放输入、输出和引用参数。默认为false。
  • Impersonation:有时需要以访问者的身份执行操作。为了满足这种需求,需要把这个属性设置为Required或Allowed。
  • ReleaseInstanceMode:此属性允许覆盖当前服务对象的 InstanceContextMode回收值。可能的取值有None(根据 InstanceContextMode 值回收对象)、BeforeCall(在调用操作前回收对象)、AfterCall(在完成操作后回收对象)、BeforeAndAfterCall(在调用操作前和完成操作后回收对象)。默认值为None。
  • TransactionAutoComplete:当事务启动时,如果当前方法没有产生错误,则这个属性会把当前事务标志为结束,否则放弃此事务。当这个属性设置为false时,必须手工把事务标志为结束或放弃。
  • TransactionScopeRequired:通过此属性可判断一个事务是否是当前方法所请求的。

利用OperationBehavior特性,可以控制与服务操作有密切关系的参数。只需把此特性应用于需要管理的操作上,然后根据具体需要设置行为的属性参数,就可以得到所需要的行为,代码如下所示:

[OperationBehavior(AutoDisposeParameters=true,
Impersonation=ImpersonationOption.NotAllowed,
ReleaseInstanceMode=ReleaseInstanceMode.None,
TransactionAutoComplete=true,
TransactionScopeRequired=false)]
public void SayOneWay(string str)
{
Console.WriteLine(str);
}

上面这个示例中,OperationBehavior特性的全部属性都取的是默认值。

四、终结点行为

虽然服务行为只在服务端有用,但是终结点行为既可以应用于所有服务,也可以应用于客户端。给终结点设置适合的行为可以实现对客户端证书的使用的序列化器参数的管理。WCF提供了一组预先定义好的行为,其中每个行为都可以实现System.ServiceModel.Description.IEndpointBehavior接口:

  • AddBindingParameters:用此行为检查当前服务描述并可以根据终结点行为的需要修改绑定参数,此方法对每个终结点只能调用一次。
  • ApplyDispatchBehavior:IEndpointBehavior接口最重要的方法,可以通过它将终结点的行为逻辑应用于服务端。
  • Validate:此方法用来检查服务描述,当服务描述无法满足终结点行为需要时就抛出一个异常。

可以通过配置文件、编程或两者结合的方式,来设置各种on个不同的终结点行为。不同于服务行为,终结点行为既可以用在客户端,也可以用在服务端。有些特殊实现只允许应用于客户端,比如ClientCredential行为。

利用配置文件,可以定义并配置终结点的行为。例如在客户端,如果希望在调用相关终结点时必须提供证书,就可以使用ClientCredential行为,如下代码所示:客户端配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IHelloWorldService" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8000/HelloWorldService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IHelloWorldService" contract="IHelloWorldService"
name="WSHttpBinding_IHelloWorldService" behaviorConfiguration="carRentalEndpointBehavior">
<identity>
<userPrincipalName value="网\001" />
</identity> </endpoint> </client>
<behaviors>
<endpointBehaviors>
<behavior name="carRentalEndpointBehavior">
<clientCredentials>
<clientCertificate findValue="CN=client_cert" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectDistinguishedName" />
</clientCredentials>
</behavior>
</endpointBehaviors>

</behaviors>
</system.serviceModel>
</configuration>

证书安全可以参见:WCF使用X509证书,证书安全后续会有介绍,这里不过多介绍。

五、契约行为

通过实现System.ServiceModel.Description.IContractBehavior接口可以扩展或修改契约的各个方面,这种方法适合于契约的整个周期。该接口有4个方法,他们都可以用于契约的修改。遇有不能在配置文件中使用契约行为,因此只能在代码中或者通过属性修改契约行为。System.ServiceModel.Description.IContractBehavior接口的4个方法如下:

  • AddBindingParameters:此方法允许添加自定义参数,这些参数常用于控制行为的执行。此方法对于每个终结点来说只能执行一次。
  • ApplyClientBehavior:可以使用这个方法在客户端应用行为逻辑。
  • ApplyDispatchBehavior:可以使用这个方法在服务客户端应用行为逻辑。
  • Validate:用于验证行为执行时的运行时上下文。

对于IEndpointBehavior,IContractBehavior既可以应用于契约接口的客户端,也可以应用于契约接口的服务端 。然而,一个IContractBehavior实现却不能在运行时通过配置文件进行修改,只能在设计时通过属性或编程方法进行添加。

[DeliveryRequirements(
QueuedDeliveryRequirements=QueuedDeliveryRequirementsMode.NotAllowed,
RequireOrderedDelivery=true)]
public class HelloWorldService : IHelloWorldService
{
// }

在上述示例中,DeliveryRequirements表示契约不是按序列发送,而是要求消息按顺序发送。

参考书籍:《WCF 4 高级编程》

[WCF编程]6.绑定行为的更多相关文章

  1. [WCF编程]5.绑定概述

    一.绑定概述 WCF提供了一个编程框架,可以抽象化服务创建的复杂过程.绑定允许开发人员将精力集中在问题本身上,而无需考虑如何创建允许系统运行的架构,因为WCF已经创建了架构. 绑定类型是开发人员控制W ...

  2. WCF编程系列(三)地址与绑定

    WCF编程系列(三)地址与绑定   地址     地址指定了接收消息的位置,WCF中地址以统一资源标识符(URI)的形式指定.URI由通讯协议和位置路径两部分组成,如示例一中的: http://loc ...

  3. [WCF编程]4.契约概述

    一.契约的基本概念 契约是消息参与者之间的约定.在SOA架构中,契约提供了服务通信所必需的元数据.契约用来定义数据类型,操作,消息交换模式和消息交换使用的传输协议.契约通常是在标准化平台中使用与编程语 ...

  4. [WCF编程]3.WCF基础

    一.服务 服务是一组公开功能的集合. 服务内部包含了如语言.技术.版本与框架等概念,服务之间的交互只允许使用规定的通信模式 外界客户端并不知道服务内部的实现细节,所以WCF服务通常通过元数据的方式描述 ...

  5. 【WCF--初入江湖】01 WCF编程概述

    01 WCF编程概述 SOA的优点 1.服务独立于平台和工作环境.服务并不关心自己所处的环境,也不关心与之进行通信的服务所处的    环境. 2.服务相互隔离. 3.服务对协议.格式和传输中立. 4. ...

  6. WCF编程系列(七)信道及信道工厂

    WCF编程系列(七)信道及信道工厂   信道及信道栈 前面已经提及过,WCF中客户端与服务端的交互都是通过消息来进行的.消息从客户端传送到服务端会经过多个处理动作,在WCF编程模型中,这些动作是按层 ...

  7. WCF编程系列(六)以编程方式配置终结点

    WCF编程系列(六)以编程方式配置终结点   示例一中我们的宿主程序非常简单:只是简单的实例化了一个ServiceHost对象,然后调用open方法来启动服务.而关于终结点的配置我们都是通过配置文件来 ...

  8. WCF编程系列(四)配置文件

    WCF编程系列(四)配置文件   .NET应用程序的配置文件 前述示例中Host项目中的App.config以及Client项目中的App.config称为应用程序配置文件,通过该文件配置可控制程序的 ...

  9. WCF编程系列(五)元数据

    WCF编程系列(五)元数据   示例一中我们使用了scvutil命令自动生成了服务的客户端代理类: svcutil http://localhost:8000/?wsdl /o:FirstServic ...

随机推荐

  1. [.net 面向对象程序设计深入](0) 开篇

    [.net 面向对象程序设计深入](0)开篇        [.net 面向对象编程基础]和 [.net 面向对象程序设计进阶]在15年底写完了,群里也加进来不少热爱学习的小伙伴.让我深切感受到在这个 ...

  2. 由乱序播放说开了去-数组的打乱算法Fisher–Yates Shuffle

    之前用HTML5的Audio API写了个音乐频谱效果,再之后又加了个播放列表就成了个简单的播放器,其中弄了个功能是'Shuffle'也就是一般播放器都有的列表打乱功能,或者理解为随机播放. 但我觉得 ...

  3. Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2)

    Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2) 上一篇里介绍了Color-Coded Picking的思路和最基本的实现.在处理GL_POINTS时已经没有问题,但是处 ...

  4. [python] 安装numpy+scipy+matlotlib+scikit-learn及问题解决

    这篇文章主要讲述Python如何安装Numpy.Scipy.Matlotlib.Scikit-learn等库的过程及遇到的问题解决方法.最近安装这个真是一把泪啊,各种不兼容问题和报错,希望文章对你有所 ...

  5. 缓存篇(Cache)~大话开篇

    回到占占推荐博客索引 闲话杂淡 想写这篇文章很久了,但总是感觉内功还不太够,总觉得,要写这种编程领域里的心法(内功)的文章,需要有足够的实践,需要对具体领域非常了解,才能写出来.如今,感觉自己有写这种 ...

  6. PDO 数据访问抽象层

    1.操作其它数据库 (1)造对象 $dsn = "mysql:dbname=test3;host=localhost"; //数据源:两个参数:数据库驱动,链接数据库 $pdo = ...

  7. 编译opengl编程指南第八版示例代码通过

    最近在编译opengl编程指南第八版的示例代码,如下 #include <iostream> #include "vgl.h" #include "LoadS ...

  8. ASP.NET MVC5 网站开发实践(一) - 项目框架

    前几天算是开题了,关于怎么做自己想了很多,但毕竟没做过项目既不知道这些想法有无必要,也不知道能不能实现,不过邓爷爷说过"摸着石头过河"吧.这段时间看了一些博主的文章收获很大,特别是 ...

  9. java发送内嵌图片邮件

    前言: 博客系统中需要邮件服务的功能,以前写过类似的功能,不过功能太简单了,仅仅是发送文本内容,现在尝试一下发送内嵌图片邮件! 准备工作: 请参考:http://www.cnblogs.com/huj ...

  10. .NET平台开源项目速览(2)Compare .NET Objects对象比较组件

    .NET平台开源项目速览今天介绍一款小巧强大的对象比较组件.可以更详细的获取2个对象的差别,并记录具体差别,比较过程和要求可以灵活配置. .NET开源目录:[目录]本博客其他.NET开源项目文章目录 ...