代码之家  ›  专栏  ›  技术社区  ›  user1019042

C中的陷阱SOAP请求/响应#

  •  0
  • user1019042  · 技术社区  · 10 年前

    我正在尝试捕获soap通信的请求/响应xml。我很想使用WCF,但必须遵守雇主的要求。 因此,我有一个示例asmx网站,在我的服务中有这个webmethod:

    [WebMethod]
    public int Multiply(int x, int y)
    {
        return x * y;
    }
    

    该网站已添加到IIS,我可以在浏览器中看到它:

    http://localhost/WebService/Service.asmx?op=Multiply
    

    当我给它两个int值时,它就起作用了。

    我试图捕获正在发送和接收的SOAP主体请求。根据我的研究,如果我添加一个soap扩展,我就能做到这一点。所以,我看这个例子: https://stackoverflow.com/a/10613433/1019042 并试图模仿它。

    我用这个类向我的解决方案中添加了一个类库项目:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web.Services.Protocols;
    using System.IO;
    using System.Reflection;
    
    namespace SoapExtensions
    {
        public class SoapLoggerExtension : SoapExtension
        {
            //private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
            private Stream oldStream;
            private Stream newStream;
    
            public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
            {
                WriteMessages("inside the getinitializer1");
                return null;
            }
    
            public override object GetInitializer(Type serviceType)
            {
                WriteMessages("inside the getinitializer2");
                WriteMessages("inside the getinitializer");
                return null;
            }
    
            public override void Initialize(object initializer)
            {
                WriteMessages("inside the Initialize");
            }
    
            public override System.IO.Stream ChainStream(System.IO.Stream stream)
            {
                WriteMessages("inside the ChainStream");
                oldStream = stream;
                newStream = new MemoryStream();
                return newStream;
            }
    
            public override void ProcessMessage(SoapMessage message)
            {
                WriteMessages("inside the ProcessMessage");
                switch (message.Stage)
                {
                    case SoapMessageStage.BeforeSerialize:
                        break;
                    case SoapMessageStage.AfterSerialize:
                        Log(message, "AfterSerialize");
                        CopyStream(newStream, oldStream);
                        newStream.Position = 0;
                        break;
                    case SoapMessageStage.BeforeDeserialize:
                        CopyStream(oldStream, newStream);
                        Log(message, "BeforeDeserialize");
                        break;
                    case SoapMessageStage.AfterDeserialize:
                        break;
                }
            }
    
            private void WriteMessages(string message)
            {
                StreamWriter sw = new StreamWriter(@"C:\MyFolder\LogFolder\myLog.txt", true);
                sw.WriteLine(message);
                sw.Close();
            }
    
            public void Log(SoapMessage message, string stage)
            {
                newStream.Position = 0;
                string contents = (message is SoapServerMessage) ? "SoapRequest " : "SoapResponse ";
                contents += stage + ";";
    
                StreamReader reader = new StreamReader(newStream);
    
                contents += reader.ReadToEnd();
    
                newStream.Position = 0;
                WriteMessages(contents.ToString());
                //log.Debug(contents);
            }
    
            void ReturnStream()
            {
                WriteMessages("inside the ReturnStream");
                CopyAndReverse(newStream, oldStream);
            }
    
            void ReceiveStream()
            {
                WriteMessages("inside the ReceiveStream");
                CopyAndReverse(newStream, oldStream);
            }
    
            public void ReverseIncomingStream()
            {
                WriteMessages("inside the ReverseIncomingStream");
                ReverseStream(newStream);
            }
    
            public void ReverseOutgoingStream()
            {
                WriteMessages("inside the ReverseOutgoingStream");
                ReverseStream(newStream);
            }
    
            public void ReverseStream(Stream stream)
            {
                WriteMessages("inside the ReverseStream");
                TextReader tr = new StreamReader(stream);
                string str = tr.ReadToEnd();
                char[] data = str.ToCharArray();
                Array.Reverse(data);
                string strReversed = new string(data);
    
                TextWriter tw = new StreamWriter(stream);
                stream.Position = 0;
                tw.Write(strReversed);
                tw.Flush();
            }
            void CopyAndReverse(Stream from, Stream to)
            {
                WriteMessages("inside the CopyAndReverse");
                TextReader tr = new StreamReader(from);
                TextWriter tw = new StreamWriter(to);
    
                string str = tr.ReadToEnd();
                char[] data = str.ToCharArray();
                Array.Reverse(data);
                string strReversed = new string(data);
                tw.Write(strReversed);
                tw.Flush();
            }
    
            private void CopyStream(Stream fromStream, Stream toStream)
            {
                WriteMessages("inside the CopyStream");
                try
                {
                    StreamReader sr = new StreamReader(fromStream);
                    StreamWriter sw = new StreamWriter(toStream);
                    sw.WriteLine(sr.ReadToEnd());
                    sw.Flush();
                }
                catch (Exception ex)
                {
                    string message = String.Format("CopyStream failed because: {0}", ex.Message);
                    WriteMessages("Message is: " + message);
                    WriteMessages("ex is: " + ex);
                   // log.Error(message, ex);
                }
            }
        }
    
        [AttributeUsage(AttributeTargets.Method)]
        public class SoapLoggerExtensionAttribute : SoapExtensionAttribute
        {
            private int priority = 1;
    
            public override int Priority
            {
                get { return priority; }
                set { priority = value; }
            }
    
            public override System.Type ExtensionType
            {
                get { return typeof(SoapLoggerExtension); }
            }
        }
    }
    

    我给每个方法都添加了一条消息,看看是否在扩展中调用了任何东西。 然后转到我的服务并添加了对该项目的引用。我转到服务的web.config并将其添加到system.web:

      <webServices>
        <soapExtensionTypes>
          <add type="SoapExtensions.SoapLoggerExtension, SoapExtension"
             priority="1" group="0" />
        </soapExtensionTypes>
      </webServices>
    

    问题是我没有在mylog.txt中得到任何东西,就像它没有击中我的肥皂服务一样。 文件位于以下文件夹中 每个人 可以完全访问它。 不应该打电话给 通过soapextension记录一些内容?我的设置是否错误?我还有别的事要做吗? 我正在使用框架3.5

    1 回复  |  直到 7 年前
        1
  •  0
  •   Raja Nadar    10 年前

    试试看

      <webServices>
        <soapExtensionTypes>
          <add type="SoapExtensions.SoapLoggerExtension, SoapExtensions"
             priority="1" group="0" />
        </soapExtensionTypes>
      </webServices>
    

    类型的程序集名称中缺少“s”。

    此外,一旦您在以下位置启动浏览器 http://localhost/WebService/Service.asmx?op=Multiply ,使用Visual Studio并附加到进程。

    通过这种方式,您可以调试传入的多重调用并跟踪流。你会看到扩展点是否被击中。