MVC アプリケーションへのビューの追加

Rick Anderson

注意

このチュートリアルの更新バージョンは、Visual Studio の最新バージョンを使用してここで入手できます。 新しいチュートリアルでは、MVC ASP.NET Core使用します。このチュートリアルでは、このチュートリアルに比して多くの機能強化が行われました。

このチュートリアルでは、ASP.NET Core MVC のコントローラーとビューについて説明します。 Razor Pages は、ページ ベースのプログラミング モデルである ASP.NET Core の新しい代替手段であり、Web UI の構築が容易になり、生産性が向上します。 MVC バージョンの前に Razor Pages チュートリアルを試してみることをお勧めします。 この Razor ページのチュートリアルの特徴は次のとおりです。

  • 使いやすい。
  • 多くの機能をカバーしている。
  • 新しいアプリ開発に推奨されるアプローチです。

このセクションでは、ビュー テンプレート ファイルを HelloWorldController 使用してクライアントに対する HTML 応答を生成するプロセスをクリーンにカプセル化するようにクラスを変更します。

Razor ビュー エンジンを使用して 、ビュー テンプレート ファイルを作成します。 Razor ベースのビュー テンプレートには .cshtml ファイル拡張子があり、C# を使用して HTML 出力を作成する優れた方法が提供されます。 Razor は、ビュー テンプレートを作成するときに必要な文字数とキーストロークを最小限に抑え、高速で流動的なコーディング ワークフローを可能にします。

現在、Index メソッドは、コントローラー クラスでハード コーディングされるメッセージを含む文字列を返します。 次の Index コードに示すように、コントローラー View メソッドを呼び出すようにメソッドを変更します。

public ActionResult Index() 
{ 
    return View(); 
}

上記の Index 方法では、ビュー テンプレートを使用してブラウザーに対する HTML 応答を生成します。 上記のメソッドなどのIndexコントローラー メソッド (アクション メソッドとも呼ばれます) は、通常、文字列のようなプリミティブ型ではなく、ActionResult (または ActionResult から派生したクラス) を返します。

Views\HelloWorld フォルダーを右クリックし、[追加] をクリックしてから、[MVC 5 View Page with Layout (Razor)] をクリックします。

ソリューション エクスプローラー ウィンドウを示すスクリーンショット。Hello World右クリック メニューと [追加] サブメニューが開き、レイアウト Razor を含む M V C 5 ビュー ページが選択されています。

[ アイテムの名前の指定 ] ダイアログ ボックスで、「 インデックス」と入力し、[OK] をクリック します

[アイテムの名前の指定] ダイアログを示すスクリーンショット。インデックスは[アイテム名]フィールドにあります。

[ レイアウト ページの選択 ] ダイアログで、既定の _Layout.cshtml をそのまま使用し、[OK] をクリック します

[レイアウトの選択] ページを示すスクリーンショット。共有サブフォルダーが開き、レイアウトドット c s h t m l が選択されています。

上のダイアログでは、左側のウィンドウで Views\Shared フォルダーが選択されています。 別のフォルダーにカスタム レイアウト ファイルがある場合は、それを選択できます。 レイアウト ファイルについては、このチュートリアルの後半で説明します

MvcMovie\Views\HelloWorld\Index.cshtml ファイルが作成されます。

ソリューション エクスプローラー ウィンドウを示すスクリーンショット。Views フォルダーと Hello World サブフォルダーが開いています。

次の強調表示されたマークアップを追加します。

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Index.cshtml ファイルを右クリックし、[ブラウザーで表示] を選択します。

PI

Index.cshtml ファイルを右クリックし、Page Inspectorで [表示] を選択することもできます。詳細については、Page Inspector チュートリアルを参照してください。

