0

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.

    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
    }
Ajit Goel
  • 4,180
  • 7
  • 59
  • 107

1 Answers1

1

Solved it by removing the "Static" property for the XMLRequest, XMLResponse properties. Also I will get the "XMLResponse" during the "SoapMessageStage.AfterSerialize" process and the "XMLRequest" during the "SoapMessageStage.BeforeSerialize" process. I previously had it switched.

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 XmlDocument XmlRequest { get; private set; }
    public 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:
                XmlResponse = 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);
                XmlRequest = 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
}
Ajit Goel
  • 4,180
  • 7
  • 59
  • 107