namespace Microshaoft
{
using System;
using System.IO;
using System.Web.Services.Protocols;
using System.Configuration;
public class TraceSoapMessagesLoggerSoapExtension : SoapExtension
{
private Stream _originalStream;
private Stream _workStream;
private string _filePath;
public override Stream ChainStream(Stream stream)
{
_originalStream = stream;
_workStream = new MemoryStream();
return _workStream;
}
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
//return ((TraceExtensionAttribute)attribute).Filename;
return null;
}
private static string _SoapMessagesLogPath = ConfigurationManager.AppSettings["SoapMessagesLogPath"];
public override object GetInitializer(Type WebServiceType)
{
// Return a file name to log the trace information to, based on the
// type.
if (!_SoapMessagesLogPath.EndsWith(@"\"))
{
_SoapMessagesLogPath += @"\";
}
return _SoapMessagesLogPath + WebServiceType.FullName + ".{0}.{1}.log";
}
// Receive the file name stored by GetInitializer and store it in a
// member variable for this specific instance.
public override void Initialize(object initializer)
{
_filePath = (string) initializer;
}
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
WriteStream();
break;
case SoapMessageStage.BeforeDeserialize:
ReadStream();
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new Exception("invalid stage");
}
}
public void WriteStream()
{
_workStream.Position = 0;
byte[] buffer = ReadStreamToBytes(_workStream);
TextReader reader = new StreamReader(_workStream);
string s = reader.ReadToEnd();
WriteLog(s, "response", _filePath);
_originalStream.Write(buffer, 0, buffer.Length);
}
public void ReadStream()
{
//解压 请求
byte[] bytes = ReadStreamToBytes(_originalStream);
TextReader reader = new StreamReader(_originalStream);
string s = reader.ReadToEnd();
WriteLog(s, "request", _filePath);
_workStream.Write(bytes, 0, bytes.Length);
_workStream.Position = 0;
}
private static void WriteLog(string data, string title, string filePath)
{
string path = Path.GetDirectoryName(filePath);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string fileName = string.Format(filePath, title, DateTime.Now.ToString("yyyy-MM-dd.HH"));
using (FileStream fs = new FileStream
(
fileName
, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite
)
)
{
StreamWriter w = new StreamWriter(fs);
w.BaseStream.Seek(0, SeekOrigin.End);
w.WriteLine(title + "Begin===========" + DateTime.Now);
w.Flush();
w.WriteLine(data);
w.WriteLine(title + "End=============");
w.Flush();
w.Close();
}
}
public static byte[] ReadStreamToBytes(Stream stream)
{
byte[] buffer = new byte[64 * 1024];
int r = 0;
int l = 0;
long position = -1;
if (stream.CanSeek)
{
position = stream.Position;
stream.Position = 0;
}
MemoryStream ms = new MemoryStream();
while (true)
{
r = stream.Read(buffer, 0, buffer.Length);
if (r > 0)
{
l += r;
ms.Write(buffer, 0, r);
}
else
{
break;
}
}
byte[] bytes = new byte[l];
ms.Position = 0;
ms.Read(bytes, 0, (int) l);
ms.Close();
ms = null;
if (position >= 0)
{
stream.Position = position;
}
return bytes;
}
}
[AttributeUsage(AttributeTargets.Method)]
public class TraceSoapMessagesLoggerSoapExtensionAttribute : SoapExtensionAttribute
{
private int _priority;
public override int Priority
{
get
{
return _priority;
}
set
{
_priority = value;
}
}
public override Type ExtensionType
{
get
{
return typeof(TraceSoapMessagesLoggerSoapExtension);
}
}
}
}