Env: Visual Studio 2005
If you make direct SOAP requests, you need to use SOAP extension to log your requests and responses. SOAP extensions is a Microsoft ASP.NET WebMethod interception mechanism that can be used to manipulate SOAP requests/responses before they are sent on the wire.
Here are the steps to implement a SOAP Extension:
1. Using Visual Studio .NET, create a new .NET class library project in the language of your choice and add the SOAP extension.
2. Add the SOAP extension assembly as reference and declare the SOAP extension on the XML Web service reference of our application
Here is a C# sample adapted from the SOAP Extension sample code at Microsoft MSDN
using System;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
namespace TraceExtension
{
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;
}
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return null;
}
public override object GetInitializer(Type WebServiceType)
{
return null;
}
public override void Initialize(object initializer)
{
// Set the log file
filename= "c:\\log.txt";
}
// SaveSoapRequest or SoapResponse to the log 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;
default:
throw new Exception("invalidstage");
}
}
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 SoapExtensionAttributefor the SOAP Extension that can be applied to an XML Web service method.
[AttributeUsage(AttributeTargets.Method)]
public class TraceExtensionAttribute : SoapExtensionAttribute
{
private int priority;
public override Type ExtensionType
{
get { return typeof(TraceExtension); }
}
public override int Priority
{
get { return priority; }
set {priority = value; }
}
}
}
Save this library project as TraceExtension and compile.
In the project where you invoke your Web Services:
- In the Solution Explorer, Click on "Show All Files"
- Expand Web References and double click on References.cs
- Locate the method for which you wish to add logging.
- Declare the SOAP Extension as follows:
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("",Use=System.Web.Services.Description.SoapBindingUse.Literal,ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare),TraceExtension.TraceExtension()]
Here is how to add it to GeteBayOfficialTime:
[System.Web.Services.Protocols.SoapHeaderAttribute("RequesterCredentials",Direction=System.Web.Services.Protocols.SoapHeaderDirection.InOut)]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("",Use=System.Web.Services.Description.SoapBindingUse.Literal,ParameterStyle=System.Web.Services.Protocols.Soap arameterStyle.Bare),TraceExtension.TraceExtension()]
[return:System.Xml.Serialization.XmlElementAttribute("GeteBayOfficialTimeResponse",Namespace="urn:ebay:apis:eBLBaseComponents")]
public GeteBayOfficialTimeResponseTypeGeteBayOfficialTime ([System.Xml.Serialization.XmlElementAttribute(Namespace="urn:ebay:apis:eBLBaseComponents")]GeteBayOfficialTimeRequestType GeteBayOfficialTimeRequest)
{
object[] results = this.Invoke("GeteBayOfficialTime",new object[] {
GeteBayOfficialTimeRequest});
return((GeteBayOfficialTimeResponseType)(results[0]));
}
source: http://ebay.custhelp.com/cgi-bin/ebay.cfg/php/enduser/std_adp.php?p_faqid=350