BeforeSendRequest question
-
Monday, June 22, 2009 4:19 PM
Hi Everyone -
I am trying to perform some modifications to the message in the BeforeSendRequest event. What would be good is if I could just load the message into an XmlDocument, perform the changes that I need, and then update the message that is passed in by ref.
I can load the XmlDocument; however, I don't see a clear way to use to get that to update the message reference that is passed into the method.
Is this possible? Is there a better way to do this?
Thanks.
Ken
All Replies
-
Monday, June 22, 2009 6:51 PM
You can definitely do that, just open the XmlDocument as a reader, and create a new message from it. The example below shows how this can be done:
public class Post_f01a7120_0351_4be2_b45f_b7fb382c8a1f { [ServiceContract] public interface ITest { [OperationContract] string Echo(string input); } [ServiceBehavior(IncludeExceptionDetailInFaults = true)] public class Service : ITest { public string Echo(string input) { return input; } } public class MyInspector : IDispatchMessageInspector, IEndpointBehavior { public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { return null; } public void BeforeSendReply(ref Message reply, object correlationState) { MemoryStream ms = new MemoryStream(); XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(ms); reply.WriteMessage(writer); writer.Flush(); ms.Position = 0; XmlDocument doc = new XmlDocument(); doc.Load(ms); // change XmlDocument XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable); nsManager.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/"); nsManager.AddNamespace("tempuri", "http://tempuri.org/"); XmlNode node = doc.SelectSingleNode("/s:Envelope/s:Body/tempuri:EchoResponse/tempuri:EchoResult", nsManager); if (node != null) { node.InnerText = node.InnerText + " - modified"; } ms = new MemoryStream(); writer = XmlDictionaryWriter.CreateTextWriter(ms); doc.WriteTo(writer); writer.Flush(); ms.Position = 0; XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(ms, XmlDictionaryReaderQuotas.Max); Message newReply = Message.CreateMessage(reader, int.MaxValue, reply.Version); reply = newReply; } 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 static void Test() { string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), ""); endpoint.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(); Console.WriteLine(proxy.Echo("Hello world")); ((IClientChannel)proxy).Close(); factory.Close(); Console.WriteLine("Press ENTER to close"); Console.ReadLine(); host.Close(); } }- Marked As Answer by kennj Tuesday, June 23, 2009 12:36 AM
-
Tuesday, June 23, 2009 12:36 AMThat is exactly what I needed. Thanks!
-
Tuesday, October 18, 2011 2:24 PMI am trying to do the same thing with the IClientMessageInspector. I have looked around online and found examples but I can't seem to get this down. I also need to add message level security through .NET code. The service requires that I provide UserNameToken credentials. I have been working on this for about 3-4 days now and I am running out of time. Any help would be greatly appreciated.

