Saltar al contenido

¿Cómo obtengo acceso a la respuesta SOAP?

Bienvenido a nuestra comunidad, en este sitio vas a encontrar la solucíon que estás buscando.

Solución:

Puede utilizar SoapExtension del marco WSE2.0 existente para interceptar las respuestas del servidor.

public class MyClientSOAPExtension : SoapExtension


     Stream oldStream;
     Stream newStream;

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

    public override void ProcessMessage(SoapMessage message)
    
       switch (message.Stage)
        
            case SoapMessageStage.BeforeDeserialize:
                // before the XML deserialized into object.
                break;
            case SoapMessageStage.AfterDeserialize:
                break;        
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                break;            
            default:
                throw new Exception("Invalid stage...");
               
    

En la etapa de SoapMessageStage.BeforeDeserialize, puede leer los datos esperados que desee de oldstream (por ejemplo, use XmlReader). Luego, almacene los datos esperados en algún lugar para que los use y también debe reenviar los datos de la secuencia anterior a la secuencia nueva para que el servicio web utilice los datos en una etapa posterior, por ejemplo, deserializar XML en objetos.

La muestra de registrar todo el tráfico del servicio web de MSDN

Aquí hay un ejemplo que puede configurar usando la referencia web de Visual Studio para http://footballpool.dataaccess.eu/data/info.wso?WSDL

Básicamente, debe insertar en la cadena de llamadas del servicio web un espía XmlReader que reconstruirá el XML sin procesar.

Creo que de esta manera es de alguna manera más simple que usar SoapExtensions.

La solución se inspiró en http://orbinary.com/blog/2010/01/getting-the-raw-soap-xml-sent-via-soaphttpclientprotocol/

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Reflection;
using System.Xml;


namespace ConsoleApplication1 

    public class XmlReaderSpy : XmlReader 
        XmlReader _me;
        public XmlReaderSpy(XmlReader parent) 
            _me = parent;
        

        /// 
        /// Extracted XML.
        /// 
        public string Xml;

        #region Abstract method that must be implemented
        public override XmlNodeType NodeType 
            get 

                return _me.NodeType;
            
        

        public override string LocalName 
            get 
                return _me.LocalName;
            
        

        public override string NamespaceURI 
            get 
                return _me.NamespaceURI;
            
        

        public override string Prefix 
            get 
                return _me.Prefix;
            
        

        public override bool HasValue 
            get  return _me.HasValue; 
        

        public override string Value 
            get  return _me.Value; 
        

        public override int Depth 
            get  return _me.Depth; 
        

        public override string BaseURI 
            get  return _me.BaseURI; 
        

        public override bool IsEmptyElement 
            get  return _me.IsEmptyElement; 
        

        public override int AttributeCount 
            get  return _me.AttributeCount; 
        

        public override string GetAttribute(int i) 
            return _me.GetAttribute(i);
        

        public override string GetAttribute(string name) 
            return _me.GetAttribute(name);
        

        public override string GetAttribute(string name, string namespaceURI) 
            return _me.GetAttribute(name, namespaceURI);
        

        public override void MoveToAttribute(int i) 
            _me.MoveToAttribute(i);
        

        public override bool MoveToAttribute(string name) 
            return _me.MoveToAttribute(name);
        

        public override bool MoveToAttribute(string name, string ns) 
            return _me.MoveToAttribute(name, ns);
        

        public override bool MoveToFirstAttribute() 
            return _me.MoveToFirstAttribute();
        

        public override bool MoveToNextAttribute() 
            return _me.MoveToNextAttribute();
        

        public override bool MoveToElement() 
            return _me.MoveToElement();
        

        public override bool ReadAttributeValue() 
            return _me.ReadAttributeValue();
        

        public override bool Read() 
            bool res = _me.Read();

            Xml += StringView();


            return res;
        

        public override bool EOF 
            get  return _me.EOF; 
        

        public override void Close() 
            _me.Close();
        

        public override ReadState ReadState 
            get  return _me.ReadState; 
        

        public override XmlNameTable NameTable 
            get  return _me.NameTable; 
        

        public override string LookupNamespace(string prefix) 
            return _me.LookupNamespace(prefix);
        

        public override void ResolveEntity() 
            _me.ResolveEntity();
        

        #endregion


        protected string StringView() 
    

    public class MyInfo : ConsoleApplication1.eu.dataaccess.footballpool.Info              

        protected XmlReaderSpy _xmlReaderSpy;

        public string Xml 
            get 
                if (_xmlReaderSpy != null) 
                    return _xmlReaderSpy.Xml;
                
                else 
                    return "";
                
            
        


        protected override XmlReader GetReaderForMessage(System.Web.Services.Protocols.SoapClientMessage message, int bufferSize)           
            XmlReader rdr = base.GetReaderForMessage(message, bufferSize);
            _xmlReaderSpy = new XmlReaderSpy((XmlReader)rdr);
            return _xmlReaderSpy;
        

    

    class Program 
        static void Main(string[] args) 

            MyInfo info = new MyInfo();
            string[] rest = info.Cities();

            System.Console.WriteLine("RAW Soap XML response :n"+info.Xml);
            System.Console.ReadLine();
        
    

