Rahul
Rahul

Reputation: 11

Log soap request and response for non .Net SOAP web services

I am using not .Net SOAP web services(ESB service) in my .net application. I have added reference or the service using add web reference.

Now when I call any method of this service, I would like to log soap request and response. And I want to store request/response in database.

Can any one please tell me how to log .Net SOAP web service's soap request and response in c#?

Upvotes: 1

Views: 1008

Answers (1)

Luca
Luca

Reputation: 1826

This Code is from this post, any code written is not mine^^

You can implement a SoapExtension that logs the full request and response to a log file. You can then enable the SoapExtension in the web.config, which makes it easy to turn on/off for debugging purposes. Here is an example that I have found and modified for my own use, in my case the logging was done by log4net but you can replace the log methods with your own.

public class SoapLoggerExtension : SoapExtension
{
    private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    private Stream oldStream;
    private Stream newStream;

public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
    return null;
}

public override object GetInitializer(Type serviceType)
{
    return null;
}

public override void Initialize(object initializer)
{

}

public override System.IO.Stream ChainStream(System.IO.Stream stream)
{
    oldStream = stream;
    newStream = new MemoryStream();
    return newStream;
}

public override void ProcessMessage(SoapMessage message)
{

    switch (message.Stage)
    {
        case SoapMessageStage.BeforeSerialize:
            break;
        case SoapMessageStage.AfterSerialize:
            Log(message, "AfterSerialize");
                CopyStream(newStream, oldStream);
                newStream.Position = 0;
            break;
            case SoapMessageStage.BeforeDeserialize:
                CopyStream(oldStream, newStream);
                Log(message, "BeforeDeserialize");
            break;
        case SoapMessageStage.AfterDeserialize:
            break;
    }
}

public void Log(SoapMessage message, string stage)
{

    newStream.Position = 0;
    string contents = (message is SoapServerMessage) ? "SoapRequest " : "SoapResponse ";
    contents += stage + ";";

    StreamReader reader = new StreamReader(newStream);

    contents += reader.ReadToEnd();

    newStream.Position = 0;

    log.Debug(contents);
}

void ReturnStream()
{
    CopyAndReverse(newStream, oldStream);
}

void ReceiveStream()
{
    CopyAndReverse(newStream, oldStream);
}

public void ReverseIncomingStream()
{
    ReverseStream(newStream);
}

public void ReverseOutgoingStream()
{
    ReverseStream(newStream);
}

public void ReverseStream(Stream stream)
{
    TextReader tr = new StreamReader(stream);
    string str = tr.ReadToEnd();
    char[] data = str.ToCharArray();
    Array.Reverse(data);
    string strReversed = new string(data);

    TextWriter tw = new StreamWriter(stream);
    stream.Position = 0;
    tw.Write(strReversed);
    tw.Flush();
}
void CopyAndReverse(Stream from, Stream to)
{
    TextReader tr = new StreamReader(from);
    TextWriter tw = new StreamWriter(to);

    string str = tr.ReadToEnd();
    char[] data = str.ToCharArray();
    Array.Reverse(data);
    string strReversed = new string(data);
    tw.Write(strReversed);
    tw.Flush();
}

private void CopyStream(Stream fromStream, Stream toStream)
{
    try
    {
        StreamReader sr = new StreamReader(fromStream);
        StreamWriter sw = new StreamWriter(toStream);
        sw.WriteLine(sr.ReadToEnd());
        sw.Flush();
    }
        catch (Exception ex)
        {
            string message = String.Format("CopyStream failed because: {0}", ex.Message);
            log.Error(message, ex);
        }
    }
}
[AttributeUsage(AttributeTargets.Method)]
public class SoapLoggerExtensionAttribute : SoapExtensionAttribute
{
    private int priority = 1; 

    public override int Priority
    {
        get { return priority; }
        set { priority = value; }
    }

    public override System.Type ExtensionType
    {
        get { return typeof (SoapLoggerExtension); }
    }
} 

You then add the following section to your web.config where YourNamespace and YourAssembly point to the class and assembly of your SoapExtension:

<webServices>
  <soapExtensionTypes>
    <add type="YourNamespace.SoapLoggerExtension, YourAssembly" 
       priority="1" group="0" />
  </soapExtensionTypes>
</webServices>

Or just try Fiddler. it will let you inspect the requests and response. It might be worth noting that Fiddler works with both http and https traffic.

Upvotes: 2

Related Questions