Wcf 如何拦截SOAP消息

Wcf 如何拦截SOAP消息,wcf,soap,Wcf,Soap,作为我进入WCF的一部分,我正在研究消息契约,并了解它们如何影响SOAP消息的内容 真正酷的是,如果你能截取消息,看看它是如何构造的。请问我该怎么做 (到目前为止,我已经看过Wireshark(太“低级”)并想到了Microsoft SOAP toolkit,但它早在2005年就被Microsoft淘汰了)我通常用来检查通过http发送的SOAP消息。我通常用来检查通过http发送的SOAP消息。当您安装.NET 3.5或更高版本时,您应该在计算机上的某个位置(隐藏在目录的深处,如C:\Prog

作为我进入WCF的一部分,我正在研究消息契约,并了解它们如何影响SOAP消息的内容

真正酷的是,如果你能截取消息,看看它是如何构造的。请问我该怎么做


(到目前为止,我已经看过Wireshark(太“低级”)并想到了Microsoft SOAP toolkit,但它早在2005年就被Microsoft淘汰了)

我通常用来检查通过http发送的SOAP消息。

我通常用来检查通过http发送的SOAP消息。

当您安装.NET 3.5或更高版本时,您应该在计算机上的某个位置(隐藏在目录的深处,如
C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\
或类似目录)

该工具允许您连接到WCF服务,并且可以调用该服务上的方法—您可以查看XML请求和响应的所有优点:-)

另一种选择是使用类似免费版本的东西,该版本旨在测试SOAP服务并以XML显示请求和响应

SoapUI是一个很好的工具,但它不是WCF专用的,它只是一个“通用”的SOAP/WSDL工具,对任何SOAP服务都非常有效


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

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

该工具允许您连接到WCF服务,并且可以调用该服务上的方法—您可以查看XML请求和响应的所有优点:-)

另一种选择是使用类似免费版本的东西,该版本旨在测试SOAP服务并以XML显示请求和响应

SoapUI是一个很好的工具,但它不是WCF专用的,它只是一个“通用”的SOAP/WSDL工具,对任何SOAP服务都非常有效


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

如果您想写入日志记录,请尝试使用TraceExtension类,下面是一个示例, 在这个链接中,您将找到关于如何实现它的详细信息,我使用它,它工作得非常好

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Web.Services.Protocols;
使用System.IO;
使用System.Xml;
名称空间PruebaServiciosNBC
{
类TraceExtension:SoapExtension
{
私有流;
私有流新闻流;
私有静态xmldocumentxmlrequest;
/// 
///获取发送到PayPal的传出XML请求
/// 
公共静态XmlDocument XmlRequest
{
获取{return xmlRequest;}
}
私有静态xml文档xmlResponse;
/// 
///获取从PayPal发送的传入XML响应
/// 
公共静态XmlDocument XmlResponse
{
获取{return xmlResponse;}
}
/// 
///保存表示SOAP请求的流
///或将SOAP响应写入本地内存缓冲区。
/// 
/// 
/// 
公共覆盖流链流(Stream-Stream)
{
oldStream=流;
newStream=newmemoryStream();
返回新闻流;
}
/// 
///如果SoapMessageStage使SoapRequest或
///SoapResponse仍然是要发送或接收的SOAP格式,
///将其保存到xmlRequest或xmlResponse属性。
/// 
/// 
公共覆盖无效ProcessMessage(SoapMessage消息)
{
开关(消息阶段)
{
案例SoapMessageStage.BeforeSerialize:
打破
案例SoapMessageStage.AfterSerialize:
xmlRequest=GetSoapEnvelope(新闻流);
CopyStream(新闻流、旧流);
打破
案例SoapMessageStage.BeforeDeserialize:
CopyStream(旧流、新闻流);
xmlResponse=GetSoapEnvelope(新闻流);
打破
案例SoapMessageStage.After反序列化:
打破
}
}
/// 
///返回所提供流中Soap信封的XML表示形式。
///将流的位置重置为零。
/// 
/// 
/// 
私有XmlDocument GetSoapEnvelope(流)
{
XmlDocument xml=新的XmlDocument();
流位置=0;
StreamReader=新的StreamReader(流);
LoadXml(reader.ReadToEnd());
流位置=0;
返回xml;
}
/// 
///复制流。
/// 
/// 
/// 
私有void CopyStream(从流、流到流)
{
TextReader=新的StreamReader(来自);
TextWriter writer=新的StreamWriter(到);
writer.WriteLine(reader.ReadToEnd());
writer.Flush();
}
#区域努普
/// 
///仅因必须实施而包含。
/// 
/// 
/// 
/// 
公共覆盖对象
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
    }
}