Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
書籍転載:ASP.NET MVC 5 実践プログラミング

書籍転載:ASP.NET MVC 5 実践プログラミング

Razor構文

2014年10月1日

ASP.NET MVCのビュー開発では「Razor」ビューエンジンを利用するのが基本。そのRazorの基本的な文法を解説。書籍転載の3本目(導入編「4-1」)。

  • このエントリーをはてなブックマークに追加

書籍転載について

 本コーナーは、秀和システム発行の書籍『ASP.NET MVC 5 実践プログラミング』の中から、特にBuild Insiderの読者に有用だと考えられる項目を編集部が選び、同社の許可を得て転載したものです。

 

 『ASP.NET MVC 5 実践プログラミング』の詳細や購入は秀和システムのサイト目次ページをご覧ください。

ご注意

 本記事は、書籍の内容を改変することなく、そのまま転載したものです。このため用字用語の統一ルールなどはBuild Insiderのそれとは一致しません。あらかじめご了承ください。

4-1 Razor構文

 2-3節(転載対象外)でも触れたように、ASP.NET MVCのビュー開発ではRazorを利用するのが、まず基本です。実際に利用すれば判るように、Razorはとても「賢い」ビューエンジンです。開発者の手をできるだけ煩わせないように、いたるところに配慮が行き届いていますから、正しい文法を理解しなくとも、なんとなく――直感的に書きたいことを表現できてしまうのが、Razorの良いところです。

 もっとも、だからと言って、正しい文法を理解しなくて良いわけではありません。思わぬ落とし穴に陥らないためにも、Razorの基本的な解析ルールを知っておくことは、決して無駄なことではありません。

 そこで本章では、まずRazorの基本的な文法について学んでいきます。導入編では漠然と触れてきたRazorの曖昧な部分を再確認し、理解を深めましょう。

4-1-1 コードナゲット(インライン式)

 「@...」はRazorの最も基本的な記法で、式の値をHTMLコードに埋め込みます。コードナゲット、もしくはインライン式と呼ばれます。

Razor
<p>@Model.Title</p>

 ASPXエンジンの<%:...%>に相当する構文ですが、決定的に異なる点は終了のデリミター*1がないという点です。Razorでは、C#/VisualBasicの識別子、もしくは「[」(インデクサーの開始)、「.」(ドット演算子)などを正しく認識します。そして、式の一部となりえない文字を検出したところで、自動的にコードの終了と見なすのです。上の例であれば「@Model.Title」までが式で、「</p>」で式を抜けたと判断します。

  • *1 プログラムコードとHTMLとの区切りを表す文字です。

 その性質上、たとえば以下のような式は、Razorでは正しく認識できません。

Razor
@Model.Viewcount / 1000

 Viewcountプロパティを1000で割った結果を求めることを期待したコードですが、結果は「36452 / 1000」(Viewcountプロパティが36452の場合)。@Model.Viewcountの直後の空白が識別子として有効な文字ではないため、Razorはここでコードが終了したと見なすのです。結果、「/ 1000」は単なる文字列と見なされ、解析されません。

 これを避けるには、「@(...)」のように式全体を丸カッコで括ります。

Razor
@(Model.Viewcount / 1000)

 丸カッコによって式の範囲が明確になりますので、今度は期待した結果(たとえば36のような演算結果)が得られます。@(...)を、式の範囲を明示することから、明示的コードナゲットと言います*2

  • *2 対義語として、「@...」ことを暗黙的のコードナゲットとも呼びます。

 明示的コードナゲットは、曖昧なコードの区切りを明確にするためにも利用できます。たとえば、以下のようなケースです。

Razor
<a href="@Model.Key_index.html">記事目次へ</a>

 上のコードは、本来は「<Keyプロパティ>_index.html」であることを期待したコードです。しかし、「_」がC#/Visual Basicの識別子として有効であるので、Razorは「@Model.Key_index」と見なします。結果、Key_indexプロパティが存在しないため、Razorは例外を発生するのです*3

  • *3 たまたまKey_indexプロパティが存在しても、意図しない値を出力するだけです。

 このような場合にも、明示的コードナゲットを利用することで、コードの終了をRazorに通知できます。

Razor
<a href="@(Model.Key)_index.html">記事目次へ</a>

