1

我已经构建了一个进行 WCF 调用的 Windows 窗体客户端应用程序。我希望能够从应用程序中显示实际的请求和响应,包括 SOAP 标头和有关 POST/Get 的信息。有没有办法在客户端上配置跟踪侦听器并在客户端内使用它,在文本框中显示内容?

我已经配置了将消息输出到文件的跟踪。此配置在我的客户端应用程序上,因此它记录了它对 wcf 服务的所有调用和响应。因此添加了源,并且每个源都有一个 XmlTraceListener,它处理对 xml 日志文件的写入。我现在要做的是利用客户端应用程序本身中的跟踪侦听器并写入文本框控件。

<system.diagnostics>
    <sources>
        <source name="System.ServiceModel" 
                switchValue="All">
            <listeners>
                <add name="xmlTraceListener" />
            </listeners>
        </source>
        <source name="System.ServiceModel.MessageLogging" 
                switchValue="All">
             <listeners>
                 <add name="xmlTraceListener" />
             </listeners>
        </source>
    </sources>
    <sharedListeners>
        <add name="xmlTraceListener" 
             type="System.Diagnostics.XmlWriterTraceListener" 
             initializeData="ClientLogBasic.svclog" />
    </sharedListeners>
    <trace autoflush="true" />
</system.diagnostics>

<!-- child of the <system.serviceModel> element -->
<diagnostics>
    <messageLogging maxMessagesToLog="10000"
                    logEntireMessage="true"
                    logMessagesAtServiceLevel="true"
                    logMalformedMessages="true"
                    logMessagesAtTransportLevel="true">
        <filters>
           <clear/>
        </filters>
    </messageLogging>
</diagnostics>

所以现在我的消息记录已经工作了,我创建了自己的可以写入文本框的跟踪侦听器:

public class MyTraceListender : System.Diagnostics.TraceListener
{
    private TextBox txt_m;
    public MyTraceListender(TextBox txt)
        : base()
    {
        txt_m = txt;
    }

    private delegate void delWrite(string sText);

    public override void Write(string message)
    {
        txt_m.Invoke(new delWrite(AsyncWrite), message);
    }

    public override void WriteLine(string message)
    {
        this.Write(message + System.Environment.NewLine);
    }

    private void AsyncWrite(string sMessage)
    {
        this.txt_m.AppendText(sMessage);
    }
}

现在我有了跟踪侦听器,我想尝试从我的 Windows 窗体客户端应用程序中使用它。

public partial class Form1 : Form
{
    private MyTraceListender listener_m;

    public Form1()
    {
        InitializeComponent();

        listener_m = new MyTraceListender(this.txtOutput);

        System.Diagnostics.Trace.Listeners.Add(listener_m);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
        string sValue = client.GetData(1234);
    }
}

在这一点上,我仍然没有看到记录到文本框控件。我认为侦听器与源无关,所以我尝试了以下方法:

public partial class Form1 : Form
{
    private MyTraceListender listener_m;

    public static System.Diagnostics.TraceSource source = new System.Diagnostics.TraceSource("System.ServiceModel.MessageLogging", System.Diagnostics.SourceLevels.All);

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
        string sValue = client.GetData(1234);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        listener_m = new MyTraceListender("test", this.txtOutput);
        source.Listeners.Add(listener_m);
    }
}

毕竟,消息不会被记录到表单上的文本框中。它们通过 XmlTraceListener 记录到文件中,所以我假设问题是我如何通过 System.Diagnostics.Trace.Listeners.Add() 添加自定义侦听器。这是正确的方法吗?

4

3 回答 3

5

使用 WCF 配置编辑器编辑配置文件,并启用跟踪,如下所示

在此处输入图像描述

于 2013-05-23T13:46:11.603 回答
2

这个解决方案主要是通过 app.config。如果您更喜欢基于代码的解决方案,请告诉我。

在 app.config 中,将您的侦听器添加到共享侦听器列表中,以及消息日志记录源的侦听器。在“listeners”列表中,名称必须与稍后在“sharedListeners”列表中的名称匹配。在“sharedListeners”列表中,“类型”必须包括完整的类名和命名空间,以及程序集名称:

<system.diagnostics>
<sources>
  <source name="System.ServiceModel" switchValue="All">
    <listeners>
      <add name="xmlTraceListener"/>
    </listeners>
  </source>
  <source name="System.ServiceModel.MessageLogging" switchValue="All">
    <listeners>
      <add name="xmlTraceListener"/>
      <add name="textBoxListener"/>
    </listeners>
  </source>
</sources>
<sharedListeners>
  <add name="xmlTraceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="ClientLogBasic.svclog"/>
  <add name="textBoxListener" type="WinTransmitterClient.MyTraceListener, WinTransmitterClient" initializeData=""/>
</sharedListeners>
<trace autoflush="true"/>

因为 MyTraceListener 将由框架构造,所以它的构造函数必须与基类匹配。因此,请将文本框设置为可以在需要时设置的属性。

在 MyTraceListener.cs 中:

public class MyTraceListener : System.Diagnostics.TraceListener
{
    public TextBox txt_m
    {
        get;set;
    }          

    public MyTraceListener()
        : base()
    {}

    // rest as before ...

在Form1.cs中,在客户端创建好后抓取自定义监听器,并设置文本框。不需要其他代码。这是整个 Form1.cs,不包括“使用”和“命名空间”行:

public partial class Form1 : Form
{
    public static System.Diagnostics.TraceSource source = new System.Diagnostics.TraceSource("System.ServiceModel.MessageLogging", System.Diagnostics.SourceLevels.All);

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ServiceReference1.ContactManagerTextServiceClient client = new ServiceReference1.ContactManagerTextServiceClient();

        // identifier in quotes must match name from config file
        MyTraceListener mtl = source.Listeners["textBoxListener"] as MyTraceListener;

        // of course this doesn't need to be done at every button click, but you get the idea
        mtl.txt_m = this.txtOutput;

        string sValue = client.GetData(1234);

    }
}
于 2013-05-28T18:54:43.140 回答
0

尝试创建一个消息检查器。在客户端,您必须实现IClientMessageInspector这将允许您在发送消息之前拦截消息以及在将其进一步传递到应用程序之前收到的响应。您可以在MSDN上找到更多信息

于 2013-05-22T09:51:36.433 回答