locked
How to log web services request and response with data in XML file in Client? RRS feed

  • Question

  • User1443586202 posted

    Hi all,

    I am trying to log the request and response messages in my client while the client is consuming a thirdparty WebService.
    After following some threads, I have reached upto the current stage where m
    y TraceExtension class code which is compiled as a library and set reference to my project is as below,

    using System;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    using System.IO;
    using System.Net;
    
    // Define a SOAP Extension that traces the SOAP request and SOAP
    // response for the XML Web service method the SOAP extension is
    // applied to.
    
    public class TraceExtension : SoapExtension
    {
        Stream oldStream;
        Stream newStream;
        string filename;
    
        // Save the Stream representing the SOAP request or SOAP response into
        // a local memory buffer.
        public override Stream ChainStream(Stream stream)
        {
            oldStream = stream;
            newStream = new MemoryStream();
            return newStream;
        }
    
        // When the SOAP extension is accessed for the first time, the XML Web
        // service method it is applied to is accessed to store the file
        // name passed in, using the corresponding SoapExtensionAttribute.	
        public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
        {
            return ((TraceExtensionAttribute)attribute).Filename;
        }
    
        // The SOAP extension was configured to run using a configuration file
        // instead of an attribute applied to a specific XML Web service
        // method.
        public override object GetInitializer(Type WebServiceType)
        {
            // Return a file name to log the trace information to, based on the
            // type.
            return "C:\\" + WebServiceType.FullName + ".log";
        }
    
        // Receive the file name stored by GetInitializer and store it in a
        // member variable for this specific instance.
        public override void Initialize(object initializer)
        {
            filename = (string)initializer;
        }
    
        //  If the SoapMessageStage is such that the SoapRequest or
        //  SoapResponse is still in the SOAP format to be sent or received,
        //  save it out to a file.
        public override void ProcessMessage(SoapMessage message)
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeSerialize:
                    break;
                case SoapMessageStage.AfterSerialize:
                    WriteOutput(message);
                    break;
                case SoapMessageStage.BeforeDeserialize:
                    WriteInput(message);
                    break;
                case SoapMessageStage.AfterDeserialize:
                    break;
            }
        }
    
        public void WriteOutput(SoapMessage message)
        {
            newStream.Position = 0;
            FileStream fs = new FileStream(filename, FileMode.Append,
                FileAccess.Write);
            StreamWriter w = new StreamWriter(fs);
    
            string soapString = (message is SoapServerMessage) ? "SoapResponse" : "SoapRequest";
            w.WriteLine("-----" + soapString + " at " + DateTime.Now);
            w.Flush();
            Copy(newStream, fs);
            w.Close();
            newStream.Position = 0;
            Copy(newStream, oldStream);
        }
    
        public void WriteInput(SoapMessage message)
        {
            Copy(oldStream, newStream);
            FileStream fs = new FileStream(filename, FileMode.Append,
                FileAccess.Write);
            StreamWriter w = new StreamWriter(fs);
    
            string soapString = (message is SoapServerMessage) ?
                "SoapRequest" : "SoapResponse";
            w.WriteLine("-----" + soapString +
                " at " + DateTime.Now);
            w.Flush();
            newStream.Position = 0;
            Copy(newStream, fs);
            w.Close();
            newStream.Position = 0;
        }
    
        void Copy(Stream from, Stream to)
        {
            TextReader reader = new StreamReader(from);
            TextWriter writer = new StreamWriter(to);
            writer.WriteLine(reader.ReadToEnd());
            writer.Flush();
        }
    }
    
    // Create a SoapExtensionAttribute for the SOAP Extension that can be
    // applied to an XML Web service method.
    [AttributeUsage(AttributeTargets.Method)]
    public class TraceExtensionAttribute : SoapExtensionAttribute
    {
    
        //private string filename = "c:\\log.txt";
        private string filename = "d:\\log.txt";
        private int priority;
    
        public override Type ExtensionType
        {
            get { return typeof(TraceExtension); }
        }
    
        public override int Priority
        {
            get { return priority; }
            set { priority = value; }
        }
    
        public string Filename
        {
            get
            {
                return filename;
            }
            set
            {
                filename = value;
            }
        }
    }

    Added the below to my web.config file

        <webServices>
          <soapExtensionTypes>
            <add type="TraceExtension.TraceExtension,TraceExtension" priority="1"/>
          </soapExtensionTypes>
        </webServices>

    Still the XML file/text file is never created at the specified path.

    Can anyone guide me to get this worked ? Please help..



    Wednesday, January 23, 2013 11:43 PM

