WCF Message Inspectors and Response Headers
-
Thursday, September 02, 2010 3:57 PMI have a question about setting http headers in a wcf message inspector. My requirement is to record the size of the results of a wcf call by our partners to our server to a log file for analysis. When the call is made our partners send in various info in the http headers such as their vendor id. I can of course see this fine during the AfterReceiveRequest, but not in the BeforeSendReply call. Is there a way to set the response https headers during the AfterReceiveRequest? Or is there another way to do this?
Thanks,
David
Microsoft MVP
All Replies
-
Thursday, September 02, 2010 5:14 PM
You should be able to see (and set) the HTTP headers on both AfterReceiveRequest and BeforeSendReply. The code below does that - sets one response header (based on a request header) on both methods.
Another way, if you don't want (for cleanness purposes) to be dealing with an (yet inexistent) response on the AfterReceiveRequest method is to create a structure (such as Dictionary<string,string>) with the headers you want to add in the response, and return it in the end of the method. That value will be passed as the "correlationState" parameter to BeforeSendReply.
public class Post_6f14b940_28e2_464a_800d_99f190a22867 { [ServiceContract] public interface ITest { [OperationContract] string Echo(string text); } public class Service : ITest { public string Echo(string text) { return text; } } public class MyInspector : IEndpointBehavior, IDispatchMessageInspector { public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this); } public void Validate(ServiceEndpoint endpoint) { } public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { object prop; string myHeader; Console.WriteLine("In {0}", MethodBase.GetCurrentMethod().Name); if (!OperationContext.Current.IncomingMessageProperties.TryGetValue(HttpRequestMessageProperty.Name, out prop)) { myHeader = "Cannot read header from request"; } else { HttpRequestMessageProperty reqProp = (HttpRequestMessageProperty)prop; myHeader = reqProp.Headers["X-MyHeader"]; Console.WriteLine("X-MyHeader: {0}", myHeader); } if (!OperationContext.Current.OutgoingMessageProperties.TryGetValue(HttpResponseMessageProperty.Name, out prop)) { prop = new HttpResponseMessageProperty(); OperationContext.Current.OutgoingMessageProperties.Add(HttpResponseMessageProperty.Name, prop); } HttpResponseMessageProperty respProp = (HttpResponseMessageProperty)prop; respProp.Headers["X-MyResponseHeader"] = "Added from AfterReceiveRequest - " + myHeader; Console.WriteLine("Leaving {0}", MethodBase.GetCurrentMethod().Name); Console.WriteLine(); return null; } public void BeforeSendReply(ref Message reply, object correlationState) { object prop; string requestHeader = null; Console.WriteLine("In {0}", MethodBase.GetCurrentMethod().Name); if (OperationContext.Current.IncomingMessageProperties.TryGetValue(HttpRequestMessageProperty.Name, out prop)) { HttpRequestMessageProperty reqProp = (HttpRequestMessageProperty)prop; requestHeader = reqProp.Headers["X-MyHeader"]; Console.WriteLine("Got the request header: {0}", requestHeader); } if (!OperationContext.Current.OutgoingMessageProperties.TryGetValue(HttpResponseMessageProperty.Name, out prop)) { prop = new HttpResponseMessageProperty(); OperationContext.Current.OutgoingMessageProperties.Add(HttpResponseMessageProperty.Name, prop); } HttpResponseMessageProperty respProp = (HttpResponseMessageProperty)prop; respProp.Headers["X-MyResponseHeader2"] = "Added from BeforeSendReply - " + requestHeader; Console.WriteLine("Leaving {0}", MethodBase.GetCurrentMethod().Name); Console.WriteLine(); } } public static void Test() { string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "").Behaviors.Add(new MyInspector()); host.Open(); Console.WriteLine("Host opened"); ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress)); ITest proxy = factory.CreateChannel(); using (new OperationContextScope((IContextChannel)proxy)) { HttpRequestMessageProperty reqProp = new HttpRequestMessageProperty(); reqProp.Headers["X-MyHeader"] = "The value of my header"; OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, reqProp); Console.WriteLine(proxy.Echo("Hello")); HttpResponseMessageProperty respProp = (HttpResponseMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name]; Console.WriteLine("HTTP headers in response:"); foreach (string headerName in respProp.Headers.AllKeys) { Console.WriteLine(" {0}: {1}", headerName, respProp.Headers[headerName]); } } ((IClientChannel)proxy).Close(); factory.Close(); Console.Write("Press ENTER to close the host"); Console.ReadLine(); host.Close(); } }
- Proposed As Answer by Carlos Figueira Wednesday, September 08, 2010 6:38 PM
- Marked As Answer by Mog LiangModerator Friday, September 10, 2010 1:41 AM

