指定服务运行时行为

在已经设计(Designing Service Contracts)并实现服务协定(Implementing Service Contracts)之后,就可以配置服务运行时的操作行为。 本主题讨论系统提供的服务和操作行为,并说明在何处查找更多信息来创建新行为。 尽管有些行为是作为属性应用的,但很多行为是使用应用程序配置文件或以编程方式应用的。 有关配置服务应用程序的详细信息,请参阅配置服务

概述

协定定义相应类型的服务的输入、输出、数据类型和功能。 实现一个服务协定将会创建一个类,当使用某个地址的绑定对该类进行配置时,该类会满足其实现的协定。 客户端了解协定、绑定和地址信息等所有信息,如果没有它们,客户端将不能使用相应服务。

但是,操作详细信息(例如,线程处理问题或实例管理)对客户端是不透明的。 在已实现服务协定之后,就可以使用行为 配置大量操作特征。 行为是一些对象,可通过设置运行时属性或通过在运行时中插入自定义类型来修改 Windows Communication Foundation (WCF) 运行时。 有关通过创建用户定义的行为来修改运行时的详细信息,请参阅扩展 ServiceHost 和服务模型层

System.ServiceModel.ServiceBehaviorAttributeSystem.ServiceModel.OperationBehaviorAttribute 属性是用途最广泛的行为,公开了最常请求的操作功能。 因为它们是属性,所以应将其应用于服务或操作实现。 其他行为(例如, System.ServiceModel.Description.ServiceMetadataBehaviorSystem.ServiceModel.Description.ServiceDebugBehavior)通常是使用应用程序配置文件进行应用的,但可以以编程方式使用它们。

本主题提供 ServiceBehaviorAttributeOperationBehaviorAttribute 属性的概述,描述行为可以操作的不同范围,并为很多系统提供的不同范围的行为(WCF 开发人员可能此感兴趣)提供快速说明。

ServiceBehaviorAttribute 和 OperationBehaviorAttribute

最重要的行为是 ServiceBehaviorAttributeOperationBehaviorAttribute 属性,可以使用这两个属性来控制以下各项:

  • 实例生存期

  • 并发和同步支持

  • 配置行为

  • 事务行为

  • 序列化行为

  • 元数据转换

  • 会话生存期

  • 地址筛选和标头处理

  • 模拟

  • 若要使用这些属性,请使用适合对应范围的属性来标记服务或操作实现并设置属性。 例如,下面的代码示例演示了一个操作实现,该实现使用 OperationBehaviorAttribute.Impersonation 属性来要求此操作的调用方支持模拟。

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;

namespace Microsoft.WCF.Documentation
{
  [ServiceContract(
    Name="SampleHello",
    Namespace="http://microsoft.wcf.documentation"
  )]
  public interface IHello
  {
    [OperationContract]
    string Hello(string greeting);
  }

  public class HelloService : IHello
  {

    public HelloService()
    {
      Console.WriteLine("Service object created: " + this.GetHashCode().ToString());
    }

    ~HelloService()
    {
      Console.WriteLine("Service object destroyed: " + this.GetHashCode().ToString());
    }

    [OperationBehavior(Impersonation=ImpersonationOption.Required)]
    public string Hello(string greeting)
    {
      Console.WriteLine("Called by: " + Thread.CurrentPrincipal.Identity.Name);
      Console.WriteLine("IsAuthenticated: " + Thread.CurrentPrincipal.Identity.IsAuthenticated.ToString());
      Console.WriteLine("AuthenticationType: " + Thread.CurrentPrincipal.Identity.AuthenticationType.ToString());

      Console.WriteLine("Caller sent: " + greeting);
      Console.WriteLine("Sending back: Hi, " + Thread.CurrentPrincipal.Identity.Name);
      return "Hi, " + Thread.CurrentPrincipal.Identity.Name;
    }
  }
}
Imports System.ServiceModel
Imports System.Threading

Namespace Microsoft.WCF.Documentation
    <ServiceContract(Name:="SampleHello", Namespace:="http://microsoft.wcf.documentation")> _
    Public Interface IHello
        <OperationContract> _
        Function Hello(ByVal greeting As String) As String
    End Interface

    Public Class HelloService
        Implements IHello

        Public Sub New()
            Console.WriteLine("Service object created: " & Me.GetHashCode().ToString())
        End Sub

        Protected Overrides Sub Finalize()
            Console.WriteLine("Service object destroyed: " & Me.GetHashCode().ToString())
        End Sub

        <OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
        Public Function Hello(ByVal greeting As String) As String Implements IHello.Hello
            Console.WriteLine("Called by: " & Thread.CurrentPrincipal.Identity.Name)
            Console.WriteLine("IsAuthenticated: " & Thread.CurrentPrincipal.Identity.IsAuthenticated.ToString())
            Console.WriteLine("AuthenticationType: " & Thread.CurrentPrincipal.Identity.AuthenticationType.ToString())

            Console.WriteLine("Caller sent: " & greeting)
            Console.WriteLine("Sending back: Hi, " & Thread.CurrentPrincipal.Identity.Name)
            Return "Hi, " & Thread.CurrentPrincipal.Identity.Name
        End Function
    End Class
