ビューの追加 - ビュー テンプレート ファイルを使用して、生成する HTML 応答をクライアントにクリーンにカプセル化する方法
投稿者: Scott Hanselman
これは、ASP.NET MVC の基本について説明する初心者向けチュートリアルです。 データベースから読み書きする単純な Web アプリを作成します。 他の ASP.NET MVC のチュートリアルとサンプルについては、ASP.NET MVC ラーニング センターにアクセスしてください。
このセクションでは、HelloWorldController クラスでビュー テンプレート ファイルを使用して、生成する HTML 応答をクライアントにクリーンにカプセル化する方法について説明します。
まず、Index メソッドでビュー テンプレートを使用してみましょう。 このメソッドは Index と呼ばれ、HelloWorldController にあります。 現在、Index() メソッドは、コントローラー クラス内でハードコーディングされたメッセージを含む文字列を返します。
public string Index()
{
return "<html><body>This is my default action...</body></html>";
}
次に、Index メソッドを次のように変更します。
public ActionResult Index()
{
return View();
}
次に、Index() メソッドに使用できるビュー テンプレートをプロジェクトに追加しましょう。 これを行うには、Index メソッドの途中でマウスを右クリックし、[ビューの追加...] をクリックします。
[ビューの追加] ダイアログが表示され、Index メソッドで使用できるビュー テンプレートを作成する方法に関するいくつかのオプションが表示されます。 ここでは、何も変更せず、[追加] ボタンをクリックします。
[追加] をクリックすると、次に示すように、新しいフォルダーと新しいファイルが [ソリューション] フォルダーに表示されます。 [ビュー] の下に [HelloWorld] フォルダーがあり、そのフォルダー内に Index.aspx ファイルがあります。
新しいインデックス ファイルも既に開いており、編集できる状態となっています。 最初の <h2>Index</h2> の下に "Hello World" のようなテキストを追加します。
<h2>Index</h2>
Hello world!
アプリケーションを実行し、ブラウザーでもう一度 http://localhost:xx/HelloWorld
にアクセスします。 この例のコントローラーの Index メソッドは何も処理しませんでしたが、"return View()" を呼び出しました。これは、ビュー テンプレート ファイルを使用してクライアントに応答をレンダリングすることを示しています。 使用するビュー テンプレート ファイルの名前を明示的に指定していないため、ASP.NET MVCは、\Views\HelloWorld フォルダー内の Index.aspx ビュー ファイルを使用するように既定で設定されています。 これで、ビューでハードコーディングした文字列が表示されます。
見栄えは良いですね。 ただし、ブラウザーのタイトルに "Index" と表示され、ページのメインタイトルに "My MVC Application" と表示されていることに注意してください。これを変えてみましょう。
ビューとマスター ページの変更
まず、"My MVC Application" というテキストを変更します。そのテキストは共有され、すべてのページに表示されます。 アプリ内のすべてのページに表示されていますが、実際にはコード内では 1 つの場所にのみ表示されます。 ソリューション エクスプローラーで /Views/Shared フォルダーに移動し、Site.Master ファイルを開きます。 このファイルはマスター ページと呼ばれ、他のすべてのページで使用される共有の「シェル」です。
このファイルの ContentPlaceholder "MainContent" というテキストに注目してください。
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
このプレースホルダーは、作成したすべてのページが表示される場所であり、マスターページに「ラップ」されます。 タイトルを変更してから、アプリを実行し、複数のページにアクセスしてみてください。 1 つの変更が複数のページに表示されていることがわかると思います。
<div id="title">
<h1>My MVC Movie Application</h1>
</div>
これで、すべてのページのプライマリ見出し (H1) が "My MVC Movie Application" となります。すべてのページで共有されている上部の白いテキストが処理されます。
タイトルを変更した Site.Master の全体は次のとおりです。
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="page">
<div id="header">
<div id="title">
<h1>My MVC Movie Application</h1>
</div>
<div id="logindisplay">
<% Html.RenderPartial("LogOnUserControl"); %>
</div>
<div id="menucontainer">
<ul id="menu">
<li><%: Html.ActionLink("Home", "Index", "Home")%></li>
<li><%: Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>
</div>
<div id="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
</div>
</div>
</div>
</body>
</html>
次に、[インデックス] ページのタイトルを変更してみましょう。
/HelloWorld/Index.aspx を開きます。 変更する場所は 2 箇所あります。 まず、ブラウザーのタイトルに表示されるタイトルを変更し、次にセカンダリ ヘッダー (H2) も変更します。 これらを少し変えることで、コードのどの部分を変更するとアプリのどの部分が変更されるかを確認することができます。
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Movie List
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>My Movie List</h2>
Hello World!
</asp:Content>
アプリを実行し、/Movies にアクセスします。 ブラウザーのタイトル、プライマリ見出し、およびセカンダリ見出しが変更されていることに注意してください ビューに小さな変更を加えることで、簡単にアプリに大きな変更を加えることができます。
わずかな「データ」 (この場合は "Hello World!" メッセージ) がハードコーディングされました。 V (ビュー) があり、C (コントローラー) はありますが、M (モデル) はまだありません。 次に、データベースを作成し、そこからモデル データを取得する方法について説明します。
ViewModel を渡す
データベースに移動してモデルについて説明する前に、まず "ViewModels" について説明しましょう。これらは、HTML 応答をクライアントにレンダリングするためにビュー テンプレートで必要なものを表すオブジェクトです。 これらは通常、コントローラー クラスによって作成され、ビュー テンプレートに渡されるため、ビュー テンプレートに必要なデータのみを含める必要があり、それ以上は含めてはなりません。
以前の HelloWorld サンプルでは、Welcome() アクション メソッドは名前と numTimes パラメーターを取得し、ブラウザーに出力しました。 コントローラーにこの応答を直接レンダリングさせ続けるのではなく、そのデータを保持する小さなクラスを作成し、それをビュー テンプレートに渡して、それを使用して HTML 応答をレンダリングしてみましょう。 こうすることで、コントローラーは一方のことに関係し、ビュー テンプレートはもう一方のことに関係することで、アプリケーション内でクリーンな「懸念事項の分離」を維持できます。
HelloWorldController.cs ファイルに戻り、新しい "WelcomeViewModel" クラスを追加し、コントローラー内の Welcome メソッドを変更します。 同じファイル内に新しいクラスを持つ完全な HelloWorldController.cs を次に示します。
using System.Web.Mvc;
namespace Movies.Controllers
{
public class HelloWorldController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Welcome(string name, int numTimes = 1)
{
var viewModel = new WelcomeViewModel
{
Message = "Hello " + name,
NumTimes = numTimes
};
return View(viewModel);
}
public class WelcomeViewModel
{
public string Message { get; set; }
public int NumTimes { get; set; }
}
}
}
複数行に記述されていても、Welcome メソッドは実際には 2 つのコード ステートメントにすぎません。 最初のステートメントは 2 つのパラメーターを ViewModel オブジェクトにパッケージ化し、2 番目のステートメントは結果のオブジェクトを View に渡します。
ここで、Welcome ビュー テンプレートが必要になりました。 Welcome メソッドを右クリックし、[ビューの追加] を選択します。 今回は、[厳密に型指定されたビューを作成する] をオンにし、ドロップダウン リストから WelcomeViewModel クラスを選択します。 この新しいビューでは、WelcomeViewModels についてのみ認識され、他の種類のオブジェクトは認識されません。
注: ドロップダウン リストに表示するには、WelcomeViewModel を追加した後に 1 回コンパイルする必要があります。
[ビューの追加] ダイアログの外観を以下に示します。 [追加] をクリックします。
新しい Welcome.aspx の <h2> の下にこのコードを追加します。 ループを作成し、ユーザーが言うのと同じ回数だけ Hello と言います。
<% for(int i=0;i<Model.NumTimes;i++) { %>
<%h3><%: Model.Message %></h3>
<% } %>
また、入力時に WelcomeViewModel に関するこのビューについても指示していたので (両者は結合していることを覚えていますか?)、以下のスクリーンショットに示すように、モデル オブジェクトを参照するたびに役立つ Intellisense が得られます。
アプリケーションを実行し、もう一度 http://localhost:xx/HelloWorld/Welcome?name=Scott&numtimes=4
にアクセスします。 これで、URL からデータを取得するようになりました。そのデータはコントローラーに自動的に渡され、コントローラーはデータを ViewModel にパッケージ化し、そのオブジェクトをビューに渡します。 次にビューは、ユーザーに HTML としてデータを表示します。
"M" (モデル) については学習しましたが、データベースについてはまだです。 学習したことを確認し、ムービーのデータベースを作成してみましょう。