`

c#2.0使用TraceExtension记录WebService的Soap日志

阅读更多
在c# 2.0的WebService中,可以使用SoapExtension来扩展WebService的功能。
在日常接口的调测中,尤其是不同平台的WebService接口调测中,很容易出现请求错误或者请求参数为空,或者复杂请求参数的属性为空的情况。这样,就需要查看传递的xml报文。
    当然,我们可以使用类似wireshark之类的抓包工具来看具体的传输东西,但是那样略嫌麻烦。在微软的官网,就给了一个TraceExtension的例子,继承自SoapExtension,用来记录传入和传出的报文。

示例如下(注意要看下面的备注及说明):
1.先创建SoapExtension.cs,新建一个App_Code文件夹,把cs文件放在这个目录下
///SoapExtension.cs
public class TraceExtension : SoapExtension
{
    private readonly string FILEPREFIX = "D:\\logs";
    Stream oldStream;
    Stream newStream;
    string filename;

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

    // When the SOAP extension is accessed for the first time, the XML Web
    // service method it is applied to is accessed to store the file
    // name passed in, using the corresponding SoapExtensionAttribute.	
    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return ((TraceExtensionAttribute)attribute).Filename;
    }

    // The SOAP extension was configured to run using a configuration file
    // instead of an attribute applied to a specific XML Web service
    // method.
    public override object GetInitializer(Type WebServiceType)
    {
        // Return a file name to log the trace information to, based on the
        // type.
        return FILEPREFIX.TrimEnd('\\') + "\\" + WebServiceType.FullName + ".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)
    {
        filename = (string)initializer;
    }

    //  If the SoapMessageStage is such that the SoapRequest or
    //  SoapResponse is still in the SOAP format to be sent or received,
    //  save it out to a file.
    public override void ProcessMessage(SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                WriteOutput(message);
                break;
            case SoapMessageStage.BeforeDeserialize:
                WriteInput(message);
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
        }
    }

    public void WriteOutput(SoapMessage message)
    {
        newStream.Position = 0;
        FileStream fs = new FileStream(filename, FileMode.Append,
            FileAccess.Write);
        StreamWriter w = new StreamWriter(fs);

        string soapString = (message is SoapServerMessage) ? "SoapResponse" : "SoapRequest";
        w.WriteLine("-----" + soapString + " at " + DateTime.Now);
        w.Flush();
        Copy(newStream, fs);
        w.Close();
        newStream.Position = 0;
        Copy(newStream, oldStream);
    }

    public void WriteInput(SoapMessage message)
    {
        Copy(oldStream, newStream);
        FileStream fs = new FileStream(filename, FileMode.Append,
            FileAccess.Write);
        StreamWriter w = new StreamWriter(fs);

        string soapString = (message is SoapServerMessage) ?
            "SoapRequest" : "SoapResponse";
        w.WriteLine("-----" + soapString +
            " at " + DateTime.Now);
        w.Flush();
        newStream.Position = 0;
        Copy(newStream, fs);
        w.Close();
        newStream.Position = 0;
    }

    void Copy(Stream from, Stream to)
    {
        TextReader reader = new StreamReader(from);
        TextWriter writer = new StreamWriter(to);
        writer.WriteLine(reader.ReadToEnd());
        writer.Flush();
    }
}

// Create a SoapExtensionAttribute for the SOAP Extension that can be
// applied to an XML Web service method.
[AttributeUsage(AttributeTargets.Method)]
public class TraceExtensionAttribute : SoapExtensionAttribute
{

    private string filename = ".\\log.txt";
    private int priority;

    public override Type ExtensionType
    {
        get { return typeof(TraceExtension); }
    }

    public override int Priority
    {
        get { return priority; }
        set { priority = value; }
    }

    public string Filename
    {
        get
        {
            return filename;
        }
        set
        {
            filename = value;
        }
    }
}


2.在web.config中的system.web节点下,加入以下配置
<system.web>
	<webServices>
		<soapExtensionTypes>
			<add type="TraceExtension,App_Code" priority="1" group="0"/>
		</soapExtensionTypes>
	</webServices>
...
</system.web>


3.启动,访问。就能看到soap报文日志了。

备注及说明:
1.TraceExtension类可以放在你项目中的非App开头的目录下,然后在web.config中App_code修改成dll名字,TraceExtension前加上命名空间即可。但不推荐这么做,因为调试的时候可能会修改TraceExtension的实现,所以最好放在类似App_Code目录下,这样发布的时候,只需要拷贝这个目录及cs文件即可,iis动态编译,修改的时候比较方便

2.附件中的WebService比较简单,但是通过浏览器直接调用的时候,没有记录soap日志,通过类似WebService Studio或新建客户端访问时,能记录日志

3.这个TraceExtension比较简单,直接写文件的方式记录文本日志的,推荐采用NLog或者log4net的方式记录。同时由于这种简单的实现方式,记录日志的目录必须是存在的。我这里的FILEPREFIX就是事先建好的目录~~

附件是完整的项目示例,欢迎交流~~
分享到:
评论
2 楼 Ajita 2013-04-20  
wt_kelly 写道
这种方法记录的日志只能说明 有多少次请求和响应,但是怎么区分 这个请求所对应的响应式哪个呢?

这种打印soap的方式是拦截输入输出流,所以不能确定对应关系。另外这种方式一般是用在调试双方webservice的时候使用,看看双方的报文完整不,不建议用于生产日志。
你说的场景建议在业务接口里面处理。
1 楼 wt_kelly 2013-04-19  
这种方法记录的日志只能说明 有多少次请求和响应,但是怎么区分 这个请求所对应的响应式哪个呢?

相关推荐

    C#winform下WebService Soap应用

    在本文中,我们将详细介绍如何使用 C# 语言在 Winform 平台下开发 WebService Soap 应用,以实现列车时刻、手机归属、QQ 在线、航空时刻等查询工具。 WebService Soap 简介 WebService Soap 是一种基于 SOAP 协议...

    CXF打印SOAP报文,记录WebService日志

    在企业级应用开发中,尤其是涉及到服务端接口(如WebService)的设计与实现时,日志记录变得尤为重要。它不仅可以帮助开发者更好地理解系统运行状况、定位问题所在,还能为后续的维护工作提供重要的参考依据。Apache...

    C#WebService-Soap扩展实现安全认证

    分高但绝对值-简介: 1、利用SoapExtension,SoapExtensionAttribute,实现Soap自定义Attribute(标签)扩展类。...4、当然你还可以发挥,比如压缩消息,日志记录,Trace之类,网上也有很多文章讲。

    C#实现SOAP调用WebService

    最近写了一个SOA服务,开始觉得别人拿到我的服务地址,然后直接添加引用就可以使用了,结果"大牛"告知不行。 让我写一个SOAP调用服务的样例,我有点愣了,因为没做过这方面的,于是搞到了一个Demo,然后学习了下。

    C#调用使用java的带soaphead的webservice

    最后,`C#调用使用java的带saophead的webservice-说明书.docx`应该是详细的步骤指南,包含了如何配置和调用Web服务的具体细节。确保按照说明书的指示操作,以确保正确地设置了SOAP Header和调用了Web服务。 总的来...

    C#高级应用开发(线程的使用、*NET 2.0 新特性、webservice 文件监视 )

    线程的使用、*NET 2.0 新特性、webservice 文件监视、C#高级应用(如何将聊天程序做成windows服务、COM+服务解决同时访问大量数据并发性、COM+服务实现银行转账系统、如何用Remoting技术传送文件、大规模数据访问时...

    C#最简单最完整的webservice实例(能打log,配有log4net)

    【C#最简单最完整的Web服务(WebService)实例与日志记录(log4net)】 在C#编程中,创建一个简单的Web服务(WebService)可以帮助开发者实现不同应用程序间的通信。本实例将展示如何构建一个基本的C# WebService,...

    SAP Webservice日志查询报表2.0

    这个功能允许用户输入特定的关键词,如服务名、错误代码或交易ID,快速定位到相关的日志记录,提高了问题排查的效率。例如,当遇到某个服务调用失败时,IT人员可以使用关键字搜索,快速找到相关的日志条目,从而更快...

    C#通过SOAP使用HttpWebRequest调用带有身份验证的WebService示例

    本示例使用C#构造SOAP信息,通过HttpWebRequest调用java编写的带有Windows身份验证的WebService,代码中详细注释了每行代码的功能与作用; 对应文章:http://blog.csdn.net/cgs_______/article/details/77894599

    C#实现SOAP调用WebService.rar

    本主题聚焦于如何利用C#进行SOAP(Simple Object Access Protocol)调用来与WebService进行通信。SOAP是一种基于XML的协议,它允许分布式系统之间交换结构化和类型化的信息。 SOAP调用通常涉及到以下步骤: 1. **...

    C#_.NET_动态调用webservice的三种方式

    C# _.NET_动态调用webservice的三种方式 在本文中,我们将讨论如何动态调用WebService的三种方式。在某些情况下,我们可能需要在程序运行期间动态调用一个未知的服务。这可以通过使用.NET Framework的System.Web....

    c#调用java带身份验证webservice

    对于Java Web服务,通常使用SOAP(Simple Object Access Protocol)协议,它基于XML来传递数据。C#可以通过创建一个与Java Web服务的WSDL(Web Service Description Language)文件对应的代理类来实现调用。 1. **...

    c# httpwebrequest调用webservice demo

    ### C# 使用 HttpWebRequest 调用 WebService 的方法详解 在C#开发中,有时候我们需要与WebService进行交互,获取或发送数据。本篇文章将详细介绍如何利用`HttpWebRequest`类来实现这一功能,并通过示例代码帮助...

    JS实现 WebService Soap 通讯

    JS WebService Soap 通讯,查询QQ号码在线状态,手机号码归属地

    asp.net2.0项目之利用webService实现的新闻系统(VS2005+SQL2000)

    利用webService实现的新闻系统 实现了新闻的添加、编辑、删除以及用户管理功能,功能上比较简单,但是都是通过调用webService来实现的,而且采用了MVC面向对象模式进行开发,用户登录采用了自定义控件 安装注意: ...

    php编写webservice soap服务端及客户端

    标题“php编写webservice soap服务端及客户端”意味着我们将讨论如何使用PHP实现SOAP协议的两个关键部分:服务提供者和服务消费者。 首先,让我们深入了解PHP如何构建SOAP服务端。在PHP中,我们可以使用SoapServer...

    C#调用JavaWebService

    调用WebService,最简单的办法当然是直接添加WEB引用,然后自动产生代理类,但是在调用JAVA的WebService时并没有这么简单,特别是对于SoapHeader的处理,通过C#添加Web引用方式访问JavaWebService的方法,除了string...

    webservice、soap等接口调用参考

    在标题和描述中提到的"webservice,soap调用",这是指使用SOAP协议来调用Web服务的过程。SOAP消息通常以HTTP或HTTPS作为传输协议,其结构主要由三个部分组成:Header、Body和Envelope。Header部分包含了关于消息处理...

    Java使用SOAP获取webservice实例解析

    ### Java使用SOAP获取WebService实例解析 #### WebService简介 WebService是一种跨编程语言和操作系统平台的、在网络上进行数据交换的一种方式。它使用标准的Internet协议,如HTTP、XML、SOAP等来实现不同系统间的...

Global site tag (gtag.js) - Google Analytics