none
Modify The Message Body

    Question

  •  

    Hi,

    I have create a client inspector:

    public class ClientOutputMessageInspector : IClientMessageInspector

    {

    #region IClientMessageInspector Members

    public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)

    {

    return;

    }

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)

    {

    string action = request.Headers.GetHeader<string>("Action", request.Headers[0].Namespace);

    if (action.Contains("SendMessage"))

    {

    }

    return null;

    }

    #endregion

    }

     

    In the BeforeSendRequest I want to modify the body content.  I need an example of how to change it.

    Thanks for your help.

     

    Guy

    Tuesday, March 18, 2008 9:20 AM

Answers

  • This is an example of changing the message body:

     

    public class Post3022028

    {

        [ServiceContract]

        public interface ITest

        {

            [OperationContract]

            string SendMessage(string text);

        }

        public class Service : ITest

        {

            public string SendMessage(string text)

            {

                return text;

            }

        }

        static Binding GetBinding()

        {

            BasicHttpBinding result = new BasicHttpBinding();

            return result;

        }

        public class ClientOutputMessageInspector : IClientMessageInspector, IEndpointBehavior

        {

            #region IClientMessageInspector Members

            public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)

            {

                return;

            }

            public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)

            {

                string action = request.Headers.GetHeader<string>("Action", request.Headers[0].Namespace);

                if (action.Contains("SendMessage"))

                {

                    XmlDocument doc = new XmlDocument();

                    MemoryStream ms = new MemoryStream();

                    XmlWriter writer = XmlWriter.Create(ms);

                    request.WriteMessage(writer);

                    writer.Flush();

                    ms.Position = 0;

                    doc.Load(ms);

                    ChangeMessage(doc);

                    ms.SetLength(0);

                    writer = XmlWriter.Create(ms);

                    doc.WriteTo(writer);

                    writer.Flush();

                    ms.Position = 0;

                    XmlReader reader = XmlReader.Create(ms);

                    request = Message.CreateMessage(reader, int.MaxValue, request.Version);

                }

                return null;

            }

            void ChangeMessage(XmlDocument doc)

            {

                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:Body/tempuriTongue TiedendMessage/tempuri:text", nsManager);

                if (node != null)

                {

                    XmlText text = node.FirstChild as XmlText;

                    if (text != null)

                    {

                        text.Value = "Modified: " + text.Value;

                    }

                }

            }

            #endregion

            #region IEndpointBehavior Members

            public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)

            {

            }

            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)

            {

                clientRuntime.MessageInspectors.Add(this);

            }

            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)

            {

            }

            public void Validate(ServiceEndpoint endpoint)

            {

            }

            #endregion

        }

        public static void Test()

        {

            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";

            ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));

            host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");

            host.Open();

            Console.WriteLine("Host opened");

     

            ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));

            factory.Endpoint.Behaviors.Add(new ClientOutputMessageInspector());

            ITest proxy = factory.CreateChannel();

            Console.WriteLine(proxy.SendMessage("Hello"));

            ((IClientChannel)proxy).Close();

            factory.Close();

     

            Console.Write("Press ENTER to close the host");

            Console.ReadLine();

            host.Close();

        }

    }

     

    Tuesday, March 18, 2008 7:40 PM

