Sunday, September 16, 2007

Logging serialization and de-serialization

To implement serialization derive your class from SoapExtension, and override all methods. ProcessMessage is the method that acts as a nevous system for our functionality. This method is called on a variety of scenarios. Before start f serialization, during serialization, after serialization etc….

If we want logging to be done, then we implement our functionality in the method ProcessMessage. If you want to achieve encryption then we need to have our functionality defined in the section BeforeSerialize and BeforeDeSerialize. Encrypt message before serialize operations and before deserialize operations.

Sample code is appended for your reference

using System;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;

[AttributeUsage(AttributeTargets.Method)]
public class TraceExtensionAttribute : SoapExtensionAttribute
{

private string filename = "c:\\SOAPTraceLog.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;
}
}
}

public class TraceExtension : SoapExtension
{
Stream oldStream;
Stream newStream;
string filename;

public override object GetInitializer(LogicalMethodInfo methodInfo,
SoapExtensionAttribute attribute) {
return ((TraceExtensionAttribute) attribute).Filename;
}

public override object GetInitializer(Type serviceType) {
return typeof(TraceExtension);
}

public override void Initialize (object initializer) {
filename = (string) initializer;
}

public override void ProcessMessage(SoapMessage message) {
switch (message.Stage) {

case SoapMessageStage.BeforeSerialize:
break;

case SoapMessageStage.AfterSerialize:
//WriteOutput();// message );
WriteOutput(message );
break;

case SoapMessageStage.BeforeDeserialize:
WriteInput ( message );
break;

case SoapMessageStage.AfterDeserialize:
break;

default:
throw new Exception("invalid stage");
}
}

public override Stream ChainStream( Stream stream ){
oldStream = stream;
newStream = new MemoryStream();
return newStream;
}

//public void WriteOutput()//SoapMessage message)
public void WriteOutput(SoapMessage message)
{
newStream.Position = 0;
FileStream fs = new FileStream(filename, FileMode.Append,
FileAccess.Write);

StreamWriter w = new StreamWriter(fs);

w.WriteLine("---------------------------------- Response at " + message.ToString() +
DateTime.Now);
w.Flush();
Copy (newStream, fs);
fs.Close();
newStream.Position = 0;
Copy (newStream, oldStream);
}

public void WriteInput ( SoapMessage message )
{
Copy(oldStream, newStream);
FileStream fs = new FileStream(filename, FileMode.Append);
StreamWriter w = new StreamWriter(fs);

w.WriteLine("============================== Request at " +
DateTime.Now);
w.Flush();
newStream.Position = 0;
Copy(newStream, fs);
fs.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();
}
}


///
/// Summary description for TraceSerialize
///

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class TraceSerialize : System.Web.Services.WebService {

public TraceSerialize () {

//Uncomment the following line if using designed components
//InitializeComponent();
}

[WebMethod]
public string HelloWorld() {
return "Hello World";
}

[WebMethod, TraceExtension(Filename = "C:\\WebServiceTrace.Log")]
public string StartTracing()
{
return "Start Tracing ....";
}

}

No comments: