連載:ASP.NET MVC入門【バージョン3対応】

第5回 新しいビュー・エンジン「Razor」の基本を理解しよう

山田 祥寛(http://www.wings.msn.to/
2011/07/25
Page1 Page2 Page3 Page4

■ブロックを伴うステートメント

 if、switch、while、for/foreachなどブロックを伴うステートメントでは、ステートメントの始まりからブロックの終わりまでが、コード・ブロックと見なされる。

 例えば、以下はモデル・オブジェクトのPriceプロパティが5000円以上である場合に、「高い!」という文字列を表示する例である。

@if (Model.Price >= 5000) {
  WriteLiteral("<b>高い!</b>");
}
@If Model.Price >= 5000 Then
  WriteLiteral("<b>高い!</b>")
End If
<% if (Model.Price >= 5000) {
  Response.Write("<b>高い!</b>");
} %>
<% If Model.Price >= 5000 Then
  Response.Write("<b>高い!</b>")
End If %>
リスト14 Priceプロパティが5000以上である場合にテキストを出力するコード
上からRazor(C#)、Razor(Visual Basic)、ASPX(C#)、ASPX(Visual Basic)。

 WriteLiteralメソッドは、Razorページに文字列をそのまま出力するためのメソッドだ。ASPXエンジンと異なり、Response.Writeメソッドではコンテンツの埋め込みはできない(=ページの先頭に出力されてしまう)ので注意されたい。

 もっとも、これはあまりRazor的なコードとはいえない。よりRazor的に記述するならば、以下のように書くのが望ましいだろう(参考までに、ASPXの方もよりスマートにした例を併記しておく)。

@if (Model.Price >= 5000) {
  <b>高い!</b>
}
@If Model.Price >= 5000 Then
    @<b>高い!</b>
End If
<% if (Model.Price >= 5000) { %>
  <b>高い!</b>
<% } %>
<% If Model.Price >= 5000 Then %>
  <b>高い!</b>
<% End If %>
リスト15 リスト14をよりスマートに書き直した例
上からRazor(C#)、Razor(Visual Basic)、ASPX(C#)、ASPX(Visual Basic)

 Razorでは、ブロック内部に、

<タグ名>〜</タグ名>(Visual Basicでは「@<タグ名>〜</タグ名>」)

を検出すると、これを自動的に静的コンテンツとして見なすわけだ。よって、コンテンツがタグで修飾されている場合、Razorでは、これを(WriteLiteralメソッドなどを利用することなく)生のコンテンツとして記述できるわけだ。

 それでは、以下のようなケースではどうだろう。

@if (Model.Price >= 5000) {
  高い!
}
リスト16 タグを伴わないコンテンツを出力する例(エラーとなる)

 この例では、配下のコンテンツがタグで修飾されていないため、Razorが自動的に静的コンテンツを識別できない(実際、上の例はコンパイル・エラーとなる)。では、このような例では、(例えば)ダミーの<span>タグでくくるか、やはりWriteLiteralメソッドを呼び出さなければならないのだろうか。

 否、そのようなことはない。Razorは、ブロック・ステートメントで静的コンテンツを識別するために、以下の方法を提供している。

(1)行頭に「@:」を付与する(単一行)

 「@:」は、現在行を静的コンテンツとして、Razorに通知するものだ。例えば、リスト16は以下のように書き換えられる。

@if (Model.Price >= 5000) {
  @:高い!
}
@If Model.Price >= 5000 Then
  @:高い!
End If
リスト17 静的コンテンツを「@:」でマークしたコード(上:C#、下:VB)

(2)<text>〜</text>を利用する(複数行)

 「@:」は、あくまで単一行の静的コンテンツを表すものであるので、複数行にわたるコンテンツを表すには適さない。

@if(Model.Price >= 5000) {
  @:高い!
  @:高い!
  @:高い!
}
@If Model.Price >= 5000 Then
  @:高い!
  @:高い!
  @:高い!
End If
リスト18 複数行の静的コンテンツを「@:」でマークした例(上:C#、下:VB)

 このようなケースでは、複数行コンテンツ対応の、

<text>〜</text>(Visual Basicでは@<text>〜</text>)

を利用するのがより望ましいだろう。<text>〜</text>は、Razorで予約されたタグで配下の文字列を静的コンテンツとして表すものだ(あくまで静的コンテンツの通知が目的であるので、<text>タグそのものは描画されない)。

 例えば以下は、リスト18を<text>タグで書き換えたものだ。

@if (Model.Price >= 5000) {
  <text>
  高い!
  高い!
  高い!
  </text>
}
@If Model.Price >= 5000 Then
  @<text>
  高い!
  高い!
  高い!
  </text>
End If
リスト19 複数行の静的コンテンツを<text>タグでマークした例(上:C#、下:VB)

 ブロック・ステートメント、「@:」、<text>タグは、それぞれ入れ子に組み合わせることもできる。以下に、より複雑なコードも確認しておこう。このように、Razorでは複雑な制御ブロックも「@:」や<text>タグを活用することで、ごく自然に(しかもシンプルなコードで)表現できるわけだ。

<ol>
@foreach (var item in Model) {
  <li>
  @item.Title(@item.Publish → 静的コンテンツのインライン式
  @item.Published.ToShortDateString()
  @if (item.Published > DateTime.Now) { → 入れ子となったブロック・ステートメント
    @: 刊行予定 → 入れ子ブロックの中の静的コンテンツ
  } else {
    <text>絶賛発売中</text> → 入れ子ブロックの中の静的コンテンツ
  }
  )
  </li>
}
</ol>
<ol>
@For Each item In Model
  @<li>
  @item.Title(@item.Publish → 静的コンテンツのインライン式
  @item.Published.ToShortDateString()
  @If item.Published > DateTime.Now Then → 入れ子となったブロック・ステートメント
    @: 刊行予定 → 入れ子ブロックの中の静的コンテンツ
  Else
    @<text>絶賛発売中</text> → 入れ子ブロックの中の静的コンテンツ
  End If
  )
  </li>
Next
</ol>
リスト20 ブロック・ステートメントを入れ子にした例(上:C#、下:VB)

■サーバサイド・コメント

 Razorでサーバサイド・コメントを表すには、「@* comment *@」のように記述すればよい。ASPXエンジンの「<%-- comment --%>」に相当する構文だ。サーバサイド・コメントは、ビュー・エンジンの解析対象外となるので、クライアントには送信されない。

@* サーバサイド・コメントです *@
<%-- サーバサイド・コメントです --%>
リスト21 サーバサイド・コメント(上:Razor、下:ASPX)

 そのほか、コード・ブロックの中では、それぞれ「//」「/* 〜 */」(C#の場合)、「'」(Visual Basicの場合)のような言語標準のコメント構文も利用できるし(コード・ブロックでは任意のコードを記述できるので、当然といえば当然だ)、静的コンテンツの一部としてHTML標準の「<!-- 〜 -->」構文も利用できる。


 INDEX
  ASP.NET MVC入門【バージョン3対応】
  第5回 新しいビュー・エンジン「Razor」の基本を理解しよう
    1.ASPXとの比較で理解するRazor文法(1)
  2.ASPXとの比較で理解するRazor文法(2)
    3.ビュー開発を効率化する「ビュー・ヘルパー」(1)
    4.ビュー開発を効率化する「ビュー・ヘルパー」(2)
 
インデックス・ページヘ  「ASP.NET MVC入門【バージョン3対応】」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間