lunes, 11 de noviembre de 2013

Trace SOAP Request/Response XML with TraceExtension - SoapExtension - C#

Trace SOAP Request/Response XML with TraceExtension - SoapExtension - C#


In one of my projects, I had to interact with a Web Service (Java) from another NET Web Service (asmx). logs to leave messages back and forth, I had to resort to SoapExtension.
Sometimes we need to send a sample of our request SOAP / XML web service response. I leave you a practical example without much return, I hope will be helpful

Class TraceExtension

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

namespace
TestProject
{
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
}
}

Method soapMessageRecord

private void soapMessageRecord(string nombreMetodo)
{
StreamWriter escritorReq = File.CreateText("C:\\logs\\request_" +
nombreMetodo+ "_" + DateTime.Now.Ticks + ".xml");
StreamWriter escritorRes = File.CreateText("C:\\logs\\response_" + nombreMetodo+ "_" + DateTime.Now.Ticks + ".xml");


// Object is accessed "XMLRequest" TraceExtension class and call property "OuterXml".
string soapRequest = TraceExtension.XmlRequest.OuterXml;
string soapResponse = TraceExtension.XmlResponse.OuterXml;

escritorReq.Write(soapRequest);
escritorReq.Close();
//Access to the object "XmlResponse" TraceExtension class and called his property "OuterXml".
escritorRes.Write(soapResponse);
escritorRes.Close();
}


Mode of use; Example

private void getStudentData(int identification)
{
PJWS.proxy2013 ws = new PJWS.proxy2013();
PJWS.getStudentDataResponse data = new contiWebAJAX.PJWS.getStudentData();
data = ws.getData(identification);

//call the above method most suitable
soapMessageRecord("getStudentData");

// or simply gain access in this way.
var soapRequest = TraceExtension.XmlRequest.OuterXml;

// or simply gain access in this way
var soapResponse = TraceExtension.XmlResponse.OuterXml;
}

In the web.config must add the following lines:

    <system.web>
<compilation debug="true" targetFramework="4.0" />
<webServices>
<soapExtensionTypes>
<add type="TestProject.TraceExtension,
TestProject" priority="1" group="0" />
</soapExtensionTypes>
</webServices>
</system.web>
See Also:

ads

Ditulis Oleh : Mandrake as Angelo Hari: 10:15 Kategori:

6 comentarios:

Anonymous dijo...

Doesn't work for me where you put:

var soapRequest = TraceExtension.XmlRequest.OuterXml;

"XmlRequest" is null. I can't recover the soap message.

The only way it works for me is writing in a file, but I need another solution. I can't use files in my app.

Angelo dijo...

Have you made ​​sure that the request is not null?
This method works when you go to consume WS from a client.

Anonymous dijo...

Thanks for answer! Fortunelly I made it work jeje. I forget to register the soapextension class in web.config file. But I had to modify the TraceExtension class because the request where mixed. That is, the request A mingled with the response B.

Anonymous dijo...

Angelo, so you just copy and paste this crappy code from another punk like you. Nice! Way to go.

Anonymous dijo...

Sorry i'm a beginner.

I create form application as a web service client.

where i use this code ???










in my client or in web service?

Admirador dijo...

Marvellous. I'll try.

SOAP XML using ASMX - OK

SOAP XML using WCF now