1

WCF 呼び出しを行う Windows フォーム クライアント アプリケーションを作成しました。SOAP ヘッダーを含む実際の要求と応答、および POST/Get に関する情報をアプリケーション内から表示できるようにしたいと考えています。クライアントでトレース リスナーを構成し、それをクライアント内から使用して、内容をテキスト ボックスに表示する方法はありますか?

メッセージをファイルに出力するトレースを構成しました。この構成はクライアント アプリケーション上にあるため、wcf サービスに対して行っているすべての呼び出しと応答をログに記録しています。したがって、ソースが追加され、各ソースには、xml ログ ファイルへの書き込みを処理する XmlTraceListener があります。私が今しようとしているのは、クライアント アプリケーション自体からトレース リスナーを利用し、テキスト ボックス コントロールに書き込むことです。

<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

2

このソリューションは、主に app.config を介して行われます。コードベースのソリューションをご希望の場合はお知らせください。

app.config で、リスナーを共有リスナーのリストに追加し、メッセージ ログ ソースのリスナーも追加します。「listeners」リストでは、名前は後で「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 で、クライアントの作成後にカスタム リスナーを取得し、テキスト ボックスを設定します。他のコードは必要ありません。これは、「using」行と「namespace」行を除いた 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 に答える