locked
How to capture XML when calling web service from win apps RRS feed

  • Question

  • in my solution i have three project. one is web service (ASMX), another is win form apps from where i am calling the web service. another class library where class has been design extending SoapExtension class.

    my objective is to capture response & request xml when i am calling web service from my win form apps.i am getting object reference not set error when i am trying to capture xml.
    here is my class library source 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;
        /// <summary>
        /// Gets the outgoing XML request sent to PayPal
        /// </summary>
        public static XmlDocument XmlRequest
        {
            get { return xmlRequest; }
        }

        private static XmlDocument xmlResponse;
        /// <summary>
        /// Gets the incoming XML response sent from PayPal
        /// </summary>
        public static XmlDocument XmlResponse
        {
            get { return xmlResponse; }
        }

        /// <summary>
        /// Save the Stream representing the SOAP request
        /// or SOAP response into a local memory buffer.
        /// </summary>
        /// <param name="stream">
        /// <returns></returns>
        public override Stream ChainStream(Stream stream)
        {
            oldStream = stream;
            newStream = new MemoryStream();
            return newStream;
        }

        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="message">
        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;
            }
        }

        /// <summary>
        /// Returns the XML representation of the Soap Envelope in the supplied stream.
        /// Resets the position of stream to zero.
        /// </summary>
        /// <param name="stream">
        /// <returns></returns>
        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;
        }

        /// <summary>
        /// Copies a stream.
        /// </summary>
        /// <param name="from">
        /// <param name="to">
        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
        /// <summary>
        /// Included only because it must be implemented.
        /// </summary>
        /// <param name="methodInfo">
        /// <param name="attribute">
        /// <returns></returns>
        public override object GetInitializer(LogicalMethodInfo methodInfo,
            SoapExtensionAttribute attribute)
        {
            return null;
        }

        /// <summary>
        /// Included only because it must be implemented.
        /// </summary>
        /// <param name="WebServiceType">
        /// <returns></returns>
        public override object GetInitializer(Type WebServiceType)
        {
            return null;
        }

        /// <summary>
        /// Included only because it must be implemented.
        /// </summary>
        /// <param name="initializer">
        public override void Initialize(object initializer)
        {
        }
        #endregion NoOp
    }
    }

    here i will show how i am calling web service from win apps

        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;
            }
        }

    this two line is giving object reference error

                var soapRequest = SoapLogger.TraceExtension.XmlRequest.InnerXml;
                var soapResponse = SoapLogger.TraceExtension.XmlResponse.InnerXml;

    i just could not figure out why i am getting error.

    in win form apps has one app.config where i register my class library assembly to capture the xml. here is my app.config details

    <?xml version="1.0"?>
    <configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="TestServiceSoap"/>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:6804/Service1.asmx" binding="basicHttpBinding" bindingConfiguration="TestServiceSoap" contract="ServiceRef.TestServiceSoap" name="TestServiceSoap"/>
        </client>
    </system.serviceModel>

    <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <webServices>
      <soapExtensionTypes>
        <add type="SoapLogger.TraceExtension,SoapLogger" priority="1" group="0" />
      </soapExtensionTypes>
    </webServices>
    </system.web>
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup>    
    </configuration>

    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.

    this url i followed to get the job done http://jramirezdev.net/blog/c-tip-capturar-los-mensajes-soap-de-un-servicio-asmx-que-hemos-referenciado

    what kind of mistake i am 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 dont want to use any tool like wireshark,fiddler to capture the request/response xml rather want to do same thing programatically.

    so please guide me what is my mistake. why i am 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.
    Friday, November 9, 2012 6:30 AM

All replies

  • This problem probably has nothing to do with the fact that you're trying to capture XML. Nearly all cases of NullReferenceException mean the same thing: you forgot to initialize something (or didn't know that you needed to initialize it). See http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net.


    John Saunders
    WCF is Web Services. They are not two separate things.
    Use WCF for All New Web Service Development, instead of legacy ASMX or obsolete WSE
    Use File->New Project to create Web Service Projects

    Monday, November 12, 2012 7:12 PM
    Moderator