All replies

  • Here is a blog which explains about something on similar lines:

    It adds custom headers to every WCF call.

     

    http://weblogs.asp.net/avnerk/archive/2006/04/26/444013.aspx

     

    Tuesday, March 18, 2008 6:53 PM
  • This is an example of changing the message body:

     

    public class Post3022028

    {

        [ServiceContract]

        public interface ITest

        {

            [OperationContract]

            string SendMessage(string text);

        }

        public class Service : ITest

        {

            public string SendMessage(string text)

            {

                return text;

            }

        }

        static Binding GetBinding()

        {

            BasicHttpBinding result = new BasicHttpBinding();

            return result;

        }

        public class ClientOutputMessageInspector : IClientMessageInspector, IEndpointBehavior

        {

            #region IClientMessageInspector Members

            public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)

            {

                return;

            }

            public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)

            {

                string action = request.Headers.GetHeader<string>("Action", request.Headers[0].Namespace);

                if (action.Contains("SendMessage"))

                {

                    XmlDocument doc = new XmlDocument();

                    MemoryStream ms = new MemoryStream();

                    XmlWriter writer = XmlWriter.Create(ms);

                    request.WriteMessage(writer);

                    writer.Flush();

                    ms.Position = 0;

                    doc.Load(ms);

                    ChangeMessage(doc);

                    ms.SetLength(0);

                    writer = XmlWriter.Create(ms);

                    doc.WriteTo(writer);

                    writer.Flush();

                    ms.Position = 0;

                    XmlReader reader = XmlReader.Create(ms);

                    request = Message.CreateMessage(reader, int.MaxValue, request.Version);

                }

                return null;

            }

            void ChangeMessage(XmlDocument doc)

            {

                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:Body/tempuriTongue TiedendMessage/tempuri:text", nsManager);

                if (node != null)

                {

                    XmlText text = node.FirstChild as XmlText;

                    if (text != null)

                    {

                        text.Value = "Modified: " + text.Value;

                    }

                }

            }

            #endregion

            #region IEndpointBehavior Members

            public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)

            {

            }

            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)

            {

                clientRuntime.MessageInspectors.Add(this);

            }

            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)

            {

            }

            public void Validate(ServiceEndpoint endpoint)

            {

            }

            #endregion

        }

        public static void Test()

        {

            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";

            ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));

            host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");

            host.Open();

            Console.WriteLine("Host opened");

     

            ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));

            factory.Endpoint.Behaviors.Add(new ClientOutputMessageInspector());

            ITest proxy = factory.CreateChannel();

            Console.WriteLine(proxy.SendMessage("Hello"));

            ((IClientChannel)proxy).Close();

            factory.Close();

     

            Console.Write("Press ENTER to close the host");

            Console.ReadLine();

            host.Close();

        }

    }

     

    Tuesday, March 18, 2008 7:40 PM
  • I have also used similar way to modify my message

    Only problem i am having is that in the messages.svclog I am not able to see the Body of the envelope

    it appears as .... Stream .....

    Looks like stream is open

     public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel)
                {
                    request = TransformOne(request);
                    return null;
                }
    
    
     private Message TransformOne(Message reply)
                {
                    var lstMessages = new List<string> { "DeliveryApptCreateRequest", "DeliveryApptUpdateRequest" };
    
    
                    Message newReply;
                    using (var ms = new MemoryStream())
                    {
                        XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(ms);
                        reply.WriteMessage(writer);
                        writer.Flush();
                        ms.Position = 0;
                        var doc = new XmlDocument();
                        doc.Load(ms);
                        if (doc.GetElementsByTagName("DeliveryApptCreateRequest").Count > 0)
                        {
                            string strNamespaceName = "b";
                            strNamespaceName = GetUspsSummaryNamespacePrefix(doc, strNamespaceName);
                            var myElement = (XmlElement)(doc.GetElementsByTagName("DeliveryApptCreateRequest").Item(0));
                            myElement.SetAttribute("xmlns:" + strNamespaceName,
                                                   "http://idealliance.org/Specs/mailxml12.0a/mailxml_tm");
    
                            var nms = new MemoryStream();
                            XmlDictionaryWriter newWriter = XmlDictionaryWriter.CreateTextWriter(nms);
                            doc.WriteTo(newWriter);
                            newWriter.Flush();
                            nms.Position = 0;
                            var reader = XmlDictionaryReader.CreateTextReader(nms, XmlDictionaryReaderQuotas.Max);
                            newReply = Message.CreateMessage(reader, int.MaxValue, reply.Version);
                        }
                        else
                        {
                            newReply = reply;
                        }
                    }
                    return newReply;
                }

    What should i do to view the logging


    Kamran Shahid Principle Engineer Development (MCP,MCAD,MCSD.NET,MCTS,MCPD.net[web])

    Wednesday, June 20, 2012 11:43 AM