Answers

  • User-1662538993 posted

    Just for the purpose of testing that you have permission to write to that folder try to do write the request and response to text file.

    using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\WriteLines.txt", true))
                {
     XmlSerializer x = new XmlSerializer(Yourobject.GetType());
                        TextWriter tw = new StringWriter();
                        x.Serialize(tw,Yourobject);
    file.WriteLine(tw.Tostring());
    }
    You can put your request object and before sending the response to client response object or in client you can do the same.
    Try so atleast you will come to know that it is writing and the request and response are correct or not.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, January 24, 2013 4:21 PM

All replies

  • User-1662538993 posted

    Are you getting any error or exception?

    Do you have permission to write to that file on the client?

    Thursday, January 24, 2013 11:02 AM
  • User1443586202 posted

    No exceptions. Everything executes normal.

    I have the permission to write to the file on the client.

    Thursday, January 24, 2013 1:20 PM
  • User-1662538993 posted

    Just for the purpose of testing that you have permission to write to that folder try to do write the request and response to text file.

    using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\WriteLines.txt", true))
                {
     XmlSerializer x = new XmlSerializer(Yourobject.GetType());
                        TextWriter tw = new StringWriter();
                        x.Serialize(tw,Yourobject);
    file.WriteLine(tw.Tostring());
    }
    You can put your request object and before sending the response to client response object or in client you can do the same.
    Try so atleast you will come to know that it is writing and the request and response are correct or not.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, January 24, 2013 4:21 PM
  • User1443586202 posted

    I placed your code block with my Request and response objects with "C:\Request" and "C:\Repsonse" as the path.
    Got excited to see two text files created with these name and all the XML with data was logged into it !!

    Thank you so much for saving my time and ending my frustration in getting this logged. I feel the class whcih I created is not required anymore.

    Appreciate your time and you for sharing your knowledge ! Smile

    Wednesday, January 30, 2013 11:41 PM
  • User-773705572 posted

    HI ,

    I tried your code. but I am not getting any file created after the request , response . I tried the other short one , wich writes the xml file sucessfully, but the response file comes empty when webservice function call goes to catch (execption).. .. Please help how can i get the response file written when it goes in catch ..

    Also need to verify,..

    <webServices> <soapExtensionTypes> <add type="TraceExtension.TraceExtension,TraceExtension" priority="1"/> </soapExtensionTypes> </webServices>

    what is the value i need to replace for this->> type="TraceExtension.TraceExtension,TraceExtension"

    My endpoint is like this..

    <endpoint address="https://localhost/service.asmx" binding="customBinding" bindingConfiguration="ServiceSoap12" contract="remit.ServiceSoap" name="ServiceSoap12"/>

    Saturday, May 18, 2013 4:35 AM
  • User-1662538993 posted

    What exactly you are trying to accomplish?

    You want to create a text file which have your web service method request or response that you are sending back to client or you are trying the enable trace log.

    For enabling trace log check this link -

    http://msdn.microsoft.com/en-us/library/ms751526.aspx

    http://stackoverflow.com/questions/4271517/how-to-turn-on-wcf-tracing

    If you just want to create a text file and put your request and response of your web service method then you can just create a text file by the code i have provided-

    // Make sure your application have permission to create a file to below path
    // Change this path as per your folder structure
    using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\WriteLines.txt", true))
                {
    // If you are working on say employee object as your web method input parameter then change //yourobject.gettype() to employee.gettype()
     XmlSerializer x = new XmlSerializer(Yourobject.GetType());
                        TextWriter tw = new StringWriter();
                        x.Serialize(tw,Yourobject);
                    file.WriteLine(tw.Tostring());
                }

    Let me know if you need any more help and if you have still problem creating then try to post more details regarding your objects and methods.

    Monday, May 20, 2013 11:38 AM
  • User-773705572 posted

    Hi kushal,

    Thank you for the reply!

    I am looking to log all the request , response in xml above the c# implementation done in object initializtion...

    for the code you share now i am able to get the xml in file, but the only issue is , when it goest to expection , i get empty response file..which is very important for me ,to get exact xml error response from client for troubleshooting..

    yeah I am able to get the response, (includes error response Smile ) from the trace link you share.. still works for me.
    but i am trying to log each response , request in different file rather in one file as log by this .. and there is too much information i get logged. Btw how do we filter message to get log for only particular webservice?

    I am wondering how do i implement the SoapExtensioncode you have shared? when i put breakpoint in the code. it is not going through..Can you explain me what to keep in web.config to  run the above code?

    Tuesday, May 21, 2013 9:02 AM