または、アプリケーションを実行し、コントローラー (http://localhost:xxxx/HelloWorld) をHelloWorld参照します。 コントローラー内のメソッドはあまり Index 機能しませんでした。単にステートメントを実行しました。このステートメント return View()では、メソッドがビュー テンプレート ファイルを使用してブラウザーに応答をレンダリングする必要があることを指定しました。 使用するビュー テンプレート ファイルの名前を明示的に指定していないので、MVC ASP.NET 既定では、\Views\HelloWorld フォルダー内の Index.cshtml ビュー ファイルを使用するように設定されています。 次の図は、ビューでハードコーディングされた文字列 "Hello from our View Template!" を示しています。

ビュー テンプレートの [インデックス] ページとテキスト Hello を示すスクリーンショット。

かなり良い見えます。 ただし、ブラウザーのタイトル バーに "Index - My ASP.NET Application" と表示され、ページの上部にある大きなリンクに "アプリケーション名" と表示されていることに注意してください。ブラウザー ウィンドウのサイズによっては、右上の 3 つのバーをクリックして、[ ホーム]、[ バージョン情報]、[ 連絡先]、[ 登録 ]、[ ログイン] の各リンクが表示される場合があります。

ビューとレイアウト ページの変更

まず、ページの上部にある [アプリケーション名] リンクを変更します。 そのテキストはすべてのページに共通です。 実際には、アプリケーション内のすべてのページに表示される場合でも、プロジェクト内の 1 つの場所にのみ実装されます。 ソリューション エクスプローラー/Views/Shared フォルダーに移動し、_Layout.cshtml ファイルを開きます。 このファイルは レイアウト ページ と呼ばれ、他のすべてのページで使用される共有フォルダーにあります。

_LayoutCshtml

[レイアウト] テンプレートでは、1 か所でサイトの HTML コンテナー レイアウトを指定し、それをサイト内の複数のページに適用できます。 @RenderBody() という行を見つけます。 RenderBody は、作成するすべてのビュー固有のページがレイアウト ページに "ラップ" されて表示されるプレースホルダーです。 たとえば、[ バージョン情報 ] リンクを選択すると、 Views\Home\About.cshtml ビューがメソッド内に RenderBody レンダリングされます。

タイトル要素の内容を変更します。 レイアウト テンプレートの ActionLink を "アプリケーション名" から "MVC Movie" に変更し、コントローラーを次の値にHomeMovies変更します。 完全なレイアウト ファイルを次に示します。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - Movie App</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("MVC Movie", "Index", "Movies", null, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                </ul>
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

アプリケーションを実行し、"MVC Movie" と表示されます。 [ バージョン情報 ] リンクをクリックすると、そのページに "MVC Movie" も表示されます。 レイアウト テンプレートで 1 回変更を加え、サイト上のすべてのページに新しいタイトルを反映させることができました。

[M V C Movie About] ページを示すスクリーンショット。

Views\HelloWorld\Index.cshtml ファイルを初めて作成したとき、次のコードが含まれていました。

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

上記の Razor コードは、レイアウト ページを明示的に設定しています。 Views\_ViewStart.cshtml ファイルを調べます。これにはまったく同じ Razor マークアップが含まれています。 Views\_ViewStart.cshtml ファイルは、すべてのビューで使用される共通レイアウトを定義するため、Views\HelloWorld\Index.cshtml ファイルからそのコードをコメントアウトまたは削除できます。

@*@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}*@

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

Layout プロパティを使用すれば、別のレイアウト ビューを設定することができます。また、null に設定して、レイアウト ファイルが使用されないようにすることができます。

次に、インデックス ビューのタイトルを変更してみましょう。

MvcMovie\Views\HelloWorld\Index.cshtml を開きます。 変更する場所は 2 つあります。最初に、ブラウザーのタイトルに表示されるテキスト、次にセカンダリ ヘッダー ( <h2> 要素) に表示されるテキストです。 これを少し変えれば、コードのどの部分でアプリのどの部分が変更されるかを確認することができます。

@{
    ViewBag.Title = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

表示する HTML タイトルを示すために、上記のコードはオブジェクトのViewBagプロパティ (Index.cshtml ビュー テンプレート内) を設定Titleします。 レイアウト テンプレート (Views\Shared\_Layout.cshtml) は、前に変更した HTML のセクションの<head>一部として要素で<title>この値を使用していることに注意してください。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - Movie App</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>

この ViewBag 方法を使用すると、ビュー テンプレートとレイアウト ファイルの間で他のパラメーターを簡単に渡すことができます。

アプリケーションを実行します。 ブラウザーのタイトル、プライマリ見出し、およびセカンダリ見出しが変更されていることに注意してください (ブラウザーに変更が表示されない場合は、キャッシュされたコンテンツを表示している可能性があります。ブラウザーで Ctrl キーを押しながら F5 キーを押して、サーバーからの応答を強制的に読み込みます)。ブラウザーのタイトルは、Index.cshtml ビュー テンプレートで設定した状態で作成ViewBag.Titleされ、レイアウト ファイルに追加された "- Movie App" が追加されます。

また、 Index.cshtml ビュー テンプレートのコンテンツが _Layout.cshtml ビュー テンプレートとマージされ、1 つの HTML 応答がブラウザーに送信されたことにも注目してください。 レイアウト テンプレートを使用すれば、アプリケーションのすべてのページに適用される変更をとても簡単に行うことができます。

M V C Movie My Movie List ページを示すスクリーンショット。

ただし、少しの "data" (この場合は "Hello from our View Template!" メッセージ) はハードコーディングされています。 MVC アプリケーションには "V" (ビュー) があり、"C" (コントローラー) もありますが、"M" (モデル) はまだありません。 次に、データベースを作成し、そこからモデル データを取得する方法について説明します。

コントローラーからビューへのデータの受け渡し

ただし、データベースに移動してモデルについて話す前に、まずコントローラーからビューに情報を渡すことについて説明しましょう。 コントローラー クラスは、受信 URL 要求に応答して呼び出されます。 コントローラー クラスでは、受信したブラウザー要求を処理し、データベースからデータを取得し、最終的にブラウザーに返す応答の種類を決定するコードを記述します。 その後、ビュー テンプレートをコントローラーから使用して、ブラウザーに対する HTML 応答を生成して書式設定できます。

コントローラーは、ビュー テンプレートがブラウザーに応答をレンダリングするために必要なデータまたはオブジェクトを提供する役割を担います。 ベスト プラクティス: ビュー テンプレートでは、ビジネス ロジックを実行したり、データベースを直接操作したりしないでください。 代わりに、ビュー テンプレートは、コントローラーによって提供されるデータでのみ機能する必要があります。 この "懸念事項の分離" を維持すると、コードをクリーンでテスト可能で保守しやすい状態に保つことができます。

現在、クラスのWelcomeHelloWorldControllerアクション メソッドは、nameパラメーターとパラメーターをnumTimes受け取り、値をブラウザーに直接出力します。 コントローラーでこの応答を文字列としてレンダリングするのではなく、代わりにビュー テンプレートを使用するようにコントローラーを変更しましょう。 このビュー テンプレートでは動的応答が生成されます。これは、応答を生成するために、コントローラーからビューに適量のデータを渡す必要があることを意味します。 これを行うには、ビュー テンプレートがアクセスできるオブジェクトに、ビュー テンプレートに必要な ViewBag 動的データ (パラメーター) をコントローラーに配置します。

HelloWorldController.cs ファイルに戻り、メソッドをWelcome変更して、オブジェクトに値MessageNumTimes値をViewBag追加します。 ViewBag は動的オブジェクトです。つまり、任意のオブジェクトを配置できます。オブジェクト内に ViewBag 何かを配置するまで、オブジェクトには定義されたプロパティがありません。 ASP.NET MVC モデル バインド システムは、名前付きパラメーター (nameおよびnumTimes) をアドレス バーのクエリ文字列からメソッド内のパラメーターに自動的にマップします。 完全な HelloWorldController.cs ファイルは次のようになります。

using System.Web;
using System.Web.Mvc;

namespace MvcMovie.Controllers
{
    public class HelloWorldController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Welcome(string name, int numTimes = 1)
        {
            ViewBag.Message = "Hello " + name;
            ViewBag.NumTimes = numTimes;

            return View();
        }
    }
}

これで、 ViewBag ビューに自動的に渡されるデータがオブジェクトに含まれます。 次に、ウェルカム ビュー テンプレートが必要です。 [ ビルド ] メニューで、[ ソリューションのビルド ] (または Ctrl + Shift + B) を選択して、プロジェクトがコンパイルされていることを確認します。 Views\HelloWorld フォルダーを右クリックし、[追加] をクリックしてから、[MVC 5 View Page with Layout (Razor)] をクリックします。

ソリューション エクスプローラー ウィンドウを示すスクリーンショット。Hello World右クリック メニューと [追加] サブメニューが開いています。レイアウト Razor を含む M V C 5 ビュー ページが選択されています。

[ アイテムの名前の指定 ] ダイアログ ボックスで、「 ようこそ」と入力し、[OK] をクリック します

[ レイアウト ページの選択 ] ダイアログで、既定の _Layout.cshtml をそのまま使用し、[OK] をクリック します

[レイアウトの選択] ページを示すスクリーンショット。[共有] というラベルのサブフォルダーが開き、レイアウトドット c s h t m l が選択されています。

MvcMovie\Views\HelloWorld\Welcome.cshtml ファイルが作成されます。

Welcome.cshtml ファイルのマークアップを置き換えます。 "Hello" というループは、ユーザーが言う回数分作成します。 完全な Welcome.cshtml ファイルを次に示します。

@{
    ViewBag.Title = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < ViewBag.NumTimes; i++)
    {
        <li>@ViewBag.Message</li>
    }
</ul>

アプリケーションを実行し、次の URL を参照します。

http://localhost:xx/HelloWorld/Welcome?name=Scott&numtimes=4

これで、データが URL から取得され、 モデル バインダーを使用してコントローラーに渡されます。 コントローラーはデータをオブジェクトにパッケージ化 ViewBag し、そのオブジェクトをビューに渡します。 その後、ビューにデータが HTML としてユーザーに表示されます。

M V C ムービーのウェルカム ページを示すスクリーンショット。

上のサンプルでは、オブジェクトを ViewBag 使用してコントローラーからビューにデータを渡しました。 チュートリアルの後半で、ビュー モデルを使用して、コントローラーからビューにデータを渡します。 データを渡すためのビュー モデルアプローチは、一般にビュー バッグ アプローチよりもかなり優先されます。 詳細については、 動的 V 厳密に型指定されたビュー に関するブログ エントリを参照してください。

"M" (モデル) については学習しましたが、データベースについてはまだです。 学習したことを確認し、ムービーのデータベースを作成してみましょう。