Specifying Service Run-Time Behavior

Once you have designed a service contract (Designing Service Contracts) and implemented your service contract (Implementing Service Contracts) you can configure the operation behavior of the service runtime. This topic discusses system-provided service and operation behaviors and describes where to find more information to create new behaviors. While some behaviors are applied as attributes, many are applied using an application configuration file or programmatically. For more information about configuring your service application, see Configuring Services.

Overview

The contract defines the inputs, outputs, data types, and capabilities of a service of that type. Implementing a service contract creates a class that, when configured with a binding at an address, fulfills the contract it implements. Contractual, binding, and address information are all known by the client; without them, the client cannot make use of the service.

However, operation specifics, such as threading issues or instance management, are opaque to clients. Once you have implemented your service contract, you can configure a large number of operation characteristics by using behaviors. Behaviors are objects that modify the Windows Communication Foundation (WCF) runtime by either setting a runtime property or by inserting a customization type into the runtime. For more information about modifying the runtime by creating user-defined behaviors, see Extending ServiceHost and the Service Model Layer.

The System.ServiceModel.ServiceBehaviorAttribute and System.ServiceModel.OperationBehaviorAttribute attributes are the most widely useful behaviors and expose the most commonly requested operation features. Because they are attributes, you apply them to the service or operation implementation. Other behaviors, such as the System.ServiceModel.Description.ServiceMetadataBehavior or System.ServiceModel.Description.ServiceDebugBehavior, are typically applied using an application configuration file, although you can use them programmatically.

This topic provides an overview of the ServiceBehaviorAttribute and OperationBehaviorAttribute attributes, describes the various scopes at which behaviors can operate, and provides a quick description of many of the system-provided behaviors at the various scopes that may be of interest to WCF developers.

ServiceBehaviorAttribute and OperationBehaviorAttribute

The most important behaviors are the ServiceBehaviorAttribute and OperationBehaviorAttribute attributes, which you can use to control:

  • Instance lifetimes

  • Concurrency and synchronization support

  • Configuration behavior

  • Transaction behavior

  • Serialization behavior

  • Metadata transformation

  • Session lifetime

  • Address filtering and header processing

  • Impersonation

  • To use these attributes, mark the service or operation implementation with the attribute appropriate to that scope and set the properties. For example, the following code example shows an operation implementation that uses the OperationBehaviorAttribute.Impersonation property to require that callers of this operation support 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

Many of the properties require additional support from the binding. For example, an operation that requires a transaction from the client must be configured to use a binding that supports flowed transactions.

Well-Known Singleton Services

You can use the ServiceBehaviorAttribute and OperationBehaviorAttribute attributes to control certain lifetimes, both of the InstanceContext and of the service objects that implement the operations.

For example, the ServiceBehaviorAttribute.InstanceContextMode property controls how often the InstanceContext is released, and the OperationBehaviorAttribute.ReleaseInstanceMode and ServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete properties control when the service object is released.

However, you can also create a service object yourself and create the service host using that object. To do so, you must also set the ServiceBehaviorAttribute.InstanceContextMode property to Single or an exception is thrown when the service host is opened.

Use the ServiceHost(Object, Uri[]) constructor to create such a service. It provides an alternative to implementing a custom System.ServiceModel.Dispatcher.IInstanceContextInitializer when you wish to provide a specific object instance for use by a singleton service. You can use this overload when your service implementation type is difficult to construct (for example, if it does not implement a parameterless public constructor).

Note that when an object is provided to this constructor, some features related to the Windows Communication Foundation (WCF) instancing behavior work differently. For example, calling InstanceContext.ReleaseServiceInstance has no effect when a well-known object instance is provided. Similarly, any other instance release mechanism is ignored. The ServiceHost class always behaves as if the OperationBehaviorAttribute.ReleaseInstanceMode property is set to ReleaseInstanceMode.None for all operations.

Other Service, Endpoint, Contract, and Operation Behaviors

Service behaviors, such as the ServiceBehaviorAttribute attribute, operate across an entire service. For example, if you set the ServiceBehaviorAttribute.ConcurrencyMode property to ConcurrencyMode.Multiple you must handle thread synchronization issues inside each operation in that service yourself. Endpoint behaviors operate across an endpoint; many of the system-provided endpoint behaviors are for client functionality. Contract behaviors operate at the contract level, and operation behaviors modify operation delivery.

Many of these behaviors are implemented on attributes, and you make use of them as you do the ServiceBehaviorAttribute and OperationBehaviorAttribute attributes—by applying them to the appropriate service class or operation implementation. Other behaviors, such as the ServiceMetadataBehavior or ServiceDebugBehavior objects, are typically applied using an application configuration file, although they can also be used programmatically.

For example, the publication of metadata is configured by using the ServiceMetadataBehavior object. The following application configuration file shows the most common usage.

<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>

The following sections describe many of the most useful system-provided behaviors that you can use to modify the runtime delivery of your service or client. See the reference topic to determine how to use each one.

Service Behaviors

The following behaviors operate on services.

Endpoint Behaviors

The following behaviors operate on endpoints. Many of these behaviors are used in client applications.

Contract Behaviors

DeliveryRequirementsAttribute. Specifies the feature requirements that bindings must provide to the service or client implementation.

Operation Behaviors

The following operation behaviors specify serialization and transaction controls for operations.

See also