Inspirado por jfburdet, quería ver si era posible interceptar directamente a nivel de flujo / byte en lugar de reconstruir XML. ¡Y es! Ver código a continuación:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Services.Protocols;
using System.Xml;

using Test.MyWebReference;

namespace Test 
    /// 
    /// Adds the ability to retrieve the SOAP request/response.
    /// 
    public class ServiceSpy : OriginalService 
        private StreamSpy writerStreamSpy;
        private XmlTextWriter xmlWriter;

        private StreamSpy readerStreamSpy;
        private XmlTextReader xmlReader;

        public MemoryStream WriterStream 
            get  return writerStreamSpy == null ? null : writerStreamSpy.ClonedStream; 
        

        public XmlTextWriter XmlWriter 
            get  return xmlWriter; 
        

        public MemoryStream ReaderStream 
            get  return readerStreamSpy == null ? null : readerStreamSpy.ClonedStream; 
        

        public XmlTextReader XmlReader 
            get  return xmlReader; 
        

        protected override void Dispose(bool disposing) 
            base.Dispose(disposing);
            DisposeWriterStreamSpy();
            DisposeReaderStreamSpy();
        

        protected override XmlWriter GetWriterForMessage(SoapClientMessage message, int bufferSize) 
            // Dispose previous writer stream spy.
            DisposeWriterStreamSpy();

            writerStreamSpy = new StreamSpy(message.Stream);
            // XML should always support UTF8.
            xmlWriter = new XmlTextWriter(writerStreamSpy, Encoding.UTF8);

            return xmlWriter;
        

        protected override XmlReader GetReaderForMessage(SoapClientMessage message, int bufferSize) 
            // Dispose previous reader stream spy.
            DisposeReaderStreamSpy();

            readerStreamSpy = new StreamSpy(message.Stream);
            xmlReader = new XmlTextReader(readerStreamSpy);

            return xmlReader;
        

        private void DisposeWriterStreamSpy() 
            if (writerStreamSpy != null) 
                writerStreamSpy.Dispose();
                writerStreamSpy.ClonedStream.Dispose();
                writerStreamSpy = null;
            
        

        private void DisposeReaderStreamSpy() 
            if (readerStreamSpy != null) 
                readerStreamSpy.Dispose();
                readerStreamSpy.ClonedStream.Dispose();
                readerStreamSpy = null;
            
        

        /// 
        /// Wrapper class to clone read/write bytes.
        /// 
        public class StreamSpy : Stream 
            private Stream wrappedStream;
            private long startPosition;
            private MemoryStream clonedStream = new MemoryStream();

            public StreamSpy(Stream wrappedStream) 
                this.wrappedStream = wrappedStream;
                startPosition = wrappedStream.Position;
            

            public MemoryStream ClonedStream 
                get  return clonedStream; 
            

            public override bool CanRead 
                get  return wrappedStream.CanRead; 
            

            public override bool CanSeek 
                get  return wrappedStream.CanSeek; 
            

            public override bool CanWrite 
                get  return wrappedStream.CanWrite; 
            

            public override void Flush() 
                wrappedStream.Flush();
            

            public override long Length 
                get  return wrappedStream.Length; 
            

            public override long Position 
                get  return wrappedStream.Position; 
                set  wrappedStream.Position = value; 
            

            public override int Read(byte[] buffer, int offset, int count) 
                long relativeOffset = wrappedStream.Position - startPosition;
                int result = wrappedStream.Read(buffer, offset, count);
                if (clonedStream.Position != relativeOffset) 
                    clonedStream.Position = relativeOffset;
                
                clonedStream.Write(buffer, offset, result);
                return result;
            

            public override long Seek(long offset, SeekOrigin origin) 
                return wrappedStream.Seek(offset, origin);
            

            public override void SetLength(long value) 
                wrappedStream.SetLength(value);
            

            public override void Write(byte[] buffer, int offset, int count) 
                long relativeOffset = wrappedStream.Position - startPosition;
                wrappedStream.Write(buffer, offset, count);
                if (clonedStream.Position != relativeOffset) 
                    clonedStream.Position = relativeOffset;
                
                clonedStream.Write(buffer, offset, count);
            

            public override void Close() 
                wrappedStream.Close();
                base.Close();
            

            protected override void Dispose(bool disposing) 
                if (wrappedStream != null) 
                    wrappedStream.Dispose();
                    wrappedStream = null;
                
                base.Dispose(disposing);
            
        
    

Al final de la artículo puedes encontrar las interpretaciones de otros administradores, tú además eres capaz mostrar el tuyo si te gusta.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *