OperationContextScope

The OperationContextScope sample demonstrates how to send extra information on a Windows Communication Foundation (WCF) call using headers. In this sample, both the server and client are console applications.

Note

The setup procedure and build instructions for this sample are located at the end of this topic.

The sample demonstrates how a client can send additional information as a MessageHeader using OperationContextScope. An OperationContextScope object is created by scoping it to a channel. Headers that must be translated to the remote service can be added to the OutgoingMessageHeaders collection. Headers added to this collection can be retrieved on the service by accessing IncomingMessageHeaders. Its calls are made on multiple channels and then the headers added to the client only apply to the channel that was used to create the OperationContextScope.

MessageHeaderReader

This is the sample service that receives a message from the client and tries to look up the header in the IncomingMessageHeaders collection. The client passes the GUID that it sent in the header and the service retrieves the custom header and, if present, compares it with the GUID passed as the argument by the client.

public bool RetrieveHeader(string guid)
{
     MessageHeaders messageHeaderCollection =
             OperationContext.Current.IncomingMessageHeaders;
     String guidHeader = null;

     Console.WriteLine("Trying to check if IncomingMessageHeader " +
               " collection contains header with value {0}", guid);
     if (messageHeaderCollection.FindHeader(
                       CustomHeader.HeaderName,
                       CustomHeader.HeaderNamespace) != -1)
     {
          guidHeader = messageHeaderCollection.GetHeader<String>(
           CustomHeader.HeaderName, CustomHeader.HeaderNamespace);
     }
     else
     {
          Console.WriteLine("No header was found");
     }
     if (guidHeader != null)
     {
          Console.WriteLine("Found header with value {0}. "+
         "Does it match with GUID sent as parameter: {1}",
          guidHeader, guidHeader.Equals(guid));
      }

      Console.WriteLine();
      //Return true if header is present and equals the guid sent by
      // client as argument
      return (guidHeader != null && guidHeader.Equals(guid));
}

MessageHeaderClient

This is the client implementation that uses the proxy generated by ServiceModel Metadata Utility Tool (Svcutil.exe) to communicate with the remote service. It first creates two proxy objects of MessageHeaderReaderClient.

//Create two clients to the remote service.
MessageHeaderReaderClient client1 = new MessageHeaderReaderClient();
MessageHeaderReaderClient client2 = new MessageHeaderReaderClient();

Client then creates an OperationContextScope and scopes it to client1. It adds a MessageHeader to OutgoingMessageHeaders and invokes one call on both clients. It ensures that the header is sent only on client1 and not on client2 by checking the return value from the RetrieveHeader call.

using (new OperationContextScope(client1.InnerChannel))
{
    //Create a new GUID that is sent as the header.
    String guid = Guid.NewGuid().ToString();

    //Create a MessageHeader for the GUID we just created.
    MessageHeader customHeader = MessageHeader.CreateHeader(CustomHeader.HeaderName, CustomHeader.HeaderNamespace, guid);

    //Add the header to the OutgoingMessageHeader collection.
    OperationContext.Current.OutgoingMessageHeaders.Add(customHeader);

    //Now call RetrieveHeader on both the proxies. Since the OperationContextScope is tied to
    //client1's InnerChannel, the header should only be added to calls made on that client.
    //Calls made on client2 should not be sending the header across even though the call
    //is made in the same OperationContextScope.
    Console.WriteLine("Using client1 to send message");
    Console.WriteLine("Did server retrieve the header? : Actual: {0}, Expected: True", client1.RetrieveHeader(guid));

    Console.WriteLine();
    Console.WriteLine("Using client2 to send message");
    Console.WriteLine("Did server retrieve the header? : Actual: {0}, Expected: False", client2.RetrieveHeader(guid));
}

This sample is self-hosted. The following sample output from running the sample is provided:

Prompt> Service.exe
The service is ready.
Press <ENTER> to terminate service.

Trying to check if IncomingMessageHeader collection contains header with value 2239da67-546f-42d4-89dc-8eb3c06215d8
Found header with value 2239da67-546f-42d4-89dc-8eb3c06215d8. Does it match with GUID sent as parameter: True

Trying to check if IncomingMessageHeader collection contains header with value 2239da67-546f-42d4-89dc-8eb3c06215d8
No header was found

Prompt>Client.exe
Using client1 to send message
Did server retrieve the header? : Actual: True, Expected: True

Using client2 to send message
Did server retrieve the header? : Actual: False, Expected: False

Press <ENTER> to terminate client.

To set up, build, and run the sample

  1. Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  2. To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  3. To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.