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

第1回 Controller−View開発のキモを押さえる

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

■ビューを作成する

 次に、アクションに対応するビュー・スクリプトを作成しよう。Model−View−Controllerの「View」に当たる部分である。

 新規にビュー・スクリプトを生成するには、コード・エディタでアクション・メソッドにカーソルを合わせた状態でマウスを右クリックし、コンテキスト・メニューから[ビューの追加]を選択すればよい。


図11 [ビューの追加]ダイアログ

 図11のような[ビューの追加]ダイアログが表示されるので、ここでは、

  • [ビュー名]欄が「Index」(アクションと同名)になっていること
  • [ビュー エンジン]欄が「Razor」になっていること、
  • [レイアウトまたはマスター ページを使用する]にチェックが入っていること

を確認したうえで、[追加]ボタンをクリックする。ほかのオプションについては、あらためて必要になったところで解説していくので、ここでは取りあえず未チェックのままとしておこう。

 ソリューション・エクスプローラを確認すると、/Viewsフォルダの配下に「Hello/Index.cshtml」が生成されているはずだ。このように、ASP.NET MVC+Razorではビュー・スクリプトを/Viewsフォルダ配下に、

コントローラ名/アクション名.cshtml

のように配置する必要がある*6


図12 アクションに対応するビュー・スクリプトが生成された

*6 C#の場合。Visual Basicでは拡張子は「.vbhtml」となる。

 自動生成されたコードがコード・エディタで開くので、ここではリスト2のようにコードを追加してみよう。追加するコードは太字で表している。

@{
  ViewBag.Title = "Index";
}

<h2>Index</h2>
@ViewBag.Message
@Code
  ViewBag.Title = "Index"*7
End Code

<h2>Index</h2>
@ViewBag.Message
リスト2 Hello/Indexアクションに対応するビュー(上がIndex.cshtml、下がIndex.vbhtml)

*7 Visual Basicでは、デフォルトで「ViewData("Title") = "Index"」というコードが生成される。意味的にはいずれでも問題ないが、本稿ではC#に合わせてViewBagオブジェクトによるコードに書き換えている。

 シンプルなコードではあるが、ポイントは盛りだくさんである。

(1)Razor文法は「@」で表現できる

 従来、ASPXビュー・エンジンではコード埋め込みのために、

<%: …… %>

のようなブロックを記述する必要があった。しかし、Razorでは、

@……

とわずかに1文字と、単純に文字数だけを比べても1/5のタイプ量で記述できるようになった(コードの末尾を示すデリミタは必要ない)。

 例えば、以下のコードは同じ意味である。

<%: ViewBag.Message %>
ASPX構文で記述

@ViewBag.Message
Razor構文で記述

 たかだか4文字の差と思われるかもしれないが、実際にRazorでコードを記述してみると、<%:……%>という枷(かせ)からの解放感を強く感じられるはずだ。

 なお、Razorでも複数行に及んだコードを記述する場合には、@{……}のように波カッコでコード・ブロック全体をくくる必要がある(Visual Basicでは@Code……End Code)。

 そのほか、Razorにかかわる構文の詳細は、「“Razor”の紹介 − ASP.NET向け新ビュー・エンジン」、「Scott Guthrie氏 Blog翻訳(CodeZine)」などを併せて参照することをお勧めする。

[Note]RazorはデフォルトでHTMLエスケープする

 Razor構文の「@……」はASPX構文の「<%:……%>」に相当する。つまり、指定された式の値はエスケープ処理された上で出力される。もしもRazorでエスケープ処理をしないで出力を行いたいなら、以下のようにRawメソッドで式を修飾する必要がある。

@Html.Raw(ViewBag.Message)
エスケープ処理をしないで出力するRawメソッド(Razor)

 ただし、エスケープ処理を無効にするのは、文字列がエスケープ済みである、または「安全な」HTMLであることが分かっている場合に限るべきだ。すでにさまざまな記事でも注意を喚起されている点であるが、いま一度、「エスケープ処理の漏れはクロスサイト・スクリプティング脆弱性の原因に直結する」ことに注意いただきたい。

(2)レイアウトを適用する

 自動生成されたビュー・スクリプトを眺めてみると、コンテンツの本体(<body>タグの内容)しか記述されていないのが見て取れる。では、ページの外枠(<html>、<head>タグ)はどこで書かれているのか。

 ずばり、「Views/Shared/_Layout.cshtml」(Visual Basicでは_Layout.vbhtml)で定義されている。これは「レイアウト」と呼ばれるRazorの機能で、Webフォームにおけるマスター・ページに相当するものであると考えればよい。

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>@ViewBag.Title</title>
  <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
  <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
</head>

<body>
  <div class="page">

    <div id="header">
      <div id="title">
        <h1>マイ MVC アプリケーション</h1>
      </div>

      <div id="logindisplay">
        @Html.Partial("_LogOnPartial")
      </div>

      <div id="menucontainer">

        <ul id="menu">
          <li>@Html.ActionLink("ホーム", "Index", "Home")</li>
          <li>@Html.ActionLink("バージョン情報", "About", "Home")</li>
        </ul>

      </div>
    </div>

    <div id="main">
      @RenderBody()
      <div id="footer">
      </div>
    </div>
  </div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>@ViewData("Title")</title>
  <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
  <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
</head>

