2013-05-21 2 views
1

Я создал клиентское приложение Windows Forms, которое делает вызов WCF. Я хотел бы иметь возможность отображать фактический запрос и ответ, включая заголовок 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 Forms.

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

Пожалуйста, не просто попросите нас решить проблему за вас. Покажите нам, как _you_ попытался решить проблему самостоятельно, а затем покажите нам _exactly_, каким был результат, и скажите, почему вы считаете, что это не сработало. См. «[Что вы пробовали?] (Http://whathaveyoutried.com/)» за отличную статью, которую вы действительно должны прочитать. –

+0

Простейшим способом является использование wirehark. Добавьте фильтр захвата, чтобы ограничить трафик. – matcheek

+1

WCF - одна из немногих библиотек, которая широко использует System.Diagnostic trace & имеет средство просмотра трассировки специально для изучения трассировки WCF. Вот хороший старт: http://msdn.microsoft.com/en-us/library/ms733025.aspx – MatthewMartin

ответ

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

    } 
} 
+0

Отлично работает! Меня действительно интересовало бы решение на основе кода, но я мог бы получить его сейчас, когда узнаю немного больше, как это работает. – Jeremy

0

Попробуйте создать инспектор сообщений. На стороне клиента вам придется реализовать IClientMessageInspector, который позволит вам перехватить сообщение до его отправки, а также ответ, полученный до передачи его в приложение. Вы найдете более подробную информацию о MSDN

5

Редактировать файл конфигурации с помощью редактора конфигурации WCF, а также включить трассировку, как показано ниже

enter image description here