{
using (SampleServiceProxy proxy = new SampleServiceProxy())
{ ... }
}
Then you get to use the current OperationContext to add your message header to -- don't create a new context. The new OperationContextScope did that for you. Like so:
using (OperationContextScope scope = new OperationContextScope())
{
// This code uses duplex communication, hence the passed InstanceContext.
using (SampleServiceProxy proxy = new SampleServiceProxy(new InstanceContext(this)))
{
try
{
MessageHeader header
= MessageHeader.CreateHeader(
"Service-Bound-RequestReplyHeader",
"http://Microsoft.WCF.Documentation",
"Custom Happy Value."
);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
Note: Recall that if you receive the following error using duplex over http, that you should adopt one of the strategies mentioned by Kenny here. I turn IIS off for a while. :-)
"There was a communication problem. HTTP could not register URL http://+:80/Temporary_Listen_Addresses/354173be-86af-4fdb-a5c2-606fb848d782/ because TCP port 80 is being used by another application."
Back to stuff. Here's the client code I used to test this all out. It uses duplex communication (to demonstrate one-way using a client instead of two services), but it all works the same.
Client:
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading;
public class Client : ISampleServiceCallback
{
ManualResetEvent wait = null;
Client()
{
this.wait = new ManualResetEvent(false);
}
public static void Main()
{
Client client = new Client();
client.Run();
}
void Run()
{
using (OperationContextScope scope = new OperationContextScope())
{
// Picks up configuration from the config file.
using (SampleServiceProxy proxy = new SampleServiceProxy(new InstanceContext(this)))
{
try
{
MessageHeader header
= MessageHeader.CreateHeader(
"Service-Bound-RequestReplyHeader",
"http://Microsoft.WCF.Documentation",
"Custom Happy Value."
);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
// Making calls.
Console.WriteLine("Enter the greeting to send: ");
string greeting = Console.ReadLine();
// Request-Reply
Console.WriteLine(proxy.RequestReply(greeting));
this.WriteHeaders(OperationContext.Current.IncomingMessageHeaders);
header = MessageHeader.CreateHeader(
"Service-Bound-OneWayHeader",
"http://Microsoft.WCF.Documentation",
"Different Happy Value."
);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
// One-way
proxy.Push(greeting);
this.wait.WaitOne();
// Done with service.
proxy.Close();
Console.WriteLine("Done!");
Console.ReadLine();
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
}
catch(CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message);
Console.ReadLine();
}
}
}
}
#region ISampleServiceCallback Members
public void PushBack(string msg)
{
Console.WriteLine("Service said: " + msg);
this.WriteHeaders(OperationContext.Current.IncomingMessageHeaders);
this.wait.Set();
}
void WriteHeaders(MessageHeaders headers)
{
foreach (IMessageHeaderInfo h in headers)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("IncomingHeader:");
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("\t" + h.Actor);
Console.WriteLine("\t" + h.Name);
Console.WriteLine("\t" + h.Namespace);
Console.WriteLine("\t" + h.Relay);
Console.ResetColor();
}
}
#endregion
}
and the service:
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;
namespace Microsoft.WCF.Documentation
{
[ServiceContract(
Namespace="http://Microsoft.WCF.Documentation",
CallbackContract=typeof(IClientCallbackContract),
Session=true
)]
public interface ISampleService{
[OperationContract(IsOneWay=true)]
void Push(string msg);
[OperationContract]
string RequestReply(string message);
}
interface IClientCallbackContract
{
[OperationContract(IsOneWay = true)]
void PushBack(string msg);
}
class SampleService : ISampleService
{
#region ISampleService Members
public string RequestReply(string message)
{
Console.WriteLine("Proxy: " + message);
MessageHeaders incomingHeaders = OperationContext.Current.IncomingMessageHeaders;
this.WriteHeaders(OperationContext.Current.IncomingMessageHeaders);
MessageHeader outBoundHeader
= MessageHeader.CreateHeader("Client-Bound-Reply-Header", "http://Microsoft.WCF.Documentation", "Custom Outbound Header");
OperationContext.Current.OutgoingMessageHeaders.Add(outBoundHeader);
Console.WriteLine("OutgoingHeader: ");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(outBoundHeader.ToString());
Console.ResetColor();
return "Received your greeting.";
}
public void Push(string msg)
{
Console.WriteLine("Proxy: " + msg);
this.WriteHeaders(OperationContext.Current.IncomingMessageHeaders);
MessageHeader outBoundHeader
= MessageHeader.CreateHeader(
"Client-Bound-One-Way-Header",
"http://Microsoft.WCF.Documentation",
"Custom Outbound Header"
);
OperationContext.Current.OutgoingMessageHeaders.Add(outBoundHeader);
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("OutgoingHeader:");
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine(outBoundHeader.ToString());
Console.ResetColor();
OperationContext.Current.GetCallbackChannel<IClientCallbackContract>().PushBack("Here's something to examine in response.");
}
void WriteHeaders(MessageHeaders headers)
{
foreach (IMessageHeaderInfo h in headers)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("IncomingHeader:");
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("\t" + h.Actor);
Console.WriteLine("\t" + h.Name);
Console.WriteLine("\t" + h.Namespace);
Console.WriteLine("\t" + h.Relay);
Console.ResetColor();
}
}
#endregion
}
}
Hope this helps someone. It helps me write the documentation, that's for sure.