title: Log both webservice Request, Response in SoapExtension
body: <p>I am using a SoapExtension to log both the webservice request, response when an error occurs in a webservice. Both the request and response XMLDocument's have incorrect data. Can someone review the code to see what I could be doing wrong? If I am unable to centralize the changes in the SoapExtension, then I will go about adding logging code around each webservice endpoint. </p>
  
  <pre><code>    using System;
      using System.IO;
      using System.Web.Services.Protocols;
      using System.Xml;
  
      using Elmah;
  
      public class ElmahSoapExtensionV2 : SoapExtension
      {
          private Stream oldStream;
          private Stream newStream;
  
          public static XmlDocument XmlRequest { get; private set; }
          public static XmlDocument XmlResponse { get; private set; }
  
          public override Stream ChainStream(Stream stream)
          {
              oldStream = stream;
              newStream = new MemoryStream();
              return newStream;
          }
  
          public override void ProcessMessage(SoapMessage soapMessage)
          {
              switch (soapMessage.Stage)
              {
                  case SoapMessageStage.BeforeSerialize:
                      break;
                  case SoapMessageStage.AfterSerialize:
                      XmlRequest = GetSoapEnvelope(newStream);
                      if (soapMessage.Exception != null)
                      {
                          var exception = soapMessage.Exception.GetBaseException();
                          exception.Data.Add("SoapRequest", XmlRequest.OuterXml);
                          exception.Data.Add("SoapResponse", XmlResponse.OuterXml);
                          ErrorSignal.FromCurrentContext().Raise(exception);
                      }
                      CopyStream(newStream, oldStream);
                      break;
                  case SoapMessageStage.BeforeDeserialize:
                      CopyStream(oldStream, newStream);
                      XmlResponse = GetSoapEnvelope(newStream);
                      break;
                  case SoapMessageStage.AfterDeserialize:
                      break;
              }
          }
  
          private static XmlDocument GetSoapEnvelope(Stream stream)
          {
              var xmlDocument = new XmlDocument();
              stream.Position = 0;
              var streamReader = new StreamReader(stream);
              xmlDocument.LoadXml(streamReader.ReadToEnd());
              stream.Position = 0;
              return xmlDocument;
          }
  
          private static void CopyStream(Stream streamFrom, Stream streamTo)
          {
              var textReader = new StreamReader(streamFrom);
              var textWriter = new StreamWriter(streamTo);
              textWriter.WriteLine(textReader.ReadToEnd());
              textWriter.Flush();
          }
  
          #region MyRegion
          public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
          {
              return null;
          }
          public override object GetInitializer(Type WebServiceType)
          {
              return null;
          }
          public override void Initialize(object initializer)
          {
          } 
          #endregion
      }
  </code></pre>