从客户端跟踪WCF调用

时间:2013-05-21 20:40:13

标签: wcf tracelistener

我已经构建了一个Windows窗体客户端应用程序来进行WCF调用。我希望能够在应用程序中显示实际的请求和响应,包括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()添加我的自定义侦听器的。这是正确的方法吗?

3 个答案:

答案 0 :(得分:5)

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

enter image description here

答案 1 :(得分:2)

此解决方案主要通过app.config。如果您更喜欢基于代码的解决方案,请与我们联系。

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

<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,不包括'using'和'namespace'行:

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);

    }
}

答案 2 :(得分:0)

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

找到更多信息