End Namespace

许多属性需要来自绑定的附加支持。 例如,要求来自客户端的事务的操作必须配置为使用支持流事务的绑定。

已知的单一实例服务

可以使用 ServiceBehaviorAttributeOperationBehaviorAttribute 属性来控制某些生存期,包括 InstanceContext 的生存期和实现操作的服务对象的生存期。

例如, ServiceBehaviorAttribute.InstanceContextMode 属性控制释放 InstanceContext 的频率,而 OperationBehaviorAttribute.ReleaseInstanceModeServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete 属性控制释放服务对象的时间。

但是,也可以自己创建服务对象以及创建使用该对象的服务主机。 为此,您还必须将 ServiceBehaviorAttribute.InstanceContextMode 属性设置为 Single ,否则在打开该服务主机时将引发异常。

可使用 ServiceHost(Object, Uri[]) 构造函数创建此类服务。 当您希望提供一个特定的对象实例供单一实例服务使用时,可以使用它作为实现自定义 System.ServiceModel.Dispatcher.IInstanceContextInitializer 的替代方法。 当服务实现类型难以构造时(例如,它没有实现无参数公共构造函数),可以使用此重载。

请注意,在为此构造函数提供对象时,一些与 Windows Communication Foundation (WCF) 实例化行为相关的功能将有不同的工作方式。 例如,在提供已知对象实例时,调用 InstanceContext.ReleaseServiceInstance 没有任何效果。 同样,也将忽略所有其他实例释放机制。 ServiceHost 类的行为总是像对于所有操作都将 OperationBehaviorAttribute.ReleaseInstanceMode 属性设置为 ReleaseInstanceMode.None 一样。

其他服务、终结点、协定和操作行为

服务行为(如 ServiceBehaviorAttribute 属性)在整个服务中运行。 例如,如果将 ServiceBehaviorAttribute.ConcurrencyMode 属性设置为 ConcurrencyMode.Multiple ,则必须自己在服务中的每个操作内处理线程同步问题。 终结点行为在终结点上运行,许多系统提供的终结点行为是针对客户端功能的。 协定行为在协定级别上运行,并且操作行为修改操作传递。

许多这些行为在属性上进行实现,并且可以像操作 ServiceBehaviorAttributeOperationBehaviorAttribute 属性一样使用它们(通过将这些行为应用于相应的服务类或操作实现)。 其他行为(如 ServiceMetadataBehaviorServiceDebugBehavior 对象)通常使用应用程序配置文件进行应用,但也可以以编程方式使用它们。

例如,可以通过使用 ServiceMetadataBehavior 对象来配置元数据的发布。 下面的应用程序配置文件演示了最常见的用法。

<configuration>
  <system.serviceModel>
    <services>
      <service 
        name="Microsoft.WCF.Documentation.SampleService"
        behaviorConfiguration="metadataSupport"
      >
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080/SampleService" />
          </baseAddresses>
        </host>
        <endpoint
          address=""
          binding="wsHttpBinding"
          contract="Microsoft.WCF.Documentation.ISampleService"
        />
        <!-- Adds a WS-MetadataExchange endpoint at -->
        <!-- "http://localhost:8080/SampleService/mex" -->
        <endpoint
           address="mex"
           binding="mexHttpBinding"
           contract="IMetadataExchange"
        />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
      <behavior name="metadataSupport">
        <!-- Enables the IMetadataExchange endpoint in services that -->
        <!-- use "metadataSupport" in their behaviorConfiguration attribute. -->
        <!-- In addition, the httpGetEnabled and httpGetUrl attributes publish -->
        <!-- Service metadata for retrieval by HTTP/GET at the address -->
        <!-- "http://localhost:8080/SampleService?wsdl" -->
        <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  </system.serviceModel>
</configuration>

下面的章节描述了许多最有用的系统提供的行为,您可以使用这些行为修改服务或客户端的运行时传递。 请参见相应的参考主题以确定如何使用每种行为。

服务行为

下面的行为在服务上运行。

终结点行为

下面的行为在终结点上运行。 许多这些行为在客户端应用程序中使用。

协定行为

DeliveryRequirementsAttribute。 指定绑定必须提供给服务或客户端实现的功能要求。

操作行为

下面的操作行为指定操作的序列化和事务控制。

请参阅