<body>
  <div class="page">

    <div id="header">
      <div id="title">
        <h1>マイ MVC アプリケーション</h1>
      </div>

      <div id="logindisplay">
        @Html.Partial("_LogOnPartial")
      </div>

      <div id="menucontainer">

        <ul id="menu">
          <li>@Html.ActionLink("ホーム", "Index", "Home")</li>
          <li>@Html.ActionLink("バージョン情報", "About", "Home")</li>
        </ul>

      </div>
    </div>

    <div id="main">
      @RenderBody()
      <div id="footer">
      </div>
    </div>
  </div>
</body>
</html>
リスト3 デフォルトで用意されているレイアウト・テンプレート(上:_Layout.cshtml、下:_Layout.vbhtml)

 個別のビュー・スクリプトで記述された内容は、実行時に、「@RenderBody()」と記述された部分に埋め込まれるわけだ。なお、適用すべきレイアウト・ファイルを決めているのは、Views/_ViewStart.cshtml、_ViewStart.vbhtmlというファイルである(名前は固定)。

@{
  Layout = "~/Views/Shared/_Layout.cshtml";
}
@Code
  Layout = "~/Views/Shared/_Layout.vbhtml"
End Code
リスト4 ビューの初期化を行うためのファイル(上:_ViewStart.cshtml、下:_ViewStart.vbhtml)

 Razorでは、ビューの処理に当たって、まず_ViewStart.htmlを呼び出し、その内容を処理する。ここではLayoutプロパティにレイアウト・ファイルを指定しているだけであるが、そのほか、ビューで行うべき初期化処理があるのであれば、ここに記述することができるだろう*8

*8 もちろん、レイアウト・ファイルを個別のビュー・スクリプトで記述しても構わない。しかし、ほとんどのページで同一のレイアウトを適用することを考えれば、まずは_ViewStart.cshtml、_ViewStart.vbhtmlの利用を優先すべきだろう。

(3)レイアウトに動的にタイトルを引き渡す

 レイアウトに動的にタイトルをセットしているのは、Index.cshtml/Index.vbhtmlの以下の部分である。

ViewBag.Title = "Index";

 そして、この値はレイアウトの以下のコードで参照している。

<title>@ViewBag.Title</title>

 ビュー・テンプレート、レイアウト・テンプレートの中であっても、ビュー変数を受け渡しする方法は、ここまで述べてきた要領で行えることが確認できるだろう。

(4)ビュー・ヘルパーを利用する

 ビュー・ヘルパーとは、ビュー・スクリプトを記述する際に役立つメソッドのこと。ビュー・ヘルパーを利用することで、リンクやフォーム要素の生成、部分ビューの呼び出しなどをごくシンプルなコードで表現できる。

 例えば、レイアウトに埋め込まれているヘルパーの意味を表にまとめておく。

メソッド 概要
Url.Content 指定されたパスから絶対パスを生成*9
Html.Partial 指定されたテンプレートを呼び出し&埋め込み
Html.ActionLink ハイパーリンクを生成
表3 レイアウト・テンプレートで利用されているビュー・ヘルパー

*9 リスト3では、参照しているjQueryのバージョンは1.4.4のままとなっているが、もちろん、1.5.1に変更しておくのが望ましい。

 ビュー・ヘルパーにはそのほかにもさまざまな種類があるので、本連載でも登場都度、説明していくこととしたい。

■サンプルの実行

 以上の手順を終えたらサンプルを実行してみよう。デバッグ実行でブラウザを起動し、以下のようなアドレスを入力してほしい(ポート番号は環境によって異なる)。

http://localhost:10720/Hello/Index

 このようにHelloコントローラのIndexアクションを呼び出すには、「/Hello/Index」のようなアドレスとなるわけだ。ちなみに、デフォルトの設定ではIndexアクションの指定は省略可能なので、この場合には、

http://localhost:10720/Hello/

としても構わない。

 結果、冒頭の図3のような画面が表示されることを確認してほしい。

 このようなURLとアクションとを結びつける仕組み(=ルーティング)は、ASP.NET MVCのもう1つのキモといえる部分であり、エンド・ユーザーに対してより分かりやすい(アクセスしやすい)URLを設計するには重要な知識となる。しかし、当面はあまり気にせず、デフォルトの設定で持って学習を進めることにする。

まとめ

 以上、今回はASP.NET MVCの中でもVC(View−Controller)の部分を解説した。冒頭述べたように、ASP.NET MVCは、MVCとはいっても、その機能の大部分はController、Viewに集約される。特にModelとViewの結節点となるControllerを理解することは、ASP.NET MVCそのものを理解することであるといってもよいだろう。

 Webフォームのイベントドリブン・モデルにどっぷりと浸かってしまった諸氏にとっては少々とっつき難くも感じたかもしれないが、まずは本稿の内容をきちんと理解しておけば、これ以降の学習もスムーズに進められるはずだ。

 次回は、いよいよ残るModel開発を中心に、データベース連携のアプリケーションを開発する。End of Article

 

 INDEX
  ASP.NET MVC入門【バージョン3対応】
  第1回 Controller−View開発のキモを押さえる
    1.ASP.NET MVC 3を利用するための準備/Hello, Worldアプリを作成
    2.コントローラ・クラスを作成する
  3.ビューを作成する/サンプルの実行/まとめ
 
インデックス・ページヘ  「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 記事ランキング

本日 月間