4-1-2 予約文字「@」のエスケープ

 Razorは、実際、賢いビューエンジンで、予約文字である「@」ですらも、ほとんどの場合にはそのまま(=エスケープなど意識せずに)静的コンテンツとして表せます。たとえば以下のような文字列は、正しいRazorのコードです。

Razor
<p>admin@examples.com</p>

 「@」の前後を見て、それが(コードナゲットではなく)静的コンテンツの一部であると判断するのです。よって、「@examples」あるいは「@examples.com」という式として処理させたい場合には、明示的コードナゲットとして「@(examples)」「@(examples.com)」のように表します。

 ただし、そのような自動識別も万能ではありません。「@」が行頭、単語の区切りなどに位置する場合、Razorは「@」をコードナゲットの開始と見なすのです。

Razor
@Niftyはインターネットプロバイダーです。

 結果、「名前 'Nifty はインターネットプロバイダーです' は現在のコンテキスト内に存在しません」のようなエラーが発生します。このような場合は、以下のように「@」をエスケープしてください。「@」をエスケープするには、「@@」のように表します。

Razor
@@Niftyはインターネットプロバイダーです。

【Note】「@」を識別する方法

 Razorで「@」をエスケープするべきかどうか、時として、悩む場合があるかもしれません。ですが、細かなルールをあえて理解する必要はありません。というのも、Visual Studio(コードエディター)は、予約文字としての「@」を黄色くハイライトします。これによって、視覚的に「@」の状態を識別できます。

図4-1 コードナゲットとして認識された「@」はハイライト表示

図4-1 コードナゲットとして認識された「@」はハイライト表示

4-1-3 コードブロック

 式の値を出力することを目的とした「@...」に対して、(一般的に)出力を伴わない任意の文(Statement)「@{...}」はで表現できます。ASPXエンジンでは「<%...%>」で表せる表現です。

Razor
@{
  ViewBag.Title = "About";
}

 コードブロックが表すのは文ですから、文末は(セミコロン)「;」で終わらなければならない点に注意してください。

 また余談ですが、Visual Basicでコードブロックを表す場合には、「@{...}」の代わりに「@Code...End Code」を利用します。本書ではC#を対象としていますので、Visual Basicの場合の細かな構文には踏み込みませんが、Razorではその他にも、Visual BasicとC#とで構文(キーワード)が異なるものがあります。詳しくは、以下の記事なども参考にしてください。

4-1-4 制御構文(コードブロック)

 if、switch、while、for/foreachなどブロックを伴う制御構文では、文の開始からブロックの終了までが、暗黙的にコードブロックと見なされます。たとえば以下は、Viewcountプロパティが10000以上の場合に[人気]アイコンを表示する例です。

Razor
@if (Model.Viewcount >= 10000) {
  WriteLiteral("<strong> 人気! </strong>");
}

 WriteLiteralは、Razorページで文字列を出力するためのメソッドです*4。ただし、このようなコードはあまりRazor的ではありません。よりRazor的には、以下のように表すのが自然です。

Razor
@if (Model.Viewcount >= 10000) {
  <strong> 人気! </strong>
}
  • *4 ASPXエンジンであれば、Response.Writeメソッドに相当します。RazorでもResponse.Writeメソッドは利用できますが、任意の位置への出力はできない=(ページの先頭で出力される)ため、現実的には利用できないと覚えておきましょう。

 コードブロックでは<tag>~</tag>を検出すると、これを自動的に静的コンテンツと見なすのです。よって、WriteLiteralメソッドは必要ありません。

 では、<tag>~</tag>で修飾されない、以下のようなケースではどうでしょう。

Razor
@if (Model.Viewcount >= 10000) {
  人気!
}

 この場合、「人気!」という文字列を静的コンテンツと見なせませんので、文法エラーとなります。このような文字列をブロック配下で出力するには、以下の方法があります。

(1)「@:」を付与する(単一行コンテンツ)

 行頭に「@:」を付与することで、現在の行を静的コンテンツとしてRazorに通知します。

Razor
@if (Model.Viewcount >= 10000) {
  @: 人気!
}
(2)<text>~</text>要素で括る(複数行コンテンツ)

 静的コンテンツが複数行に及ぶ場合、すべての行に「@:」を付与するのは冗長です。その場合は、全体を<text>~</text>要素で括ることで、該当する範囲をすべて静的コンテンツであると見なします。

 <text>は、配下の文字列が静的コンテンツであることを表すためのダミーの要素ですので、それ自体は出力されません。

