How to: Create a Service That Requires Sessions

Sessions create a shared state between two or more endpoints that enables useful features such as callbacks, multi-hop security, and associations between clients and service instances. For more information about sessions in Windows Communication Foundation (WCF) applications, see Using Sessions.

To specify that a contract require its binding to support sessions

  1. Create a service contract with at least one operation. For an example of how to create a service contract, see How to: Define a Windows Communication Foundation Service Contract.

  2. Modify the System.ServiceModel.ServiceContractAttribute that declares the contract by setting the System.ServiceModel.ServiceContractAttribute.SessionMode property to either:

  3. Configure your service endpoint to use a binding that supports sessions. The following configuration example shows the use of the System.ServiceModel.WSDualHttpBinding, which supports a WS-ReliableMessaging session.

    <appSettings>
      <!-- use appSetting to configure base address provided by host -->
      <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
    </appSettings>
    <system.serviceModel>
      <services>
        <service 
          name="Microsoft.WCF.Documentation.DuplexHello"
          behaviorConfiguration="mex"
        >
          <endpoint
            address="/DuplexService"
            binding="wsDualHttpBinding"
            contract="Microsoft.WCF.Documentation.IDuplexHello"
           />
          <endpoint
            address=""
            binding="mexHttpBinding"
            contract="IMetadataExchange"
          />
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="mex" >
            <serviceMetadata httpGetEnabled="true" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
    <appSettings>
      <!-- use appSetting to configure base address provided by host -->
      <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
    </appSettings>
    <system.serviceModel>
      <services>
        <service 
          name="Microsoft.WCF.Documentation.DuplexHello"
          behaviorConfiguration="mex"
        >
          <endpoint
            address="/DuplexService"
            binding="wsDualHttpBinding"
            contract="Microsoft.WCF.Documentation.IDuplexHello"
           />
          <endpoint
            address=""
            binding="mexHttpBinding"
            contract="IMetadataExchange"
          />
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="mex" >
            <serviceMetadata httpGetEnabled="true" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
    
    <appSettings>
      <!-- use appSetting to configure base address provided by host -->
      <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
    </appSettings>
    <system.serviceModel>
      <services>
        <service 
          name="Microsoft.WCF.Documentation.DuplexHello"
          behaviorConfiguration="mex"
        >
          <endpoint
            address="/DuplexService"
            binding="wsDualHttpBinding"
            contract="Microsoft.WCF.Documentation.IDuplexHello"
           />
          <endpoint
            address=""
            binding="mexHttpBinding"
            contract="IMetadataExchange"
          />
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="mex" >
            <serviceMetadata httpGetEnabled="true" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
    
    <appSettings>
      <!-- use appSetting to configure base address provided by host -->
      <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
    </appSettings>
    <system.serviceModel>
      <services>
        <service 
          name="Microsoft.WCF.Documentation.DuplexHello"
          behaviorConfiguration="mex"
        >
          <endpoint
            address="/DuplexService"
            binding="wsDualHttpBinding"
            contract="Microsoft.WCF.Documentation.IDuplexHello"
           />
          <endpoint
            address=""
            binding="mexHttpBinding"
            contract="IMetadataExchange"
          />
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="mex" >
            <serviceMetadata httpGetEnabled="true" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
    
    <appSettings>
      <!-- use appSetting to configure base address provided by host -->
      <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
    </appSettings>
    <system.serviceModel>
      <services>
        <service 
          name="Microsoft.WCF.Documentation.DuplexHello"
          behaviorConfiguration="mex"
        >
          <endpoint
            address="/DuplexService"
            binding="wsDualHttpBinding"
            contract="Microsoft.WCF.Documentation.IDuplexHello"
           />
          <endpoint
            address=""
            binding="mexHttpBinding"
            contract="IMetadataExchange"
          />
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="mex" >
            <serviceMetadata httpGetEnabled="true" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
    

Example

The following example code shows how to specify a contract-level session requirement and use a configuration file to support that requirement with the System.ServiceModel.WSDualHttpBinding binding.


Imports System
Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.Threading

Namespace Microsoft.WCF.Documentation
    <ServiceContract(Name:="SampleDuplexHello", Namespace:="http://microsoft.wcf.documentation", _
                     CallbackContract:=GetType(IHelloCallbackContract), SessionMode:=SessionMode.Required)> _
    Public Interface IDuplexHello
        <OperationContract(IsOneWay:=True)> _
        Sub Hello(ByVal greeting As String)
    End Interface

  Public Interface IHelloCallbackContract
    <OperationContract(IsOneWay := True)> _
    Sub Reply(ByVal responseToGreeting As String)
  End Interface

  <ServiceBehaviorAttribute(InstanceContextMode:=InstanceContextMode.PerSession)> _
  Public Class DuplexHello
      Implements IDuplexHello

    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

    Public Sub Hello(ByVal greeting As String) Implements IDuplexHello.Hello
      Console.WriteLine("Caller sent: " & greeting)
      Console.WriteLine("Session ID: " & OperationContext.Current.SessionId)
      Console.WriteLine("Waiting two seconds before returning call.")
      ' Put a slight delay to demonstrate asynchronous behavior on client.
      Thread.Sleep(2000)
      Dim callerProxy As IHelloCallbackContract = OperationContext.Current.GetCallbackChannel(Of IHelloCallbackContract)()
            Dim response = "Service object " & Me.GetHashCode().ToString() & " received: " & greeting
      Console.WriteLine("Sending back: " & response)
      callerProxy.Reply(response)
    End Sub
  End Class
