如何拦截SOAP消息

时间:2012-01-17 13:04:50

标签: wcf soap

作为我参与WCF的一部分,我正在研究消息合同,并了解它们如何影响SOAP消息的内容。

如果你能拦截这个消息并看看它是如何构建的,那真的很酷。我该怎么做呢...

(到目前为止,我已经看过Wireshark(太'低级')并且考虑过Microsoft SOAP工具包,但是2005年它被微软退役了)

3 个答案:

答案 0 :(得分:4)

当您安装.NET 3.5或更高版本时,您的计算机上应该有WCF Test Client(隐藏在C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\之类的目录或类似内容中。

这个工具允许你连接到你的WCF服务,你可以在它上面调用方法 - 你可以看看它的所有美丽的XML请求和响应: - )

enter image description here

另一种选择是使用像SoapUI这样的免费版本,用于测试SOAP服务并在XML中显示请求和响应

enter image description here

SoapUI是一个很棒的工具 - 但它不是特定于WCF,它只是一个“通用”SOAP / WSDL工具,可以很好地对抗任何SOAP服务。

如果您不是在寻找“按需”捕获请求和响应,但如果您对跟踪所有请求和响应更感兴趣,则应调查WCF tracing features并设置它们根据需要。您可以将所有流量捕获到磁盘上的*.svclog文件中,并且WCF Service Trace Viewer(也可以免费使用WCF)来检查这些跟踪文件。

答案 1 :(得分:2)

我通常使用Fiddler来检查通过http发送的肥皂消息。

答案 2 :(得分:1)

如果要编写日志记录,请尝试使用TraceExtension类,下面的示例, 在这个链接中,你会找到有关如何实现它的详细信息,我使用它并且它工作得非常好

http://www.systemdeveloper.info/2013/11/trace-soap-requestresponse-xml-with.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Services.Protocols;
using System.IO;
using System.Xml;

namespace PruebaServiciosNBC
{
    class TraceExtension : SoapExtension
    {
        private Stream oldStream;
        private Stream newStream;

        private static XmlDocument xmlRequest;
        /// <summary>
        /// Gets the outgoing XML request sent to PayPal
        /// </summary>
        public static XmlDocument XmlRequest
        {
            get { return xmlRequest; }
        }

        private static XmlDocument xmlResponse;
        /// <summary>
        /// Gets the incoming XML response sent from PayPal
        /// </summary>
        public static XmlDocument XmlResponse
        {
            get { return xmlResponse; }
        }

        /// <summary>
        /// Save the Stream representing the SOAP request
        /// or SOAP response into a local memory buffer. 
        /// </summary>
        /// <param name="stream">
        /// <returns></returns>
        public override Stream ChainStream(Stream stream)
        {
            oldStream = stream;
            newStream = new MemoryStream();
            return newStream;
        }

        /// <summary>
        /// If the SoapMessageStage is such that the SoapRequest or
        /// SoapResponse is still in the SOAP format to be sent or received,
        /// save it to the xmlRequest or xmlResponse property.
        /// </summary>
        /// <param name="message">
        public override void ProcessMessage(SoapMessage message)
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeSerialize:
                    break;
                case SoapMessageStage.AfterSerialize:
                    xmlRequest = GetSoapEnvelope(newStream);
                    CopyStream(newStream, oldStream);
                    break;
                case SoapMessageStage.BeforeDeserialize:
                    CopyStream(oldStream, newStream);
                    xmlResponse = GetSoapEnvelope(newStream);
                    break;
                case SoapMessageStage.AfterDeserialize:
                    break;
            }
        }

        /// <summary>
        /// Returns the XML representation of the Soap Envelope in the supplied stream.
        /// Resets the position of stream to zero.
        /// </summary>
        /// <param name="stream">
        /// <returns></returns>
        private XmlDocument GetSoapEnvelope(Stream stream)
        {
            XmlDocument xml = new XmlDocument();
            stream.Position = 0;
            StreamReader reader = new StreamReader(stream);
            xml.LoadXml(reader.ReadToEnd());
            stream.Position = 0;
            return xml;
        }

        /// <summary>
        /// Copies a stream.
        /// </summary>
        /// <param name="from">
        /// <param name="to">
        private void CopyStream(Stream from, Stream to)
        {
            TextReader reader = new StreamReader(from);
            TextWriter writer = new StreamWriter(to);
            writer.WriteLine(reader.ReadToEnd());
            writer.Flush();
        }

        #region NoOp
        /// <summary>
        /// Included only because it must be implemented.
        /// </summary>
        /// <param name="methodInfo">
        /// <param name="attribute">
        /// <returns></returns>
        public override object GetInitializer(LogicalMethodInfo methodInfo,
            SoapExtensionAttribute attribute)
        {
            return null;
        }

        /// <summary>
        /// Included only because it must be implemented.
        /// </summary>
        /// <param name="WebServiceType">
        /// <returns></returns>
        public override object GetInitializer(Type WebServiceType)
        {
            return null;
        }

        /// <summary>
        /// Included only because it must be implemented.
        /// </summary>
        /// <param name="initializer">
        public override void Initialize(object initializer)
        {
        }
        #endregion NoOp
    }
}