title: How do I capture incoming and outgoing XML from WCF service end
body: <p>In my solution I have three projects. One is a WCF service, another is a Winforms app from where I am calling the web service, and the last is a class library where class has been design extending soap extension class.</p>
  
  <p>My objective is to capture response &amp; request xml when I am calling the WCF service from my Winforms app. I am getting object reference not set error when I am trying to capture xml.</p>
  
  <p>Here is my class library source code.</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Web.Services;
  using System.Web.Services.Protocols;
  using System.IO;
  using System.Net;
  using System.Xml;
  
  namespace SoapLogger
  {
  public class TraceExtension : SoapExtension
  {
      private Stream oldStream;
      private Stream newStream;
  
      private static XmlDocument xmlRequest;
      /// &lt;summary&gt;
      /// Gets the outgoing XML request sent to PayPal
      /// &lt;/summary&gt;
      public static XmlDocument XmlRequest
      {
          get { return xmlRequest; }
      }
  
      private static XmlDocument xmlResponse;
      /// &lt;summary&gt;
      /// Gets the incoming XML response sent from PayPal
      /// &lt;/summary&gt;
      public static XmlDocument XmlResponse
      {
          get { return xmlResponse; }
      }
  
      /// &lt;summary&gt;
      /// Save the Stream representing the SOAP request
      /// or SOAP response into a local memory buffer.
      /// &lt;/summary&gt;
      /// &lt;param name="stream"&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public override Stream ChainStream(Stream stream)
      {
          oldStream = stream;
          newStream = new MemoryStream();
          return newStream;
      }
  
      /// &lt;summary&gt;
      /// If the SoapMessageStage is such that the SoapRequest or
      /// SoapResponse is still in the SOAP format to be sent or received,
      /// save it to the xmlRequest or xmlResponse property.
      /// &lt;/summary&gt;
      /// &lt;param name="message"&gt;
      public override void ProcessMessage(SoapMessage message)
      {
          switch (message.Stage)
          {
              case SoapMessageStage.BeforeSerialize:
                  break;
              case SoapMessageStage.AfterSerialize:
                  xmlRequest = GetSoapEnvelope(newStream);
                  CopyStream(newStream, oldStream);
                  break;
              case SoapMessageStage.BeforeDeserialize:
                  CopyStream(oldStream, newStream);
                  xmlResponse = GetSoapEnvelope(newStream);
                  break;
              case SoapMessageStage.AfterDeserialize:
                  break;
          }
      }
  
      /// &lt;summary&gt;
      /// Returns the XML representation of the Soap Envelope in the supplied stream.
      /// Resets the position of stream to zero.
      /// &lt;/summary&gt;
      /// &lt;param name="stream"&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      private XmlDocument GetSoapEnvelope(Stream stream)
      {
          XmlDocument xml = new XmlDocument();
          stream.Position = 0;
          StreamReader reader = new StreamReader(stream);
          xml.LoadXml(reader.ReadToEnd());
          stream.Position = 0;
          return xml;
      }
  
      /// &lt;summary&gt;
      /// Copies a stream.
      /// &lt;/summary&gt;
      /// &lt;param name="from"&gt;
      /// &lt;param name="to"&gt;
      private void CopyStream(Stream from, Stream to)
      {
          TextReader reader = new StreamReader(from);
          TextWriter writer = new StreamWriter(to);
          writer.WriteLine(reader.ReadToEnd());
          writer.Flush();
      }
      #region NoOp
      /// &lt;summary&gt;
      /// Included only because it must be implemented.
      /// &lt;/summary&gt;
      /// &lt;param name="methodInfo"&gt;
      /// &lt;param name="attribute"&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public override object GetInitializer(LogicalMethodInfo methodInfo,
          SoapExtensionAttribute attribute)
      {
          return null;
      }
  
      /// &lt;summary&gt;
      /// Included only because it must be implemented.
      /// &lt;/summary&gt;
      /// &lt;param name="WebServiceType"&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public override object GetInitializer(Type WebServiceType)
      {
          return null;
      }
  
      /// &lt;summary&gt;
      /// Included only because it must be implemented.
      /// &lt;/summary&gt;
      /// &lt;param name="initializer"&gt;
      public override void Initialize(object initializer)
      {
      }
      #endregion NoOp
  }
  </code></pre>
  
  <p>Here is how I am calling the web service from my Winforms app:</p>
  
  <pre><code>private void button1_Click(object sender, EventArgs e)
  {
  
      using (ServiceRef.TestServiceSoapClient oService = new ServiceRef.TestServiceSoapClient())
      {
          textBox1.Text = oService.HelloWorld("Sudip");
          var soapRequest = SoapLogger.TraceExtension.XmlRequest.InnerXml;
          var soapResponse = SoapLogger.TraceExtension.XmlResponse.InnerXml;
      }
  }
  </code></pre>
  
  <p>These two lines are causing the object reference error</p>
  
  <pre><code>var soapRequest = SoapLogger.TraceExtension.XmlRequest.InnerXml;
  var soapResponse = SoapLogger.TraceExtension.XmlResponse.InnerXml;
  </code></pre>
  
  <p>I just could not figure out why I am getting error.</p>
  
  <p>The Winforms app has an <code>app.config</code> where I register my class library assembly to capture the xml. Here is my <code>app.config</code> details</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt; 
  &lt;configuration&gt; 
  &lt;system.serviceModel&gt; 
  &lt;bindings&gt; 
  &lt;basicHttpBinding&gt; 
  &lt;binding name="TestServiceSoap"/&gt; &lt;/basicHttpBinding&gt; 
  &lt;/bindings&gt; &lt;client&gt; &lt;endpoint address="http://localhost:6804/Service1.asmx" 
  binding="basicHttpBinding" bindingConfiguration="TestServiceSoap" 
  contract="ServiceRef.TestServiceSoap" name="TestServiceSoap"/&gt; 
  &lt;/client&gt; 
  &lt;/system.serviceModel&gt; 
  &lt;system.web&gt; 
  &lt;compilation debug="true" targetFramework="4.0" /&gt; 
  &lt;webServices&gt; &lt;soapExtensionTypes&gt; 
  &lt;add type="SoapLogger.TraceExtension,SoapLogger" priority="1" group="0" /&gt; 
  &lt;/soapExtensionTypes&gt; &lt;/webServices&gt; 
  &lt;/system.web&gt; 
  &lt;startup&gt;
  &lt;supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/&gt; 
  &lt;/startup&gt; &lt;/configuration&gt;
  </code></pre>
  
  <p>When I search google just to know how to capture request/response xml then I got this kind of many article. I followed many but nothing works.</p>
  
  <p>This url I followed to get the job done <a href="http://jramirezdev.net/blog/c-tip-capturar-los-mensajes-soap-de-un-servicio-asmx-que-hemos-referenciado" rel="nofollow">http://jramirezdev.net/blog/c-tip-capturar-los-mensajes-soap-de-un-servicio-asmx-que-hemos-referenciado</a></p>
  
  <p>What kind of mistake am I making not clear. I set the break point at every method in my class library method but when web service call no method got executed in the class library. I don't want to use any tool like wireshark, fiddler to capture the request/response xml rather want to do same thing programatically.</p>
  
  <p>So please guide me what is my mistake? Why am I getting object reference not set error? Please have a look at my code or go to the url link and tell me what is wrong in my approach</p>