End Namespace
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;

namespace Microsoft.WCF.Documentation
{
  [ServiceContract(
    Name = "SampleDuplexHello",
    Namespace = "http://microsoft.wcf.documentation",
    CallbackContract = typeof(IHelloCallbackContract),
    SessionMode = SessionMode.Required
  )]
  public interface IDuplexHello
  {
    [OperationContract(IsOneWay = true)]
    void Hello(string greeting);
  }

  public interface IHelloCallbackContract
  {
    [OperationContract(IsOneWay = true)]
    void Reply(string responseToGreeting);
  }

  [ServiceBehaviorAttribute(InstanceContextMode=InstanceContextMode.PerSession)]
  public class DuplexHello : IDuplexHello
  {

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

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

    public void Hello(string greeting)
    {
      Console.WriteLine("Caller sent: " + greeting);
      Console.WriteLine("Session ID: " + OperationContext.Current.SessionId);
      Console.WriteLine("Waiting two seconds before returning call.");
      // Put a slight delay to demonstrate asynchronous behavior on client.
      Thread.Sleep(2000);
      IHelloCallbackContract callerProxy
        = OperationContext.Current.GetCallbackChannel<IHelloCallbackContract>();
      string response = "Service object " + this.GetHashCode().ToString() + " received: " + greeting;
      Console.WriteLine("Sending back: " + response);
      callerProxy.Reply(response);
    }
  }
}
<appSettings>
  <!-- use appSetting to configure base address provided by host -->
  <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
</appSettings>
<system.serviceModel>
  <services>
    <service 
      name="Microsoft.WCF.Documentation.DuplexHello"
      behaviorConfiguration="mex"
    >
      <endpoint
        address="/DuplexService"
        binding="wsDualHttpBinding"
        contract="Microsoft.WCF.Documentation.IDuplexHello"
       />
      <endpoint
        address=""
        binding="mexHttpBinding"
        contract="IMetadataExchange"
      />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="mex" >
        <serviceMetadata httpGetEnabled="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>
<appSettings>
  <!-- use appSetting to configure base address provided by host -->
  <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
</appSettings>
<system.serviceModel>
  <services>
    <service 
      name="Microsoft.WCF.Documentation.DuplexHello"
      behaviorConfiguration="mex"
    >
      <endpoint
        address="/DuplexService"
        binding="wsDualHttpBinding"
        contract="Microsoft.WCF.Documentation.IDuplexHello"
       />
      <endpoint
        address=""
        binding="mexHttpBinding"
        contract="IMetadataExchange"
      />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="mex" >
        <serviceMetadata httpGetEnabled="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>
<appSettings>
  <!-- use appSetting to configure base address provided by host -->
  <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
</appSettings>
<system.serviceModel>
  <services>
    <service 
      name="Microsoft.WCF.Documentation.DuplexHello"
      behaviorConfiguration="mex"
    >
      <endpoint
        address="/DuplexService"
        binding="wsDualHttpBinding"
        contract="Microsoft.WCF.Documentation.IDuplexHello"
       />
      <endpoint
        address=""
        binding="mexHttpBinding"
        contract="IMetadataExchange"
      />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="mex" >
        <serviceMetadata httpGetEnabled="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>
<appSettings>
  <!-- use appSetting to configure base address provided by host -->
  <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
</appSettings>
<system.serviceModel>
  <services>
    <service 
      name="Microsoft.WCF.Documentation.DuplexHello"
      behaviorConfiguration="mex"
    >
      <endpoint
        address="/DuplexService"
        binding="wsDualHttpBinding"
        contract="Microsoft.WCF.Documentation.IDuplexHello"
       />
      <endpoint
        address=""
        binding="mexHttpBinding"
        contract="IMetadataExchange"
      />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="mex" >
        <serviceMetadata httpGetEnabled="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>
    <appSettings>
      <!-- use appSetting to configure base address provided by host -->
      <add key="baseAddress" value="https://localhost:8080/ServiceMetadata" />
    </appSettings>
    <system.serviceModel>
      <services>
        <service 
          name="Microsoft.WCF.Documentation.DuplexHello"
          behaviorConfiguration="mex"
        >
          <endpoint
            address="/DuplexService"
            binding="wsDualHttpBinding"
            contract="Microsoft.WCF.Documentation.IDuplexHello"
           />
          <endpoint
            address=""
            binding="mexHttpBinding"
            contract="IMetadataExchange"
          />
        </service>
      </services>
      <behaviors>
        <serviceBehaviors>
          <behavior name="mex" >
            <serviceMetadata httpGetEnabled="true" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>

See Also

Reference

System.ServiceModel.ServiceContractAttribute
System.ServiceModel.ServiceContractAttribute.SessionMode
System.ServiceModel.SessionMode