共用方式為


將檢視新增到 MVC 應用程式

作者:Rick Anderson

注意

本教學課程的更新版本可在此取得,它使用最新版的 Visual Studio。 新的教學課程會使用 ASP.NET Core MVC,它在本教學課程提供多種改良。

本教學課程可讓您了解 ASP.NET Core MVC 與控制器和檢視。 Razor 頁面是 ASP.NET Core 中的新替代方案,它是以頁面為基礎的程式設計模型,可讓 Web UI 的建立更容易且更有效率。 建議您在嘗試使用 MVC 版本之前,先試試 Razor 頁面教學課程。 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 檢視頁面,包含版面配置 (Razor)]

螢幕擷取畫面所示為「方案總管」視窗。「Hello World」右鍵功能表和「新增」子功能表已開啟,且 [MVC 5 檢視頁面,包含版面配置 (Razor)] 已選取。

[指定項目名稱] 對話方塊中輸入「Index」,然後按一下 [確定]

螢幕擷取畫面所示為「指定項目名稱」對話方塊。「項目名稱」欄位中是「Index」。

[選取版面配置頁面] 對話方塊中,接受預設的 _Layout.cshtml,然後按一下 [確定]

螢幕擷取畫面所示為「選取版面配置頁面」。「共用」子資料夾已開啟,且「Layout.cshtml」已選取。

在上述對話方塊中,左窗格的 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教學課程