Razor
@if (Model.Viewcount >= 10000) {
  <text>
  人気!
  人気!
  人気!
  </text>
}

 制御構文によるコードブロック(ステートメントブロック)は、互いに入れ子にすることもできます。Razorでは、ステートメントブロックと「@:」、<text>要素を組み合わせることで、複雑な制御ブロックもごく自然に表現できるのです。

Razor
 1
3
2
 
1
 
 
 
 
 
11
12
<ul>
@foreach (var item in Model) {
  <a href="@item.Url">
  【 @item.Published.ToShortDateString()
     @if (item.Published < DateTime.Now) {
       @: 公開
     } else {
       <text> 公開予定 </text>
     }
  】@item.Title</a>
}
</ul>
  • 1内側の@ifブロック
  • 2アンカータグを出力
  • 3外側の@foreachブロック

【Note】コードブロックでの出力

 ステートメントブロックでの出力ルールは、標準のコードブロック(@{...})でも同様です。よって、以下は(あえてコードブロックで括る意味はありませんが)正しいRazorのコードです。

Razor
@{
  <p> こんにちは! </p>
  @: こんにちは!
  <text> こんにちは! </text>
}

 Razorでは、以下のコメントを利用できます。

(1)@*...*@

 Razor標準のコメントで、@*...*@配下のコンテンツをすべてコメントと見なします。配下に「@...」「@{...}」を含めることもできますので、特定のブロックを無効にしたい場合にも利用できます。

Razor
@*
@{
  ViewBag.Title = " コメント ";
}
<h3>@ViewBag.Message</h3>
*@

 @*...*@は、コードブロックの配下でも利用できます。

Razor
@{
  @* これはコメントです。 *@
}
(2)//、/* ~ */

 C#標準のコメント構文で、@{...}の配下でのみ利用できます。「//」が単一行コメント、「/*...*/」は複数行コメントです。

Razor
@{
  // これはコメントです。
  /*
  複数行コメントはこちら
  */
}
(3)<!--...-->

 標準的なHTMLのコメントです。RazorはあくまでHTML埋め込み型の構文を採用していますので、当然、HTMLのコメントも利用できます。ただし、(1)(2)とは異なり、ブラウザー側で処理されるコメントなので、[ソースの表示]でエンドユーザーからも見えてしまう点に注意してください。

Razor
<!--これはコメントです。-->

※以下では、本稿の前後を合わせて5回分(第1回~第5回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

書籍転載:ASP.NET MVC 5 実践プログラミング
1. ASP.NETの全体像

ASP.NET上で動作するWebアプリケーションフレームワーク「ASP.NET MVC」とは? その全体像と6つの構成要素について紹介する。書籍転載の1本目(導入編「1-1」)。

書籍転載:ASP.NET MVC 5 実践プログラミング
2. ASP.NET MVCとは?

なぜASP.NET MVCを使うとよいのか? Webフォームの問題点を示し、ASP.NET MVCの特徴とメリットを紹介する。書籍転載の2本目(導入編「1-2」)。

書籍転載:ASP.NET MVC 5 実践プログラミング
3. 【現在、表示中】≫ Razor構文

ASP.NET MVCのビュー開発では「Razor」ビューエンジンを利用するのが基本。そのRazorの基本的な文法を解説。書籍転載の3本目(導入編「4-1」)。

書籍転載:ASP.NET MVC 5 実践プログラミング
4. フォームを生成する - BeginFormメソッド[Razor]

<form>要素を生成するには、標準のビューヘルパーとして提供されているBeginFormメソッドが便利だ。その使い方を解説。書籍転載の4本目(基礎編「4-2-1」)。

書籍転載:ASP.NET MVC 5 実践プログラミング
5. ルート定義からフォームを生成する - BeginRouteFormメソッド[Razor]

ポスト先のルートパラメーターを指定した<form>要素を生成できるBeginRouteFormメソッドの使い方を解説。書籍転載の5本目(基礎編「4-2-2」)。

サイトからのお知らせ

Twitterでつぶやこう!