2013-05-21 52 views
1

我構建了一個使WCF調用的Windows窗體客戶端應用程序。我希望能夠在應用程序中顯示實際的請求和響應,包括SOAP頭和有關POST/Get的信息。有沒有一種方法可以在客戶端上配置跟蹤偵聽器,並在客戶端使用它,在文本框中顯示內容?跟蹤來自客戶端的WCF調用

我配置了將消息輸出到文件的跟蹤。此配置位於我的客戶端應用程序中,因此它將記錄正在對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()添加自定義偵聽器。這是正確的方法嗎?

+0

請不要只問我們爲你解決問題。告訴我們你是如何試圖自己解決問題的,然後向我們展示結果是什麼,並告訴我們爲什麼你覺得它不起作用。請參閱「[您嘗試過什麼?](http://whathaveyoutried.com/)」,以獲得一篇您最近需要閱讀的優秀文章。 –

+0

到目前爲止最簡單的方法是使用wireshark。添加捕獲過濾器來限制流量。 – matcheek

+1

WCF是廣泛使用System.Diagnostic跟蹤和具有專門用於檢查WCF跟蹤的跟蹤查看器的少數幾個庫之一。這是一個很好的開始:http://msdn.microsoft.com/en-us/library/ms733025.aspx – MatthewMartin

回答

2

這個解決方案大多通過的app.config。讓我知道你是否更喜歡基於代碼的解決方案。

在app.config中,將偵聽器添加到共享偵聽器的列表以及消息日誌記錄源的偵聽器。在「聽衆」列表中,名稱必須與'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); 

    } 
} 
+0

工程太棒了!我會對基於代碼的解決方案非常感興趣,但是現在我可以從中得到一個更多瞭解它的工作方式。 – Jeremy

0

嘗試創建一個消息檢查器。在客戶端,您必須實現IClientMessageInspector,這將允許您在發送消息之前攔截消息以及在將消息傳遞給應用程序之前接收到的響應。你會發現更多的信息,MSDN

5

編輯使用WCF配置編輯器配置文件,並啓用跟蹤如下圖所示

enter image description here