或者,執行應用程式並前往 HelloWorld 控制器 (http://localhost:xxxx/HelloWorld)。 控制器的 Index 方法不會執行太多作業;它只會執行陳述式 return View(),藉此指定方法應使用檢視範本檔案來轉譯瀏覽器的回應。 因為您沒有明確指定要使用的檢視範本檔案名稱,ASP.NET MVC 預設為使用 \Views\HelloWorld 資料夾中的 Index.cshtml 檢視檔案。 下列影像所示為在檢視中的硬編碼字串「Hello from our View Template!」

螢幕擷取畫面所示為「Index」頁面和文字「Hello from our View Template」。

看起來很不錯。 不過,請注意瀏覽器的標題列顯示「索引 - 我的 ASP.NET 應用程式」,而頁面頂端的主要連結顯示「應用程式名稱」。視您設定的瀏覽器視窗大小而定,您可能需要按一下右上方的三橫條圖示,才能查看 [首頁][關於][聯絡人][註冊][登入] 連結。

變更檢視和版面配置頁面

首先,您要變更頁面頂端的「應用程式名稱」連結。 該文字在每個頁面都會顯示。 即使它出現在應用程式的每個頁面,實際上僅僅實作在專案的一個位置。 前往方案總管/Views/Shared 資料夾,然後開啟 _Layout.cshtml 檔案。 此檔案稱為版面配置頁面,位於所有其他頁面都會使用的共用資料夾中。

_LayoutCshtml

版面配置範本可讓您在某個位置指定網站的 HTML 容器配置,然後將它套用到網站中的多個頁面。 找到 @RenderBody() 這行。 RenderBody 是預留位置,用於顯示您建立的所有檢視特定頁面,「包裝」在版面配置頁面中。 舉例來說,如果您選取 [關於] 連結,Views\Home\About.cshtml 檢視就會在 RenderBody 方法中轉譯。

變更標題元素的內容。 將版面配置範本中的 ActionLink 從「應用程式名稱」變更為「MVC 電影」,並將控制器從 Home 變更為 Movies。 完整的版面配置檔案如下所示:

<!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 電影」。 按一下 [關於] 連結,您也會看到該頁面顯示「MVC Movie」。 我們可以在版面配置範本中只變更一次,就讓網站上的所有頁面都反映新的標題。

螢幕擷取畫面所示為「MVC Movie 關於」頁面。

我們第一次建立 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,因此不會使用任何版面配置檔案。

接下來,我們要變更 Index 檢視的標題。

開啟 MvcMovie\Views\HelloWorld\Index.cshtml。 有兩個位置可以進行變更:首先是顯示在瀏覽器標題的文字,然後是次要標頭中的文字 (<h2> 元素)。 您會使這些變更略有不同,因此可看出哪一段程式碼變更了應用程式的哪個部分。

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

<h2>My Movie List</h2>

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

為了指出要顯示的 HTML 標題,上述程式碼會設定 ViewBag 物件的 Title 屬性 (位於 Index.cshtml 檢視範本)。 請注意,版面配置範本 (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 檢視範本和傳送至瀏覽器的單一 HTML 回應合併。 版面配置範本可讓您輕鬆進行會套用到應用程式之所有頁面的變更。

螢幕擷取畫面所示為「MVC Movie 我的電影清單」頁面。

不過,我們的一小段「資料」(在本例中為「Hello from our View Template!」訊息) 採用硬編碼。 MVC 應用程式具有 "V" (檢視),並已取得 "C" (控制器),但還沒有 "M" (模型)。 我們很快會逐步解說如何建立資料庫,並從中擷取模型資料。

將資料從控制器傳遞至檢視

不過,在我們前進到資料庫並討論模型之前,先討論如何將資訊從控制器傳遞至檢視。 回應傳入的 URL 要求時系統會叫用控制器類別。 控制器類別會在您撰寫程式碼時用於處理傳入瀏覽器要求、從資料庫擷取資料,最後決定要向瀏覽器傳回何種回應類型。 您接著可以從控制器使用檢視範本來產生並格式化瀏覽器的 HTML 回應。

控制器負責提供任何所需資料或物件,藉此讓檢視範本轉譯回應所需的資料。 最佳做法:檢視範本絕不應執行商務邏輯或直接與資料庫互動。 反之,檢視範本應該只使用由控制器提供給它的資料。 維持這種「分離考量」,有助於保持程式碼的整潔與可測試,也更容易維護。

目前,HelloWorldController 類別的 Welcome 動作會採用 namenumTimes 參數,然後將值直接輸出到瀏覽器。 與其讓控制器以字串方式轉譯此回應,不如將控制器改為使用檢視範本。 檢視範本會產生動態回應,這表示您需要將適當數量的資料從控制器傳遞至檢視,以便產生回應。 讓控制器將檢視範本需要的動態資料 (參數) 放在檢視範本隨後可存取的 ViewBag 物件,即可完成這項操作。

返回 HelloWorldController.cs 檔案並變更 Welcome 方法,將 MessageNumTimes 值新增至 ViewBag 物件。 ViewBag 是動態物件,表示您可以在其中放置任何項目;ViewBag 物件會在您放入某些項目之後,產生有定義的屬性。 ASP.NET MVC 模型繫結系統會自動將網址列的查詢字串中具名的參數 (namenumTimes) 對應至方法中的參數。 完整的 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 物件已包含會自動傳遞至檢視的資料。 接下來,您需要 Welcome 檢視範本! 在 [建置] 功能表中,選取 [建置解決方案] (或按 Ctrl+Shift+B),確認專案已編譯。 以滑鼠右鍵按一下 Views\HelloWorld 資料夾,然後按一下 [新增],然後按一下 [MVC 5 檢視頁面,包含版面配置 (Razor)]

螢幕擷取畫面所示為「方案總管」視窗。「Hello World」右鍵功能表和「新增」子功能表已開啟,[MVC 5 檢視頁面,包含版面配置 (Razor)] 已選取。

[指定項目名稱] 對話方塊中輸入「Welcome」,然後按一下 [確定]

[選取版面配置頁面] 對話方塊中,接受預設的 _Layout.cshtml,然後按一下 [確定]

螢幕擷取畫面所示為「選取版面配置頁面」。標籤為「共用」的子資料夾已開啟,且「Layout.cshtml」已選取。

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 格式將資料呈現給使用者。

螢幕擷取畫面所示為「MVC Movie Welcome」頁面。

在上述範例中,我們使用 ViewBag 物件,以便將資料從控制器傳遞至檢視。 稍後在教學課程中,我們將使用檢視模型將控制器中的資料傳遞至檢視。 用檢視模型方法傳遞資料通常比檢視包方法更常用。 如需詳細資訊,請參閱部落格文章動態 V 強型別檢視

這是一種代表模型的 "M",但不是資料庫類型。 讓我們運用所學的內容,建立電影的資料庫。