Trace Soap Messages Logger SoapExtension


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);
            }
        }
    }
}

posted @ 2009-05-11 11:55  于斯人也  阅读(1908)  评论(0编辑  收藏  举报