ブラウザからトレースビューア Trace.axd を要求したとき表示される[トレース情報]に、System.Diagnostics.Trace クラス(Page.Trace プロパティで取得できる TraceContext オブジェクトではない点に注意)を利用して書き込んだトレースメッセージを表示する方法を書きます。
この記事の例では、一つのソリューションの中に二つのプロジェクトがあって、一方が ASP.NET MVC4 の Web アプリケーション、他方がデータベースなどからデータなどを取得する中間ビジネス層のクラスライブラリを考えます。また、View に Razor 構文を使用することとします。
ASP.NET Web Forms アプリケーションの例は MSDN ライブラリの チュートリアル : ASP.NET トレースと System.Diagnostics トレースの統合 に詳しく書いてあります。(現時点の記事には、「Web フォームのトレース メッセージを書き込むには」のセクションのコード Trace.WriteLine が Trace.Write の間違い、WebPageTraceListener とコンパイラのバージョンが古いなどの問題があるので注意してください)
これと同様なことを MVC4 Razor 構文のアプリケーションで行ってみます。ちなみに、この記事の検証に使った環境は、Vista SP2, ASP.NET 4, VS2010 Professional, MVC4 インターネットアプリケーションテンプレートで作成、IIS7 統合パイプラインモード上で実行、ブラウザは IE9 です。
(1) クラスライブラリ(Model 相当)
チュートリアルにある AuthorClass ビジネスオブジェクトに相当するクラスライブラリは、以下のコードのとおり実装しました。
MVC アプリケーションの Model として利用しやすいように、Author クラスを定義し、List<Author> 型のオブジェクトを作成して渡すようにしています。チュートリアルとは違って、Authors.xml ファイルは使用していません。
トレースメッセージは、チュートリアルと同様に、AuthorClass オブジェクトの生成時点と AuthorClass.GetAuthors メソッドの呼び出し時点で Trace.Write メソッドを使って書き込みます。
加えて、非同期で呼び出したメソッドでトレースメッセージを書き込んだ場合にはどうなるかを検証するため、AsynchronousMethod を追加し、非同期で呼び出してみました。(結果は、上の画像の通りトレースビューアには表示されません)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AuthorClassLibrary
{
public class Author
{
public string au_id { get; set; }
public string au_lname { get; set; }
public string au_fname { get; set; }
public string au_phone { get; set; }
}
public delegate Author WriteTraceMessage();
public class AuthorClass
{
public AuthorClass()
{
// トレースメッセージ書込み
System.Diagnostics.Trace.Write(
"AuthorClass is created.", "AUTHORCLASS TRACE");
}
public List<Author> GetAuthors()
{
// トレースメッセージ書込み
System.Diagnostics.Trace.Write(
"GetAuthors called.", "AUTHORCLASS TRACE");
List<Author> authors = new List<Author>() {
new Author { au_id = "172-32-1176", au_lname = "White",
au_fname = "Gerry", au_phone = "408 496-7223" },
new Author { au_id = "172-32-1176", au_lname = "Green",
au_fname = "Marjorie", au_phone = "415 986-7020" }
};
// AsynchronousMethod を非同期呼び出し
WriteTraceMessage asyncCall =
new WriteTraceMessage(AsynchronousMethod);
IAsyncResult ar = asyncCall.BeginInvoke(null, null);
Author author = asyncCall.EndInvoke(ar);
authors.Add(author);
return authors;
}
// 非同期で呼び出すメソッド
static Author AsynchronousMethod()
{
// トレースメッセージ書込み(Trace.axd では表示されない)
System.Diagnostics.Trace.Write(
"AsynchronousMethod called.", "AUTHORCLASS TRACE");
Author author = new Author() {
au_id = "123-45-6789", au_lname = "太郎",
au_fname = "日本", au_phone = "000 111-2222" };
return author;
}
}
}
(2) Controller
MVC4 インターネットアプリケーションテンプレートで自動生成される HomeController に、以下のように Authors アクションメソッドを追加します。
ブラウザから Home/Authors が呼び出されたときに Trace.Write メソッドを使ってトレースメッセージを書き込むようにしています。
また、このメソッドの中で、上のクラスライブラリの AuthorClass コンストラクタと AuthorClass.GetAuthors メソッドが呼び出され、トレースメッセージが書き込まれることに注意してください。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Mvc4App.Controllers
{
public class HomeController : Controller
{
// ・・・中略・・・
public ActionResult Authors()
{
System.Diagnostics.Trace.Write(
"Home/Authors method called.", "CONTROLLER TRACE");
ViewBag.Message = "System.Diagnostics Trace の統合。";
AuthorClassLibrary.AuthorClass authors =
new AuthorClassLibrary.AuthorClass();
return View(authors.GetAuthors());
}
}
}
(3) View
View においても、以下のコードのように、Trace.Write メソッドを使ってトレースメッセージを書き込むことができます。
@model IEnumerable<AuthorClassLibrary.Author>
@{
ViewBag.Title = "ASP.NET MVC Trace";
Layout = "~/Views/Shared/_Layout.cshtml";
System.Diagnostics.Trace.Write(
"Home/Authors.cshtml called.", "VIEW TRACE");
}
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>@ViewBag.Message</h2>
</hgroup>
<table>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.au_id)
</td>
<td>
@Html.DisplayFor(modelItem => item.au_lname)
</td>
<td>
@Html.DisplayFor(modelItem => item.au_fname)
</td>
<td>
@Html.DisplayFor(modelItem => item.au_phone)
</td>
</tr>
}
</table>
Trace.Write メソッドで書き込んだトレースメッセージが出力されるようにするには、Visual Studio で当該プロジェクトの Property を開き、その[ビルド]タブの[TRACE 定数の定義(T)]にチェックマークを入れる必要があります。
View については更なる設定が web.config に必要です(上の画像の[トレース定数の定義]の設定だけでは View の Trace.Write メソッドは無視されます)。
具体的には、C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config の中の complier 要素を、アプリケーションルート直下の web.config にコピーして、それに compilerOptions="/define:TRACE" を追加します。
詳しくは、MSDN ブログの記事 Tracing in ASP.NET MVC Razor Views を見てください。チュートリアルの「トレースを有効にしてアプリケーションを自動コンパイルするには」のセクションにも同様なことが書かれていますが、こちらはバージョンが古いので注意してください。
今回の検証で使った環境では以下のようになります。
<system.codedom>
<compilers>
<compiler
language="c#;cs;csharp"
extension=".cs"
warningLevel="4"
compilerOptions="/define:TRACE"
type="Microsoft.CSharp.CSharpCodeProvider,
System,
Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=b77a5c561934e089">
<providerOption
name="CompilerVersion"
value="v4.0"/>
<providerOption
name="WarnAsError"
value="false"/>
</compiler>
</compilers>
</system.codedom>
さらに、System.Diagnostics.Trace クラスを使用して書き込んだトレースメッセージをルーティングして、ASP.NET トレース ビューア(Trace.axd)に表示されるようにするには、web.config で trace 要素を有効にし、WebPageTraceListener を追加する必要があります。
WebPageTraceListener の設定はチュートリアルの「構成でアプリケーションの WebPageTraceListener を追加するには」のセクションに書かれていますが、バージョンが古いようです。
WebPageTraceListener は System.Web.dll に含まれていますので、参照設定を見てそれと同じバージョンにするのがよさそうです。具体的には、今回の検証で使った環境では、以下の通りです。
<system.web>
<trace enabled="true" pageOutput="true"
requestLimit="40" localOnly="false"/>
</system.web>
<system.diagnostics>
<trace>
<listeners>
<add
name="WebPageTraceListener"
type="System.Web.WebPageTraceListener,
System.Web,
Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"/>
</listeners>
</trace>
</system.diagnostics>
上記の通り設定してブラウザから Home/Authors を呼び出すと以下のように表示されるはずです。
その後、ブラウザからトレースビューア Trace.axd を呼び出し、ブラウザに表示された Home/Authors 行の[詳細の表示]をクリックして[トレース情報]を見ると一番上の画像のようになっているはずです。
非同期呼び出しした AsynchronousMethod メソッドで書き込んだトレースメッセージ以外はトレースビューアに表示されているのがわかるでしょうか?