title: EDIT SOAP of a WCF Service using IClientMessageInspector
body: <p>In my WCF Service, I want to edit the SOAP in BeforeSendRequest and AfterReceiveReply of IClientMessageInspector.</p>
  
  <p>I have created a custom Behavior like this:</p>
  
  <pre><code>public class MyBehavior : BehaviorExtensionElement, IEndpointBehavior
  {
  }
  </code></pre>
  
  <p>in the class MyBehavior, I implemented IEndpointBehavior method Like below code:</p>
  
  <pre><code>public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
  {
      MyInspector inspector = new MyInspector();
      clientRuntime.MessageInspectors.Add(inspector);
  }
  </code></pre>
  
  <p>MyInspector is nothing but the class which is inherited from IClientMessageInspector.</p>
  
  <p>Now, my question is: ApplyClientBehavior of IEndpointBehavior is not getting fired. But at wcf client, when I add a reference of the project where the MyBehavior class is present and write below code at client side:</p>
  
  <pre><code>c.Endpoint.Behaviors.Add(new MyBehavior());
  </code></pre>
  
  <p>It works fine. I mean the Apply Client Behavior method getting fired.</p>
  
  <p>I dont want to ask my clients to add this Behavior manually and I want this to happen automatically. How can I achive this?</p>
  
  <p>Here is the full code:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Xml;
  using System.ServiceModel.Configuration;
  using System.ServiceModel.Description;
  using System.ServiceModel.Dispatcher;
  using System.ServiceModel.Channels;
  using System.IO;
  
  namespace MethodChangeService
  {
     public class MyInspector : IClientMessageInspector
      {
          public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
          {
              XmlDocument doc = new XmlDocument();
              MemoryStream ms = new MemoryStream();
              XmlWriter writer = XmlWriter.Create(ms);
              reply.WriteMessage(writer);
              writer.Flush();
              ms.Position = 0;
              doc.Load(ms);
              ChangeMessage(doc, false);
              ms.SetLength(0);
              writer = XmlWriter.Create(ms);
              doc.WriteTo(writer);
              writer.Flush();
              ms.Position = 0;
              XmlReader reader = XmlReader.Create(ms);
              reply = Message.CreateMessage(reader, int.MaxValue, reply.Version);
  
          }
  
          public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
          {
              string action = request.Headers.GetHeader&lt;string&gt;("Action", request.Headers[0].Namespace);
              if (action.Contains("GetData"))
              {
                  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, true);
                  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);
              }
              request.Headers.Action += "1";
              return null;
          }
  
          void ChangeMessage(XmlDocument doc, bool flag)
          {
              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", nsManager);
              if (node != null)
              {
                  if (flag)
                      node.InnerXml = node.InnerXml.Replace("GetData", "GetData1");
                  else
                      node.InnerXml = node.InnerXml.Replace("GetData1Response", "GetDataResponse").Replace("GetData1Result", "GetDataResult");
              }
          }
      }
  
      public class MyBehavior : BehaviorExtensionElement, IEndpointBehavior
      {
          public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
          {
              //endpoint.Behaviors.Add(new MyBehavior());
          }
  
          public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
          {
              MyInspector inspector = new MyInspector();
              clientRuntime.MessageInspectors.Add(inspector);
          }
  
          public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
          {
          }
  
          public void Validate(ServiceEndpoint endpoint)
          {
          }
  
          protected override object CreateBehavior()
          {
              return new MyBehavior();
          }
  
          public override Type BehaviorType
          {
              get
              {
                  Type t = Type.GetType("MethodChangeService.MyBehavior");
                  return t;
              }
          }
      }
  }
  </code></pre>
  
  <p>and the Service class is:</p>
  
  <pre><code>using System;
  using System.Configuration;
  using System.Collections.Generic;
  using System.Linq;
  using System.Runtime.Serialization;
  using System.ServiceModel;
  using System.ServiceModel.Web;
  using System.Text;
  using System.ServiceModel.Description;
  using System.ServiceModel.Configuration;
  using System.ServiceModel.Dispatcher;
  using System.ServiceModel.Channels;
  using System.IO;
  using System.Xml;
  
  namespace MethodChangeService
  {
      // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
      public class HardcoadedService : IHardcoadedService
      {
          public string GetData(int i)
          {
              return string.Format("you entered {0}",i);
          }
  
          public string GetData1()
          {
              return string.Format("You got redirected to another method!!");
          }
      }
  
  }
  </code></pre>
  
  <p>Here is the client code:</p>
  
  <pre><code>class Program
      {
          static void Main(string[] args)
          {
              HardcoadedServiceClient c = new HardcoadedServiceClient();
              c.Endpoint.Behaviors.Add(new MyBehavior());
              string s = c.GetData(3);
              Console.WriteLine(s);
              Console.ReadKey();
          }
      }
  </code></pre>